HTTP parameter pollution : Bug bounties [Server-Side ; Client-Side]

Falken Smaze
5 min readApr 29, 2023

Join our Discord server for private learning material and like-minded individuals!

What is HTTP parameter pollution?

HTTP Parameter Pollution (HPP) involves manipulating the way a website handles parameters received in HTTP requests. This vulnerability arises when an attacker adds extra parameters to a request, and the targeted website considers them trustworthy, resulting in unexpected behavior. HPP bugs can occur on both the client and server sides. On the client side, usually through the browser, one can observe the impact of tests. HPP vulnerabilities are often dependent on how server-side code utilizes parameter values passed through, which are controlled by the attacker. As a result, discovering such vulnerabilities may require more experimentation than other types of bugs.

Server-Side HPP

In a server-side HPP vulnerability, your goal is to send unexpected information to the server, in order for the server code to return some unexpected results.

When a website receives a request, its servers process the request and respond with a web page. In certain situations, the servers not only return a web page, but also execute code based on the data they receive from the URL. This code runs solely on the servers, making it impossible for us to see. You can only see the information you send and the results you receive, but not the code. Thus, you can only make guesses about what’s happening. To exploit server-side HPP vulnerabilities, you must identify vulnerable parameters and experiment with them because you cannot view how the server’s code operates. (considering it is a blackbox penetration test/bug bounties). If you can see the source code, then it would make the process much faster.

Let’s see an example for better understanding : there is a server-side HPP vulnerability in a messaging application. Imagine you could send a message by entering values in the URL parameters : from, to, msg. The parameters specify the account name to send the message from, the account name to send the message to and the message content itself. A URL with these parameters that would send the message “hello”, would look something like this :

https://falkensmz.com/message?from=falken&to=smz&msg=hello

When you look at this URL, you have to think that the application might assume it will only receive one “from” parameter. But what would happen if we were to submit two parameters, like in this URL:

https://falkensmz.com/message?from=falken&to=smz&msg=hello&from=elliot

This URL is essentially the same as the first URL, but appends an extra from parameter that specifies another sender, elliot . In this scenario, an attacker will send the extra parameter hoping that the application would validate the message using the first from parameter, but send the actual message using the elliot account, essentially taking control of the messaging system of the application.

Whenever a server receives multiple parameters with the same name, it can respond in multiple ways. As a result, there isn’t one guaranteed process for handling multiple parameter submissions with the same name, meaning finding HPP vulnerabilities takes a lot of experimentation to confirm the way the site you’re testing , actually works.

The messaging application example from earlier uses parameters that are obvious. However, sometimes these vulnerabilities result from hidden server-side behavior, from code that is not directly visible. For example, let’s say the messaging application changes its backend code and no longer includes a from parameter in the URL. This time, the code will only take in two parameters , one for the account to send the message to, and the other for the contents of the actual message. The URL would look something like this :

https://falkensmz.com/message?to=smz&msg=hello

Usually, we would not have access to the backend code, but to demonstrate this example , we know the server-side Rust code:

let user_account = "falken".to_string();

fn prepare_message(mut params: Vec<String>) {
params.push(user_account.clone());
send_message(params); //user.account (falken) becomes params[2]
}

fn send_message(params: Vec<String>) {
let to = &params[0];
let msg = &params[1];
let from = &params[2];
message(to, amount, from);
}

This code creates two functions, prepeare_messsage and send_message. The first function takes an array called params, which contains the to and msg parameters from the URL. It should look something like this : [‘smz’, ‘hello’]. The first function adds the user account information that was first defined in the code to the end of the array, so the final array would look like this : [‘smz’, ‘hello’, ‘falken’]. After we have the array ready , in the send_message function, we are assigning the values from the arrays to the proper variables ; ‘smz’ -> to , and so on. After that, the variables are passed to the message function which takes all of the values and generates the response, sending the “hello” message from “falken” to “smz”.

Normally, the URL parameters would always be formatted in the way that code expects. But, as attackers, we have to think outside of the box. We could change the outcome of this code logic by passing a from value to the params array. E.G.

https://falkensmz.com/message?to=smz&msg=hello&from=elliot

In this scenario, the from parameter is also included in the params array passed to the prepeare_message function. So, the array’s values would be [“smz”, “hello”, “elliot”], then it will add the user account defined in the first line of the code snippet , and so will result in the following array [“smz”, “hello”, “elliot”, “falken”]. As a result, the from variable would take the third parameter, expecting it to be user.account, however, it would reference the value passed by the attacker, which in our case, is “elliot”

Client-Side HPP

The core definition of HPP is almost the same , both for client-side attacks as well as server-side. The main difference, is that for client-side, the effect(s) take(s) place on a user’s end. The attacker can exploit this vulnerability to construct a URL that, when accessed by another user, injects additional query-string parameters into the response, overriding existing ones. As a result, links and forms may function in unexpected ways, potentially leading to serious consequences such as modifying the intended recipient of an invitation form.

The impact of such an attack can vary depending on the capabilities of the affected application. Even if the application itself has limited functionality, an attacker may combine this vulnerability with other exploits to escalate the overall attack.

Summary

The potential impact of HPP depends on the backend actions of a website and the specific parameters that are being manipulated. Testing for HPP vulnerabilities requires a comprehensive approach, as the backend code that is run by a server after receiving a request is usulally hidden from view. This means that we can only make assumptions about how the server handles the parameters we provide. Identifying HPP vulnerabilities may require extensive trial and error testing. It is recommended to start with social media links, but it’s important to continue testing and be aware of potential HPP risks when testing for parameter substitutions, such as ID-like values.

Join our Discord server for private learning material and like-minded individuals!

--

--