Difference between CSRF and HPP (HTTP Parameter Pollution)? - security

I went through this link to understand about HPP (HTTP Parameter Pollution) attacks.
In HPP attacks it seems like, attacker modifies the HTTP parameters and sends the modified URL to the victim. Isn't this same as CSRF attacks? If not can somebody tell me what is the difference between CSRF & HPP?

HTTP Parameter Pollution is when your application makes a back-end HTTP request to another system and these parameters can be manipulated by input into your main application. HPP is defined by the fact the attacker causes a duplicate parameter name to be passed to the back-end request, which overrides the parameter value being explicitly passed by the application. A similar vulnerability, HTTP Parameter Injection is defined by the attacker adding a new parameter to the back-end request which is interpreted by the other system. So HPI causes a new parameter to be added, whereas HPP causes an existing parameter to be ignored or interpreted in a new way.
See my answer here for a solid example of HPP.
CSRF doesn't require any back-end HTTP request. This is a front-end request, but made by the victim without their knowledge. It basically means that a malicious request is made using the victim's browser and the victim's authorisation cookies. It could be as simple as a hidden image on the attacker's page:
<img src="https://bank.example.com/transfer_money?toAmount=999&toAccount=12345678" />
This will be triggered whenever the victim visits the attacker's page (e.g. following a link emailed to them, or something posted on a forum).
See my answer here for another example using the POST method.
Sometimes a HPP vulnerability can be exploited via CSRF. For example, one that requires the victim to be the one logged into the system that is exploitable via HPP. e.g. the POST to https://www.example.com/transferMoney.php could be made by the attacker's site, passing the toAccount=9876 POST parameter causing the victim to transfer money to an unauthorised account using their autorisation cookie for www.example.com.
Regarding the article in your question, I don't think that is a realistic HPP attack because any actions that cause a state change should be implemented via the POST method and not a GET link as the article demonstrates, so you wouldn't actually get an action link being constructed from the current page (but hey, anything is possible). This is why HPP is really more around back-end requests in practice.

From what the linked article describes, it seems that HPP is a specific type of injection attack, where you modify the request parameters in order to modify the contents of the returned page. In a sense, its a more generalized version of a reflected XSS attack; whereas with XSS you are attempting to inject and execute malicious javascript through tampering with a request, in HPP you are trying to modify any data (in the example given, data used to generate URLs) to inject malicious data.
The term CSRF, however, is usually used to describe an attack where an entirely valid request is sent to a server in a context that leads to unexpected or unwanted behavior. The somewhat standard example would be tricking a user into clicking a link on your site, which sends a request to the user's banking site (as the user) to transfer money from their account to yours.
There is nothing preventing an attacker from using a HPP or XSS attack with a CSRF attack. An XSS or HPP attack takes advantage of a lack of validation in the processing of user input that is later returned as part of a response, while a CSRF attack takes advantage of "sequence breaking" in application flow to cause unintended behavior.

Related

Cross Site Request Forgery prevention via 'Referer' header

We recently received result from IBM AppScan DAST and some of the result don't make much senses.
2.Medium -- Cross-Site Request Forgery
Risk(s): It may be possible to steal or manipulate customer session and cookies, which might be used to impersonate a legitimate
user, allowing the hacker to view or alter user records, and to perform transactions as that user
Fix: Validate the value of the "Referer" header, and use a one-time-nonce for each submitted form
The following changes were applied to the original request:
Set header to 'http://bogus.referer.ibm.com'
Reasoning:
The test result seems to indicate a vulnerability because the Test Response is identical to the
Original Response, indicating that the Cross-Site Request Forgery attempt was successful, even
though it included a fictive 'Referer' header.
Request/Response:
POST /**/main.xhtml HTTP/1.1 -- **This xhtml only opens a default menu on page load**
User-Agent: Mozilla/4.0 (compatible; MS
The recommend fix
Validate the value of the "Referer" header, and use a one-time-nonce for each submitted form.
javax.faces.ViewState has an implicit CSRF protection.
https://www.beyondjava.net/jsf-viewstate-and-csrf-hacker-attacks
I could also do explicit CSRF protection using protected-views. This explicit CSRF protection adds a token for all cases, and additionally adds checks for the “referer” and “origin” HTTP headers. (Reference Bauke & Arjan Book Definitive Guide)
The report also marks /javax.faces.resource/ like CSS , JS , fonts which i believe are false positive in the report.
Looking for feedback and some insight.
This is indeed needless in JSF. This kind of attack is in JSF only possible when there's already an open remote code execution hole such as XSS (and thus the hacker has access to among others the session cookies and can therefore copy them via the phishing site), or when the view is stateless via <f:view transient="true"> (because you lose the javax.faces.ViewState hidden input field as implicit CSRF protection for the "normal" case when there's no remote code execution hole), or when you use HTTP instead of HTTPS (because a man-in-middle attacker can then plainly see all transferred bits and extract the session cookies from them).
All you need to make sure is that the enduser's session cookies are never in some way exposed to the world. The advised fix is not at all helpful in that. It only makes it the attacker more difficult to perform a successful CSRF attack when you sooner or later accidentally introduce a remote code execution hole. But then you have really way much bigger problems than only CSRF. All these efforts advised by this tool are only useful to give the hacker slightly less time to perform a successful attack, and to give yourself slightly more time to fix the remote code execution hole.
If all you want is to "suppress" this warning, then create a Filter which does the desired job. Here's a kickoff example, map it on /*.
if (!"GET".equals(request.getMethod())) {
String referrer = request.getHeader("referer"); // Yes, with the legendary typo.
if (referrer != null) {
String referrerHost = new URL(referrer).getHost();
String expectedHost = new URL(request.getRequestURL().toString()).getHost();
if (!referrerHost.equals(expectedHost)) {
response.sendError(403);
return;
}
}
else {
// You could also send 403 here. But this is more likely to affect real users.
}
}
chain.doFilter(request, response);
see also:
CSRF, XSS and SQL Injection attack prevention in JSF

Why do some consider 2nd-order (aka persistent) XSS to not be true XSS?

I'm reading "The Web Application Hacker's Handbook", and it talks about the differences between 1st-order (aka reflected) XSS and 2nd-order (aka persistent) XSS. It mentions how reflected XSS takes advantage of incomplete or nonexistent sanitization of query string params to execute arbitrary scripts into the user's DOM without persisting any malicious code to the application's database, and how 2nd-order XSS does in fact persist that malicious code, to be executed in the user's DOM at some later time.
My question relates to the author's desription of 2nd-order XSS (on page 438, if you've got a copy handy). The description from the book states that:
Attacks against stored XSS vulnerabilities typically involve at least
two requests to the application. In the first, the attacker posts some
crafted data containing malicious code that the application stores. In
the second, a victim views a page containing the attacker’s data, and
the malicious code is executed when the script is executed in the
victim’s browser. For this reason, the vulnerability is also sometimes
called second-order cross-site scripting. (In this instance, “XSS” is
really a misnomer, because the attack has no cross-site element. [emphasis mine] The
name is widely used, however, so we will retain it here.)
In 2nd-order XSS, the malicious code that the attacker still injects is (presumably) still some arbitrary script pointing to an external server (for example, injecting an img tag with a src attribute of "http://www.malicioussite.dom" + document.cookie). I'm confused why the author then states that this attack has no cross-site element. Making a request to the malicious external server seems to me like a proper cross-site element. Am I missing something?
To me, 'cross-site' in XSS means that the malicious script itself is directly sent from another site. Like for example in case of reflected XSS on an url parameter, a malicious website A.com can craft a link to the victim website B.com with its attack in a vulnerable parameter of B, and when a user visits A and clicks the link, he will execute the script on B.
So I think it's not about what the malicious script is doing, it's where it comes from (and how).
In case of stored XSS, the script is usually entered on the vulnerable website directly, however that may not always be the case, such maintaining the original 'cross-site' element. But it doesn't matter, the name is the same, because the underlying problem and also the solution in code are the same, so the name of the vulnerability is the same too. :)
Whatever people call it though, the important thing is to avoid it. :)

are precautions against CSRF needed for view-only pages?

All the examples of CSRF exploits tend to be against pages which process the incoming request.
If the page doesn't have a form processing aspect do I need to worry about CSRF ?
The situation I'm looking # :
the page in question contains sensitive data
as such users need to establish a session to view the page
... my understanding is that a malicious page will be able to redirect a client to this page by embedding a link to it, however since there's no action on the target to perform there's no harm that can result, right ?
There's no way for said malicious site can view the sensitive page, correct ?
Why I ask: I want the url to the page with sensitive data to have a 'simple' URL which allows people to email the link to other people (who will in turn need a session to view the page). The token-based solution I've seen for most CSRF solutions remove this possibility, and so I'd like to avoid them if possible.
There's no way for said malicious site can view the sensitive page, correct ?
Correct in terms of CSRF.
The blog you linked is talking about Cross-Origin Script Inclusion, which is a different animal. To be vulnerable to XOSI your sensitive page would have to be interpretable as JavaScript, and you'd have to be either serving it without a proper HTML MIME type, or the browser would have to be an old one that didn't enforce type checking on scripts.
You might also potentially worry about clickjacking, where another site includes yours in a frame and overlays misleading UI elements. There are some sneaky ways that has been used to extract sensitive data (see the next generation clickjacking paper and this amusing info leak in Firefox) so you may wish to disallow framing with the X-Frame-Options header.
Why I ask: I want the url to the page with sensitive data to have a 'simple' URL which allows people to email the link to other people (who will in turn need a session to view the page). The token-based solution I've seen for most CSRF solutions remove this possibility
You definitely shouldn't be putting a CSRF token in a GET URL. Apart from the ugliness, and breakage of navigation, URLs are easy to leak from the browser or other infrastructure, potentially compromising the confidentiality of the token.
Normal practice is not to put CSRF protection on side-effect-free actions.
In general, CSRF is independent from whether the request causes any side effects or not. The CWE describes CSRF (CWE-352) as follows:
The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
So CSRF is a general request intention authenticity problem.
However, although CSRF is not really feasible without any effects other than data retrieval as the same-origin policy restricts the attacker from accessing the response, the attacker could exploit another vulnerability to profit from retrieval-only requests as well and gain access to sensitive data.

Why bother requiring CSRF token on POST requests?

My understanding is that CSRF prevents an attacker using an <img> tag to get the victim's browser to send a request that would be authenticated using the session cookie. Given that <img>s are always submitted using a GET request, not POST, then why is it necessary to require a CSRF token in a POST request?
Also, the attacker wouldn't be able to submit a form in the webpage without being able to run code (ie. an XSS attack), in which case they can circumvent your CSRF protections anyway.
The attacker can host a form on their own site, but it does not require the form to be submitted by the user. They can use JavaScript to do this:
<form method="post" action="http://www.example.com/executeAction">
<input type="hidden" name="action" value="deleteAllUsers">
</form>
<script>document.forms[0].submit()</script>
IFrame injection is more of a XSS vulnerability. A XSS vulnerability is more serious than a CSRF one because more damage can be done and it will always override any CSRF protection you have. Make sure you are always correctly encoding output for the context that the output is in (e.g. encode for HTML or for JavaScript as appropriate).
Check out the Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet - their best recommendation is to use the Synchronizer Token Pattern which seems similar to the link in your answer but can work in combination with cookies.
Also, here's a link to the XSS (Cross Site Scripting) Prevention Cheat Sheet.
Cross Site Request Forgery is when a site (let's say evil.example.com) can force a visiting user to make requests to another site (let's say example.com). It's not really forcing a user since embedding a image that (HTTP GET request) or POST request via form submission or javascript is not that difficult.
You should not make state or data changes via HTTP GET requests. img tags (get request) shouldn't be able to make any kind of change what so ever. If you allow this ... stop it. :)
POST requests need to contain a value that is not guessable by a remote attacker. Typically this is a per request random value.
So yes, CSRF is a a demonstrated, known vulnerability that you should bother protecting against.
Having done some further investigation:
It's possible for the attacker to host a <form> on their own site which submits to the target site (your site). All they need to do is get the victim to submit this form and it'll be submitted with their cookies and potentially their authentication.
It's also possible for the attacker to inject an <iframe> into your site, which would then be able to display this malicious <form>.
I'm thinking that a token-based approach is a better solution for my use case.

XSS as attack vector even if XSS data not stored?

I have a question about XSS
Can forms be used as a vector for XSS even if the data is not stored in the database and used at a later point?
i.e. in php the code would be this:
<form input="text" value="<?= #$_POST['my_field'] ?>" name='my_field'>
Showing an alert box (demonstrate that JS can be run) on your own browser is trivial with the code above. But is this exploitable across browsers as well?
The only scenario I see is where you trick someone into visiting a certain page, i.e. a combination of CSRF and XSS.
"Stored in a database and used at a later point": the scenario I understand about CSS is where you're able to post data to a site that runs JavaScript and is shown on a page in a browser that has greater/different privileges than your own.
But, to be clear, this is not wat I'm talking about above.
Yes, it's still an attack vector.
What you need to consider is:
Can an authenticated user be tricked into viewing this page with maliciously-crafted data?
The answer is this case is yes (assuming you have authenticated users). Because it's possible to direct someone to your site and pass in malicious variables to that field.
Yeah, it's still an attack vector, although impact is more situational.
Here's a contrived scenario that expands on previous answers if the form requires authentication to reach (and is easier if the site doesn't care if forms are submitted via POST or GET):
1) Attacker uses CSRF to login the victim using the attacker's credentials (e.g. <iframe src=http://../login?id=...&pass=..."></iframe>). This way the attacker brings the form to the victim and it doesn't matter if the victim doesn't have an account.
2) Attacker uses another CSRF to execute XSS against the form, which asks the victim for some credentials, etc. (This is where some convincing social engineering needs to occurr or the attacker has some useful JavaScript to use within the browser's Same Origin for the site.)
Another contrived scenario in which the vulnerable form performs some important action, like transfer money between accounts:
0) Vulnerable form uses hidden form fields with random values to prevent CSRF. The attacker doesn't know what the values are and can't set up a proper attack.
1) Attacker creates a CSRF payload that includes JavaScript to read a form's random csrf tokens (i.e. pull them from the browser's DOM).
2) Victim logs into site.
3) Attacker lures victim to CSRF payload, CSRF bootstraps the form request with the correct csrf tokens because it's executing in the victim's browser, within the victim site's Same Origin, and using the victim's auth session. The attacker doesn't need to know the csrf tokens, just be able to manipulate the form fields that store them.
4) Attacker benefits from having the victim submit the form -- no pop-ups or social engineering necessary aside from luring the victim to the CSRF payload, but the form needs to do something "useful" for the attacker.
i think what you are mean is, since User 2 cannot be showing previous data added by User 1, so can the XSS happen? So if User 1 hack the URL so that some $_GET params got displayed on the webpage as well (and then even, change it to a tinyurl), and spread this URL saying that it is really worthwhile to see this page, etc, then it might be possible.
So it is still better to escape all params when displaying the page.
That is absolutely a valid form of XSS. XSS comes in two forms - stored and reflected. Reflected is much more common, but stored has the potential to be more damaging. Reflected XSS is usually used as part of a social engineering attack. An attacker creates a URL like the following:
http://host.com/page.php?my_field=malicious_code
They will often shorten the URL with tinyutl or bit.ly, and get it out with the usual social engineering methods (email, message board, twitter, hijacked facebook accounts, etc.)

Resources