daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

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 `&amp;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)