7

Let's say there is a program sending some data to server via GET:

http://server.com/gateway?value1=abc&value3=def

Then the server sends these values further, adding value2: (python code)

SECURED_VALUE = "safe"
"http://externalAPI.com/?value1={0}&value2={1}&value3={2}".format ( get['value1'], SECURED_VALUE, get['value2'] )

And my point is, can I inject another attribute to the latter request in a way like:

http://server.com/gateway?value1=abc&&value2=hacked&value3=def&&value2=hacked

so then the server --> API request looks like:

http://externalAPI.com/?value1=abc&value2=hacked&value2=safe&value3=def&value2=hacked

The external API most probably will read only the last or first occurrence of the repeated key.

So I have two questions, main, if such hack is possible and one should protect his apps against it. Secondary, how to actually do that, not only by GET method, but maybe by POST, or by modifying a JSON encoded string. Decoding JSON with an ampersand or semicolon gives me an error, putting ampersand to POST method behaves same as in GET method.

I ask this, because I found some security issue and I'm currently writing an example of a successful hacking attempt in case a server developer doesn't strip out ampersands and other risky characters. I don't want to turn out to be a stupid guy who doesn't know such injection can't be performed and is only wasting time of admins, so I thought I'll ask You first.

Third, mini-question, do you know of any good sources of wisdom how to protect yourself from injection (what functions to use for that) in Google App Engine, python, webapp2 framework?

1 Answer 1

6

Overview. Yes. You are right. Very good catch to have noticed this.

Details. This is basically an instance of a HTTP Parameter Pollution vulnerability. This is basically an injection vulnerability (analogous to XSS, except that it is injection into HTTP parameters rather than injection into HTML).

Defenses. To defend against this, I suggest you do two things:

  1. Sanitize the parameter values. Build a whitelist of characters that are expected to appear in your queries and that are also known to be safe in this context (make sure it does not include &, ?, =, #, %), and strip everything in the parameter value that is not in the whitelist.

  2. URL encode the parameter values before interpolating them into the new query.

Related research. See also the following research paper:

5
  • Thanks for this, I'm reading right now. As for defending, in this case it's pretty easy, as the parameter values consists only of letters and digits, but to protect other developers I think the service ('external API' in example) provider should check if some keys are repeated, and if they're different, it could just return "success:false", am I right here? Commented Apr 29, 2012 at 10:27
  • 1
    I can't believe it was so easy. It was probably too hot yesterday, that I didn't achieve it myself, I tried escaping the ampersand, just not with %26. I guess again, when I already knew something is possible, got it easily... Accepted! Thank you, good sir! Commented Apr 29, 2012 at 11:25
  • I wrote that the API server could check if a key is repeated, but now I think, could the hacker inject such characters, to make real ampersand become part of the previous value, and so, making the whole key-value pair 'swallowed' by previous value? Commented Apr 29, 2012 at 12:19
  • @MarkusvonBroady, yes, if you do not take any precautions (e.g., if you do not sanitize and do not apply URL encoding), an attacker could inject something (like a %) to swallow up a real ampersand and the next key-value pair. Good observation! As for your other question: just checking for duplicate keys is not sufficient. For instance, an attacker could introduce an entirely new key that is not repeated but that is trusted by the recipient. If you follow the defenses listed in my answer (sanitize, URL encode), you'll be protected against all of these threats.
    – D.W.
    Commented Apr 30, 2012 at 1:32
  • 1
    With this repeated keys i was meaning a specific situation when I already set all keys that the API reads, and the API could just check if keys aren't repeated. But indeed, it looks like I can just inject everything in one key, and then put %23 (#) on end of it. It will make everything next to parse not as keys. In some situations that would bypass the multikey checking protection, and in PHP it would always made the injected params treated as most (only) important. But my current point is, how the API can protect a developer, and looks like there's no general solution. Commented Apr 30, 2012 at 9:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .