When we make a request, sometimes parameters get involved. These parameters can be manipulated by us, being the user, and thus we can play with them a little. This exploit itself forms when we duplicate a parameter with the same name and then change the value of both parameters.
This can funnily enough cause the application to interpret the request different and this is because applications are formed of servers, architecture and design - Imagine a system where there are 2 servers for example:

In this diagram we can see that a link is generated and then sent to the user. Now imagine what could happen if you duplicate a parameter.

If the system is misconfigured, and if it consists of multiple different points that will treat 1 request - HPP could potentially be a real threat. But you might be wondering how you then abuse that in production.
This happens because the RFC for websites does not contain a clause on how to handle multiple duplicated parameters.
Take the ModSecurity SQL Injection rules. If you try to send a blatant malicious string like select 1,2,3 from table, the filter sees it and shuts you down immediately. But, if we split that string across two parameters—like /index.aspx?page=select 1&page=2,3 from table—the filter might look at them individually and think, "Eh, looks fine to me."
However, once that request hits the actual application, the server might decide to concatenate (glue) them back together. Suddenly, the full malicious string is alive and well inside the system, having bypassed the "bouncer" at the door.
While messing with parameters can lead to XSS or SQLi, it gets even more serious when we talk about Authentication Bypass. A classic (and pretty scary) example happened with Blogger.
Basically, an attacker could invite themselves to be an author on someone else's blog by confusing the security check. They’d send a request that looked something like this:
POST /add-authors.do
security_token=attacker_token&blogID=my_blog_id&blogID=victim_blog_id&authorsList=my_email
Here’s the trick: the web application’s security "guard" would look at the first blogID (the one the attacker actually owned) and say, "Yep, the token matches this ID, let them in!" But then, the actual script that adds the author would look at the second blogID (the victim's) to perform the action.
By the time the application realized what was happening, the attacker had already granted themselves access to a blog they didn't own. It's like showing the bouncer your real ID to get into the club, but then handing the bartender someone else’s credit card.
As we mentioned, the reason HPP is such a headache is that there's no official rule for what to do when a parameter shows up twice. Different web technologies have different "personalities" when it comes to picking which value to trust.
If we sent a request like https://example.com/?color=red&color=blue, here is how the backend would likely interpret it:
| Web Technology / Server | Resulting Value of color | Behavior |
|---|---|---|
| ASP.NET / IIS | red,blue |
Concatenates with a comma |
| PHP / Apache | blue |
Takes the last occurrence |
| Python / Flask | red |
Takes the first occurrence (usually) |
| JSP / Tomcat | red |
Takes the first occurrence |
| Node.js / Express | ['red', 'blue'] |
Creates an array |