Icinga / icinga-web

Icinga Web 1.x, the old new web interface (EOL 31.12.2018)
22 stars 11 forks source link

[dev.icinga.com #7924] CVE-2015-2685: SQL injection in API due to unchecked 'method' field #1341

Closed icinga-migration closed 9 years ago

icinga-migration commented 9 years ago

This issue has been migrated from Redmine: https://dev.icinga.com/issues/7924

Created by ekohl on 2014-12-02 13:43:09 +00:00

Assignee: mfrosch Status: Resolved (closed on 2015-03-12 18:11:57 +00:00) Target Version: 1.13 Last Update: 2015-03-30 08:13:15 +00:00 (in Redmine)

Icinga Version: 2.2.0
Icinga Web Version: 1.11.2
IDO Version: 2.2.0
OS Version: CentOS Linux release 7.0.1406 (Core)
DB Type: PostgreSQL
DB Version: 9.2.7
Browser Version: Any

When querying the API the 'method' field is inserted straight into the SQL statement. This is reproducable using curl:

curl 'http://icinga.example.com/icinga-web/web/api/authkey=mykey/json' -d 'target=service' -d 'filters_json={"field": [{"field": ["SERVICE_NAME"], "type": "atom", "method": ["bla"], "value": ["something"]}], "type": "AND"}'

It results in the following output:

                    A critical exception occured!

                        Uncaught Doctrine_Connection_Pgsql_Exception thrown:

                                                        SQLSTATE[42601]: Syntax error: 7 ERROR:  syntax error at or near "bla"
LINE 1: ...((COALESCE(i4.current_state, 0) = '0' AND i.name2 bla 'dns_s...
                                                             ^                        
                        Stacktrace:#0 /usr/share/icinga-web/lib/doctrine/lib/Doctrine/Connection/Statement.php(274): Doctrine_Connection->rethrowException(Object(PDOException), Object(Doctrine_Connection_Statement))

#1 /usr/share/icinga-web/lib/doctrine/lib/Doctrine/Connection.php(1014): Doctrine_Connection_Statement->execute(Array)
#2 /usr/share/icinga-web/lib/doctrine/lib/Doctrine/Query/Abstract.php(976): Doctrine_Connection->execute('SELECT DISTINCT...', Array)
#3 /usr/share/icinga-web/app/modules/Api/lib/database/IcingaDoctrine_Query.class.php(116): Doctrine_Query_Abstract->_execute(NULL)
#4 /usr/share/icinga-web/lib/doctrine/lib/Doctrine/Query/Abstract.php(1026): IcingaDoctrine_Query->_execute(NULL)
#5 /usr/share/icinga-web/app/modules/Api/models/Store/LegacyLayer/IcingaApiModel.class.php(129): Doctrine_Query_Abstract->execute(NULL, 5)
#6 /usr/share/icinga-web/app/modules/Api/models/Store/LegacyLayer/IcingaApiModel.class.php(148): Api_Store_LegacyLayer_IcingaApiModel->execRead()
#7 /usr/share/icinga-web/app/modules/Api/actions/ApiSearchAction.class.php(126): Api_Store_LegacyLayer_IcingaApiModel->fetch()
#8 /usr/share/icinga-web/app/modules/Api/actions/ApiSearchAction.class.php(406): Api_ApiSearchAction->executeRead(Object(AgaviWebRequestDataHolder))
#9 /var/cache/icinga-web/config/compile.xml_production__d41bc4e7416d79a2859fb497054ab4f5308e2df1.php(949): Api_ApiSearchAction->executeWrite(Object(AgaviWebRequestDataHolder))
#10 /var/cache/icinga-web/config/compile.xml_production__d41bc4e7416d79a2859fb497054ab4f5308e2df1.php(1463): AgaviExecutionContainer->runAction()
#11 /var/cache/icinga-web/config/compile.xml_production__d41bc4e7416d79a2859fb497054ab4f5308e2df1.php(1255): AgaviExecutionFilter->execute(Object(AgaviFilterChain), Object(AgaviExecutionContainer))
#12 /var/cache/icinga-web/config/compile.xml_production__d41bc4e7416d79a2859fb497054ab4f5308e2df1.php(1700): AgaviFilter->executeOnce(Object(AgaviFilterChain), Object(AgaviExecutionContainer))
#13 /usr/share/icinga-web/app/modules/Api/lib/auth/IcingaApiAuthentificationLogoutFilter.class.php(33): AgaviFilterChain->execute(Object(AgaviExecutionContainer))
#14 /var/cache/icinga-web/config/compile.xml_production__d41bc4e7416d79a2859fb497054ab4f5308e2df1.php(1255): IcingaApiAuthentificationLogoutFilter->execute(Object(AgaviFilterChain), Object(AgaviExecutionContainer))
#15 /var/cache/icinga-web/config/compile.xml_production__d41bc4e7416d79a2859fb497054ab4f5308e2df1.php(1700): AgaviFilter->executeOnce(Object(AgaviFilterChain), Object(AgaviExecutionContainer))
#16 /usr/share/icinga-web/lib/agavi/src/filter/AgaviSecurityFilter.class.php(61): AgaviFilterChain->execute(Object(AgaviExecutionContainer))
#17 /var/cache/icinga-web/config/compile.xml_production__d41bc4e7416d79a2859fb497054ab4f5308e2df1.php(1255): AgaviSecurityFilter->execute(Object(AgaviFilterChain), Object(AgaviExecutionContainer))
#18 /var/cache/icinga-web/config/compile.xml_production__d41bc4e7416d79a2859fb497054ab4f5308e2df1.php(1700): AgaviFilter->executeOnce(Object(AgaviFilterChain), Object(AgaviExecutionContainer))
#19 /var/cache/icinga-web/config/compile.xml_production__d41bc4e7416d79a2859fb497054ab4f5308e2df1.php(870): AgaviFilterChain->execute(Object(AgaviExecutionContainer))
#20 /var/cache/icinga-web/config/compile.xml_production__d41bc4e7416d79a2859fb497054ab4f5308e2df1.php(1266): AgaviExecutionContainer->execute()
#21 /var/cache/icinga-web/config/compile.xml_production__d41bc4e7416d79a2859fb497054ab4f5308e2df1.php(1255): AgaviDispatchFilter->execute(Object(AgaviFilterChain), Object(AgaviExecutionContainer))
#22 /var/cache/icinga-web/config/compile.xml_production__d41bc4e7416d79a2859fb497054ab4f5308e2df1.php(1700): AgaviFilter->executeOnce(Object(AgaviFilterChain), Object(AgaviExecutionContainer))
#23 /usr/share/icinga-web/lib/agavi/src/filter/AgaviFormPopulationFilter.class.php(78): AgaviFilterChain->execute(Object(AgaviExecutionContainer))
#24 /var/cache/icinga-web/config/compile.xml_production__d41bc4e7416d79a2859fb497054ab4f5308e2df1.php(1700): AgaviFormPopulationFilter->executeOnce(Object(AgaviFilterChain), Object(AgaviExecutionContainer))
#25 /var/cache/icinga-web/config/compile.xml_production__d41bc4e7416d79a2859fb497054ab4f5308e2df1.php(579): AgaviFilterChain->execute(Object(AgaviExecutionContainer))
#26 /usr/share/icinga-web/pub/index.php(49): AgaviController->dispatch()
#27 {main}

Changesets

2015-03-12 17:49:28 +00:00 by mfrosch 016f065fea98392830e1bc0f98f984d57e29fce7

Prohibit SQL injection via operator in API

It was possible to inject SQL via a special crafted JSON filter.

```
'filters_json={"field": [{"field": ["SERVICE_NAME"], "type": "atom", "method": ["bla"], "value": ["something"]}], "type": "AND"}'
```

I implemented validation of any supplied matcher in the API against the
internal matcher list.

Kudos to Ewoud Kohl van Wijngaarden!

Refs #7924

2015-09-21 11:40:05 +00:00 by elippmann b8fd93d524a9881502720c3743d57fbf035cc07b

API: Fix IcingaApiModel::validateMatcher()

Icinga-web itself uses the API w/ upper-cased filter methods, e.g. LIKE.
The validateMatcher() did not take this into account thus throwing an exception when adding restrictions for example.

refs #7924
fixes #10184
icinga-migration commented 9 years ago

Updated by mfriedrich on 2014-12-05 11:38:56 +00:00

icinga-migration commented 9 years ago

Updated by mfriedrich on 2015-02-14 23:05:48 +00:00

icinga-migration commented 9 years ago

Updated by mfrosch on 2015-03-12 17:51:02 +00:00

icinga-migration commented 9 years ago

Updated by mfrosch on 2015-03-12 17:54:55 +00:00

icinga-migration commented 9 years ago

Updated by mfrosch on 2015-03-12 18:11:57 +00:00

Fixed with proper validation, merged to master.

Thank you very much @ekohl!

icinga-migration commented 9 years ago

Updated by mhein on 2015-03-30 08:13:15 +00:00

Attached CVE ID: CVE-2015-2685