Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API SQL Injection #2099

Closed
connortechnology opened this issue May 7, 2018 · 10 comments · Fixed by #2517
Closed

API SQL Injection #2099

connortechnology opened this issue May 7, 2018 · 10 comments · Fixed by #2517

Comments

@connortechnology
Copy link
Member

API is vulnerable to SQL injections via so called "named parameters" ( https://book.cakephp.org/2.0/en/development/routing.html#named-parameters ).

In the EventsController::index() and MonitorsController::index() methods (located in web/api/app/Controller/EventsController.php and web/api/app/Controller/MonitorsController.php), $this->request->params['named'] is directly being used as conditions for Model::find() calls, and unless named parameters are explicitly whitelisted ( https://book.cakephp.org/2.0/en/development/routing.html#controlling-named-parameters ), arbitrary values can be passed, which means that it's possible to define the key side of the conditions array, which is where CakePHP accepts plain SQL.

Here's a basic example for testing purposes:

/zm/api/events/index/Id = 1 OR 1=:1.json

This will result in an conditions array that looks like

[
    'Id = 1 OR 1=' => 1
]

which will subsequently generate the following SQL:

... WHERE Id = 1 OR 1=1

Named parameters should either be whitelisted on router level, either per route ( https://book.cakephp.org/2.0/en/development/routing.html#per-route-named-parameters ), or globally via Router::connectNamed(), ie every possible column/operator combination (like Id >=, Id <=, Id =, etc...) needs to be registered, or they should be validated against whitelists manually accordingly.

The above example has been tested against the latest release and the master branch, using the release and the development docker files ( https://github.com/ZoneMinder/zmdockerfiles ).

@stale
Copy link

stale bot commented Jul 6, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jul 6, 2018
@stale stale bot closed this as completed Jul 13, 2018
@rhaamo
Copy link

rhaamo commented Jul 13, 2018

@connortechnology can you confirm if this is still the case or it have been fixed at some point and forgotten to update the issue ?

@niloc132
Copy link

Definitely a problem - from the demo site (zmuser/zmpass), try this link

https://demo.zoneminder.com/zm/api/events/index/Id%20=%201%20OR%201=:1.json

It should show no rows (since that isn't a valid ID), but instead it shows all rows. Anyone could use this to execute more complex SQL, which potentially could include deleting or modifying events, triggering alarms, adding users, changing permissions, running shell code, etc.

@IdanDavidi
Copy link

Any news about this vulnerability?

@connortechnology
Copy link
Member Author

Nothing has been done about it.

Please note that this is only a vulnerability if you do not use authentication. You have to be logged in to do this.. So use authentication.

@mnoorenberghe mnoorenberghe added this to the 1.34.0 milestone Feb 10, 2019
@mnoorenberghe mnoorenberghe added Web API REST API and removed Under Review labels Feb 10, 2019
@mnoorenberghe
Copy link
Contributor

@pliablepixels Does zmNinja do any API queries with OR (or similar) like #2099 (comment) shows? I'm trying to figure out whether we can limit the syntax to one column name and one operator between a / and the : and then for the right of the :, can we limit that to a literal value or should we allow a column name there too?

@pliablepixels
Copy link
Member

I don't use OR or similar, but I do use a lot of nested paths like

/StartTime >=:time/EndTime <=:time/Notes%20REGEXP:detected%3A/

@mnoorenberghe
Copy link
Contributor

mnoorenberghe commented Feb 11, 2019

OK, yeah, that is fine. I won't limit how many path segments there are.

Side note: I just found the docs for CakePHP Complex Find Conditions and it specifically warns about this kind of SQLi:

CakePHP only escapes the array values. You should never put user data into the keys. Doing so will make you vulnerable to SQL injections.

Looks like it's too late to listen to that if we don't want to break all consumers… we'll just have to do our own sanitization.

@mnoorenberghe
Copy link
Contributor

@pliablepixels Do you ever include the table name in your query e.g. Table.Field? I'm wondering if I can exclude periods?

mnoorenberghe added a commit to mnoorenberghe/ZoneMinder that referenced this issue Feb 11, 2019
@pliablepixels
Copy link
Member

@mnoorenberghe not to my knowlege. That being said, once you are done with the changes I'll pull and test. But to this specific question, I'm pretty sure I don't use table names anywhere. I don't remember, however, if there are other applications of "." inside a query

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants