nwarp
nwarp

Reputation: 791

Sanitizing url and parameters

Currently, my software has the following workflow

  1. User performs an search through a REST API and selects an item
  2. Server performs the same search again to validate the user's selection

In order to implement step 2, the user has to send the URL params that he used for his search as a string (ex. age=10&gender=M).

The server will then http_get(url + "?" + params_str_submitted_by_user)

Can a malicious user make the server connect to an unintended server by manipulating params_str_submitted_by_user?

What is the worst case scenario if even newlines are left in and the user can arbitrarily manipulate the HTTP headers?

Upvotes: 3

Views: 19904

Answers (1)

SilverlightFox
SilverlightFox

Reputation: 33578

As you are appending params_str_submitted_by_user to the base URL after the ? delimiter, you are safe from this type of attack used where the context of the domain is changed to a username or password:

Say URL was http://example.com and params_str_submitted_by_user was @evil.com and you did not have the / or ? characters in your URL string concatenation.

This would make your URL http://[email protected] which actually means username example.com at domain evil.com.

However, the username cannot contain the ? (nor slash) character, so you should be safe as you are forcing the username to be concatenated. In your case URL becomes:

http://[email protected]

or

http://example.com/[email protected]

if you include the slash in your base URL (better practise). These are safe as all it does is pass your website evil.com as a query string value because @evil.com will no longer be interpretted as a domain by the parser.

What is the worst case scenario if even newlines are left in and the user can arbitrarily manipulate the HTTP headers?

This depends on how good your http_get function is at sanitizing values. If http_get does not strip newlines internally it could be possible for an attacker to control the headers sent from your application.

e.g. If http_get internally created the following request

GET <url> HTTP/1.1
Host: <url.domain>

so under legitimate use it would work like the following:

http_get("https://example.com/foo/bar")

generates

GET /foo/bar HTTP/1.1
Host: example.com

an attacker could set params_str_submitted_by_user to

<space>HTTP/1.1\r\nHost: example.org\r\nCookie: foo=bar\r\n\r\n

this would cause your code to call

http_get("https://example.com/" + "?" + "<space>HTTP/1.1\r\nHost: example.org\r\nCookie: foo=bar\r\n\r\n")

which would cause the request to be

GET / HTTP/1.1
Host: example.org
Cookie: foo=bar

 HTTP/1.1
Host: example.com

Depending on how http_get parses the domain this might not cause the request to go to example.org instead of example.com - it is just manipulating the header (unless example.org was another site on the same IP address as your site). However, the attacker has managed to manipulate headers and add their own cookie value. The advantage to the attacker depends on what can be gained under your particular setup from them doing this - there is not necessarily any general advantage, it would be more of a logic flaw exploit if they could trick your code into behaving in an unexpected way by causing it to make requests under the control of the attacker.

What should you do?

To guard against the unexpected and unknown, either use a version of http_get that handles header injection properly. Many modern languages now deal with this situation internally.

Or - if http_get is your own implementation, make sure it sanitizes or rejects URLs that contain invalid characters like carriage returns or line feeds and other parameters that are invalid in a URL. See this question for list of valid characters.

Upvotes: 7

Related Questions