Skip to content

#4 Removing XSS vulnerability in queryStringToJSON() #5

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ndwhelan
Copy link

Removing a very dangerous eval(), that operates on all params, one or more of which could be arbitrary javascript. There may still be some issues with the advanced part.

Removing a very dangerous eval(), that operates on all params, one or more of which could be arbitrary javascript. There may still be some issues with the advanced part.
@vitorbaptista
Copy link

👍

Thanks for this pull request. I applied this on my fork used in https://github.com/ckan/ckan. As far as I understand, @balupton added this eval() to convert, for example, "2014" to 2014. Apart from the XSS issue you're describing here, I've also had a problem with it as described in ckan/ckan#1870.

Basically, the issue is that I have a query string like ?filters=year:2014, and I would expect it to be converted to { filters: "year:2014" }, but it's converted to { filters: 2014 } because eval("year:2014") === 2014.

Your patch solved both issues, with the side effect of not converting query string values (they all will be strings). I have no problems with it.

vitorbaptista added a commit to ckan/ckan that referenced this pull request Aug 5, 2014
The problem is with the function `queryStringToJSON` that we use in
`ckan/public/base/javascript/view-filters.js` to convert the URL's query string
into a JavaScript object to then parse it.

To understand the bug, take a look at this example:

```javascript
> "filters=country:Brazil|year:2014".queryStringToJSON()
Object {filters: "country:Brazil|year:2014"}
> "filters=country:Brazil".queryStringToJSON()
Object {filters: "country:Brazil"}
> "filters=year:2014".queryStringToJSON()
Object {filters: 2014} // The correct result would be { filters: "year:2014" }
```

Looking at `queryStringToJSON` code, I found the problematic part at
https://github.com/ckan/ckan/blob/1792-filterable-resource-views/ckan/public/base/javascript/view-filters.js#L49-L57

```javascript
// ...

// Fix
key = decodeURIComponent(key);
value = decodeURIComponent(value);
try {
  // value can be converted
  value = eval(value);
} catch ( e ) {
  // value is a normal string
}

// ...
```

This code tries to `eval` the query string's values. "Normal" strings throw an
error when eval'd, which the code ignores. But unfortunately `"year:2014"`
isn't a normal string. See:

```javascript
> eval("year:2014")
2014
> year: 2014
2014
> { year: 2014 }
2014
> eval("year:2014|country:Brazil")
SyntaxError: Unexpected token :
> eval("country:Brazil")
ReferenceError: Brazil is not defined
```

We'll have the same problem if the filter value is between quotes, as in:

```javascript
> "filters=country:'Brazil'".queryStringToJSON()
Object {filters: "Brazil"}
```

The XSS issue is related to us calling `eval()` on all parameters, so some
malicious user could send a link to e.g.
`http://demo.ckan.org/?param=alert('abc')` and execute JS code on anyone that
clicks on that. This was discovered in bevry-archive/jquery-sparkle#5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants