For some reason, Cross-Site Request Forgery has been a vulnerability I have had a hard time getting a full understanding of so I thought it would make a good topic for one of these posts.
Before we can get into examples though, let's talk about what Cross-Site Request Forgery (CSRF) is. OWASP defines it as "an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated." They go into more detail, but let's pull that apart first. CSRF is all about having something happen within the context of a targeted user of an application. The attacker causes a user to perform an action within their account. This can be to add another user, change account info, or even something more specific to an application. OWASP continues by saying "with a little help of social engineering (such as sending a link via email or chat), an attacker may trick the users of a web application into executing actions of the attacker’s choosing." Involving another person like this is probably what breaks it in my head. Therefore, this is where we need to get a little creative. To demonstrate this vulnerability exists within a web application, we will need to play the part of the attacker and the victim. By crafting payloads and clicking on them from a browser window which has you logged in as the victim user we can show the risk associated with the vulnerability.
Alright, let's go through an example. We will use DVWA. Once its set up, log in and you will see they have a dedicated section for CSRF:

Imagine this is part of a real application and this page serves to allow a user to change their password. Only someone with an existing account could visit this page and change the password associated with their account. But with CSRF, we can force the admin user to change their password to something we choose, which would gain us access to their account.
To start, let's go through what happens when we change the password the right way:

When we enter a new password and click the "Change" button, it sends a GET
request with password_new
, password_conf
, and Change
parameters. We will take note of that and then forward the request.
What we can do to exploit CSRF, is host our own web page which appears innocent, but actually forces the visitor's browser to send a request to the password change page:

Here is what the source of the page looks like:

The important bit here is: img style="display:none" src="http://127.0.0.1:8081/vulnerabilities/csrf/?password_new=hacked&password_conf=hacked&Change=Change" alt="">
which will cause the browser to send the password change request but won't be visible anywhere on the page.
Now anyone visiting the page will request their password be changed. But if we try to visit the page from a browser that isn't currently logged in (such as Firefox Private Browsing) we can see that the target application will respond with 302 Found
:

Followed by a request to /login.php
:

In our Private browser, we won't see any of that since its loading in the image tag. If we then visit the login page and try our hacked
password, it won't work.

However, if we go back to our browser window which is logged in and then visit the attacker's site:

We get a response that the password has changed! We can then re-visit the login page in our Private Browsing window and log in with the password of "hacked".
So that's kind of the basic overview of CSRF. We forced an end user (admin) to execute an unwanted action (changing their password) in an application which they're currently authenticated (DVWA). But keep in mind that the password change request will happen to anyone that visits the attacker's website. As mentioned above, you would need to use some social engineering to lead your victim to the website. However, consider a scenario where you find Stored Cross-Site Scripting on an application. Something like a comment or other page which authenticated users visit. You could inject a CSRF payload into your XSS and then any user that browses to that specific page within the application will fall victim!