Information Security Stack Exchange is a question and answer site for information security professionals. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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

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

"{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:

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

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?

share|improve this question
up vote 6 down vote accepted

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:

share|improve this answer
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? – Markus von Broady Apr 29 '12 at 10:27
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! – Markus von Broady Apr 29 '12 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? – Markus von Broady Apr 29 '12 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. Apr 30 '12 at 1:32
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. – Markus von Broady Apr 30 '12 at 9:13

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.