parameter-pollution.md (13510B)
1 --- 2 title: "Parameter Pollution | JSON Injection" 3 section: "Web Pentesting" 4 sectionSlug: "pentesting-web" 5 sourcePath: "src/pentesting-web/parameter-pollution.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/parameter-pollution.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # Parameter Pollution | JSON Injection 14 15 ## HTTP Parameter Pollution (HPP) Overview 16 17 HTTP Parameter Pollution (HPP) is a technique where attackers manipulate HTTP parameters to change the behavior of a web application in unintended ways. This manipulation is done by adding, modifying, or duplicating HTTP parameters. The effect of these manipulations is not directly visible to the user but can significantly alter the application's functionality on the server side, with observable impacts on the client side. 18 19 ### Example of HTTP Parameter Pollution (HPP) 20 21 A banking application transaction URL: 22 23 - **Original URL:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000` 24 25 By inserting an additional `from` parameter: 26 27 - **Manipulated URL:** `https://www.victim.com/send/?from=accountA&to=accountB&amount=10000&from=accountC` 28 29 The transaction may be incorrectly charged to `accountC` instead of `accountA`, showcasing the potential of HPP to manipulate transactions or other functionalities such as password resets, 2FA settings, or API key requests. 30 31 #### **Technology-Specific Parameter Parsing** 32 33 - The way parameters are parsed and prioritized depends on the underlying web technology, affecting how HPP can be exploited. 34 - Tools like [Wappalyzer](https://addons.mozilla.org/en-US/firefox/addon/wappalyzer/) help identify these technologies and their parsing behaviors. 35 36 ### PHP and HPP Exploitation 37 38 **OTP Manipulation Case:** 39 40 - **Context:** A login mechanism requiring a One-Time Password (OTP) was exploited. 41 - **Method:** By intercepting the OTP request using tools like Burp Suite, attackers duplicated the `email` parameter in the HTTP request. 42 - **Outcome:** The OTP, meant for the initial email, was instead sent to the second email address specified in the manipulated request. This flaw allowed unauthorized access by circumventing the intended security measure. 43 44 This scenario highlights a critical oversight in the application's backend, which processed the first `email` parameter for OTP generation but used the last for delivery.<sup>[[1]](#references)</sup> 45 46 **API Key Manipulation Case:** 47 48 - **Scenario:** An application allows users to update their API key through a profile settings page. 49 - **Attack Vector:** An attacker discovers that by appending an additional `api_key` parameter to the POST request, they can manipulate the outcome of the API key update function. 50 - **Technique:** Utilizing a tool like Burp Suite, the attacker crafts a request that includes two `api_key` parameters: one legitimate and one malicious. The server, processing only the last occurrence, updates the API key to the attacker's provided value. 51 - **Result:** The attacker gains control over the victim's API functionality, potentially accessing or modifying private data unauthorizedly. 52 53 This example further underscores the necessity for secure parameter handling, especially in features as critical as API key management.<sup>[[1]](#references)</sup> 54 55 ### Parameter Parsing: Flask vs. PHP 56 57 The way web technologies handle duplicate HTTP parameters varies, affecting their susceptibility to HPP attacks:<sup>[[2]](#references)</sup> 58 59 - **Flask:** Adopts the first parameter value encountered, such as `a=1` in a query string `a=1&a=2`, prioritizing the initial instance over subsequent duplicates. 60 - **PHP (on Apache HTTP Server):** Contrarily, prioritizes the last parameter value, opting for `a=2` in the given example. This behavior can inadvertently facilitate HPP exploits by honoring the attacker's manipulated parameter over the original. 61 62 63 ### HPP Testing Notes (OWASP WSTG) 64 65 - HTTP standards do not define how to interpret multiple parameters with the same name, so behavior varies across stacks and components. 66 - When testing server-side HPP, duplicate each parameter in query strings or bodies and observe whether the application concatenates values, uses first/last, or errors. 67 - For client-side HPP, inject a URL-encoded `&` into a reflected parameter value (e.g., `%26HPP_TEST`) and look for decoded occurrences such as `&HPP_TEST` or `&HPP_TEST` inside generated links or form actions.<sup>[[5]](#references)</sup> 68 69 ### Server-Side Parameter Pollution (SSPP) in Internal APIs 70 71 Some applications embed user input into server-side requests to internal APIs. If that input is not properly encoded, you can inject or override parameters in the internal request. Test any user input, including query parameters, form fields, headers, and URL path parameters.<sup>[[6]](#references)</sup> 72 73 Common probes: 74 75 - Add a new parameter with `%26` (URL-encoded `&`). 76 - Truncate the downstream query with `%23` (URL-encoded `#`). 77 - Override an existing parameter by duplicating it. 78 79 Example: 80 81 ```http 82 GET /userSearch?name=peter%26name=carlos&back=/home 83 ``` 84 85 Potentially results in a server-side request like: 86 87 ```http 88 GET /users/search?name=peter&name=carlos&publicProfile=true 89 ``` 90 91 ## Parameter pollution by technology 92 93 These results were taken from [HTTP Parameter Pollution in 2024](https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89).<sup>[[3]](#references)</sup> 94 95 ### PHP 8.3.11 AND Apache 2.4.62 <a href="#id-9523" id="id-9523"></a> 96 97 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281255%29.png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*l_Pf2JNCYhmfAvfk7UTEbQ.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*l_Pf2JNCYhmfAvfk7UTEbQ.jpeg</a></p></figcaption></figure> 98 99 1. Ignore anything after %00 in the parameter name . 100 2. Handle name\[] as array . 101 3. \_GET not meaning GET Method . 102 4. Prefer the last parameter . 103 104 ### Ruby 3.3.5 and WEBrick 1.8.2 105 106 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281257%29.png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*kKxtZ8qEmgTIMS81py5hhg.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*kKxtZ8qEmgTIMS81py5hhg.jpeg</a></p></figcaption></figure> 107 108 1. Uses the & and ; delimiters to split parameters . 109 2. Not Recognized name\[] . 110 3. Prefer the first parameter . 111 112 ### Spring MVC 6.0.23 AND Apache Tomcat 10.1.30 <a href="#dd68" id="dd68"></a> 113 114 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281258%29.png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*llG22MF1gPTYZYFVCmCiVw.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*llG22MF1gPTYZYFVCmCiVw.jpeg</a></p></figcaption></figure> 115 116 1. POST RequestMapping == PostMapping & GET RequestMapping == GetMapping . 117 2. POST RequestMapping & PostMapping Recognized name\[] . 118 3. Prefer name if name AND name\[] existing . 119 4. Concatenate parameters e.g. first,last . 120 5. POST RequestMapping & PostMapping Recognized query parameter with Content-Type . 121 122 ### **NodeJS** 20.17.0 **AND** Express 4.21.0 <a href="#id-6d72" id="id-6d72"></a> 123 124 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281259%29.png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*JzNkLOSW7orcHXswtMHGMA.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*JzNkLOSW7orcHXswtMHGMA.jpeg</a></p></figcaption></figure> 125 126 1. Recognized name\[] . 127 2. Concatenate parameters e.g. first,last . 128 129 ### GO 1.22.7 <a href="#id-63dc" id="id-63dc"></a> 130 131 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281260%29.png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*NVvN1N8sL4g_Gi796FzlZA.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*NVvN1N8sL4g_Gi796FzlZA.jpeg</a></p></figcaption></figure> 132 133 1. NOT Recognized name\[] . 134 2. Prefer the first parameter . 135 136 ### Python 3.12.6 AND Werkzeug 3.0.4 AND Flask 3.0.3 <a href="#b853" id="b853"></a> 137 138 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281261%29.png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*Se5467PFFjIlmT3O7KNlWQ.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*Se5467PFFjIlmT3O7KNlWQ.jpeg</a></p></figcaption></figure> 139 140 1. NOT Recognized name\[] . 141 2. Prefer the first parameter . 142 143 ### Python 3.12.6 AND Django 4.2.15 <a href="#id-8079" id="id-8079"></a> 144 145 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281262%29.png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*rf38VXut5YhAx0ZhUzgT8Q.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*rf38VXut5YhAx0ZhUzgT8Q.jpeg</a></p></figcaption></figure> 146 147 1. NOT Recognized name\[] . 148 2. Prefer the last parameter . 149 150 ### Python 3.12.6 AND Tornado 6.4.1 <a href="#id-2ad8" id="id-2ad8"></a> 151 152 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281263%29.png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*obCn7xahDc296JZccXM2qQ.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*obCn7xahDc296JZccXM2qQ.jpeg</a></p></figcaption></figure> 153 154 1. NOT Recognized name\[] . 155 2. Prefer the last parameter . 156 157 ## JSON Injection 158 159 [Json Xml Yaml Hacking](/hacktricks/pentesting-web/json-xml-yaml-hacking) 160 161 ### Duplicate keys 162 163 ```ini 164 obj = {"test": "user", "test": "admin"} 165 ``` 166 167 The front-end might believe the first ocurrence while the backend uses the second ocurrence of the key.<sup>[[4]](#references)</sup> 168 169 ### Key Collision: Character Truncation and Comments 170 171 Certain characters aren't going to be correctly interpreted by the frontend but the backend will interpret them and use those keys, this could be useful to **bypass certain restrictions**:<sup>[[4]](#references)</sup> 172 173 ```json 174 {"test": 1, "test\[raw \x0d byte]": 2} 175 {"test": 1, "test\ud800": 2} 176 {"test": 1, "test"": 2} 177 {"test": 1, "te\st": 2} 178 ``` 179 180 Note how in these cases the front end might think that `test == 1` and the backend will think that `test == 2`. 181 182 This can also by used to bypass value restrictions like: 183 184 ```json 185 {"role": "administrator\[raw \x0d byte]"} 186 {"role":"administrator\ud800"} 187 {"role": "administrator""} 188 {"role": "admini\strator"} 189 ``` 190 191 ### **Using Comment Truncation** 192 193 ```ini 194 obj = {"description": "Duplicate with comments", "test": 2, "extra": /*, "test": 1, "extra2": */} 195 ``` 196 197 Here we will use the serializer from each parser to view its respective output. 198 199 Serializer 1 (e.g., GoLang's GoJay library) will produce: 200 201 - `description = "Duplicate with comments"` 202 - `test = 2` 203 - `extra = ""` 204 205 Serializer 2 (e.g., Java's JSON-iterator library) will produce: 206 207 - `description = "Duplicate with comments"` 208 - `extra = "/*"` 209 - `extra2 = "*/"` 210 - `test = 1` 211 212 Alternatively, straightforward use of comments can also be effective: 213 214 ```ini 215 obj = {"description": "Comment support", "test": 1, "extra": "a"/*, "test": 2, "extra2": "b"*/} 216 ``` 217 218 Java’s GSON library: 219 220 ```json 221 { "description": "Comment support", "test": 1, "extra": "a" } 222 ``` 223 224 Ruby’s simdjson library: 225 226 ```json 227 { "description": "Comment support", "test": 2, "extra": "a", "extra2": "b" } 228 ``` 229 230 ### **Inconsistent Precedence: Deserialization vs. Serialization** 231 232 ```ini 233 obj = {"test": 1, "test": 2} 234 235 obj["test"] // 1 236 obj.toString() // {"test": 2} 237 ``` 238 239 ### Float and Integer 240 241 The number 242 243 ```text 244 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 245 ``` 246 247 can be decoded to multiple representations, including: 248 249 ```text 250 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 251 9.999999999999999e95 252 1E+96 253 0 254 9223372036854775807 255 ``` 256 257 These differing numeric representations can create parser inconsistencies.<sup>[[4]](#references)</sup> 258 259 ## References 260 261 - [1] [HTTP Parameter Pollution. It's Contaminated](https://medium.com/@shahjerry33/http-parameter-pollution-its-contaminated-85edc0805654) 262 - [2] [Writeup for Under Construction - Google CTF 2023](https://github.com/google/google-ctf/tree/main/2023/quals/web-under-construction/solution) 263 - [3] [HTTP Parameter Pollution in 2024](https://medium.com/@0xAwali/http-parameter-pollution-in-2024-32ec1b810f89) 264 - [4] [JSON Interoperability Vulnerabilities](https://bishopfox.com/blog/json-interoperability-vulnerabilities) 265 - [5] [Testing for HTTP Parameter Pollution - OWASP WSTG](https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/04-Testing_for_HTTP_Parameter_Pollution) 266 - [6] [Server-side parameter pollution - PortSwigger](https://portswigger.net/web-security/api-testing/server-side-parameter-pollution)