Defeating cross-site request forgery (CSRF) attacks
A cross-site request forgery (CSRF) is an attack that exploits the trust that a site has in a user's browser to transmit unauthorized commands.
The CSRF protection feature is not supported when the operation mode is Offline Protection or Transparent Inspection.
Configuration overview
To protect back-end servers from CSRF attacks, you create two lists of items: a list of web pages to protect against CSRF attacks, and a corresponding list of the URLs found in the requests that the pages generate.
- When FortiWeb receives a request for a web page in the list, it embeds a javascript in the web page. The script runs in the client's web browser and automatically appends the parameter
tknfv
(the anti-CSRF token) to any HTML link elements that have the href attribute (<a href>
) and HTML form elements. Subsequent requests that these HTML elements generate contain thetknfv
parameter. The parameter has the value of the cookie issued by Client Management. - The URL list contains all the URLs that you expect to contain the
tknfv
parameter, based on the web pages that you specified. When these URLs appear in requests without thetknfv
parameter, or the parameter does not match the cookie value for the session, FortiWeb takes the action you specify in the CSRF protection rule.
Create your configuration carefully, making sure that all the URLs in the list have corresponding entries in the page list, and Client Management is enabled. When FortiWeb checks requests for the token but has not added the script to the corresponding web page, it blocks or takes other action against the request.
Examples of requests with the anti-CSRF parameter
For example, a web page in the list of pages contains the following <a href>
element:
<a href=/csrf_test1.php>test</a>
This link generates the following request, which includes the parameter that the javascript has added:
http://example.com/csrf_test1.php?tknfv=3DF5BDCCIG3DCXNTE3RUNCTKRS3E36AD
Therefore, to make the feature work for this web page, you add /csrf_test1.php
to the list of URLs.
For an example using an HTML form element, the web page csrf_login.html
contains the following form:
<form name="do_some_action" id="form1" action="csrf_test2.php" method="GET">
<input type="text" name="username" value=""/>
<Input type="text" name="password" value=""/>
<input type="submit" value="do Action"/>
</form>
This form generates the following request when the page is added to the list of pages protected by a CSRF protection policy:
http://target-site.com/csrf_test2.php?username=test&password=123&tknfv=3DF5BDCCIG3DCXNTE3RUNCTKRS3E36AD
In this case, you add csrf_login.html
to the list of pages and /csrf_check2.php
to the list of URLs.
Parameter filters
In some cases, a request for a web page and the requests generated by its links have the same URL. FortiWeb cannot distinguish between requests to add javascript to and requests to check for the anti-CSRF parameter.
To avoid this issue, you create unique Page List Table and URL List Table items by adding a parameter filter to them. The parameter filter allows you to add additional criteria to match in the URL or HTTP body of a request.
For example, in the following form element, the parameters are in the body of the HTTP request, not the URL:
<form action="post.asp" enctype="MULTIPART/FORM-DATA" method="POST">
<input TYPE="FILE" NAME="FILE1">
<input TYPE="TEXT" NAME="TEXT1" VALUE="HELLO">
<input TYPE="SUBMIT" NAME="SUB1" VALUE="Upload File">
</form>
To allow FortiWeb to correctly recognize the POST request as one that should contain the anti-CSRF token, add a filter that checks for a parameter in the HTTP body to the corresponding URL List Table item. If the request for post.asp
does not contain the parameter specified in the URL List Table item, FortiWeb can instead match it with a post.asp
item in the Page List Table, and adds the javascript to it.
You can also match a parameter in the URL. For example, the request to match has the following URL:
/www.test.com?username=test&password=123
Request Type—Simple String
Full URL—/www.test.com
Parameter Filter—Selected
Parameter Name—username
Parameter Value Type—Regular Expression
Parameter Value—*
The parameter value * (asterix) matches any value.
Troubleshooting
If the feature is not working properly, ensure the following:
- The type of the web page to protect is HTML and contains the
<html>
and</html>
tags. -
The HTTP response code for the page is
200 OK
. - If the page is compressed, a corresponding uncompress policy is configured. For details, see Compression.
- The Maximum Body Cache Size value is larger than the size of the web page. For details, see Advanced settings.
To protect against CSRF attacks
- Go to Web Protection > Advanced Protection > CSRF Protection.
- Click Create New.
- Configure these settings:
- Alert—Accept the request and generate an alert email, log message, or both.
-
Alert & Deny—Block the request (reset the connection) and generate an alert, a log message, or both.
You can customize the web page that FortiWeb returns to the client with the HTTP status code. For details, see Customizing error and authentication pages (replacement messages).
-
Deny (no log)—Block the request (or reset the connection).
-
Period Block—Block subsequent requests from the client for a number of seconds. Also configure Block Period.
You can customize the web page that FortiWeb returns to the client with the HTTP status code. For details, see Customizing error and authentication pages (replacement messages).
- Informative
- Low
- Medium
- High
- Click OK.
- Under Page List Table, click Create New.
- Configure these settings:
- For Request Type, select Simple String, and for Full URL, enter
/www.test.com
. - For Request Type, select Regular Expression, and for Full URL, enter
test\.com
. - Click OK.
- Add any additional web pages that you want to protect.
- Under URL List Table, click Create New, and then configure the settings. The settings for adding a URL list item are the same as the ones that you use to add a page list item.
- Click OK.
- To apply the rule, in an inline protection profile, ensure Client Management is enabled, and then select the CSRF protection rule. For details, see Configuring a protection profile for inline topologies.
Name | Enter a unique name that can be referenced in other parts of the configuration. |
Action |
Select which action FortiWeb takes when it detects a missing or incorrect anti-CSRF parameter: The default value is Alert. Note: Logging and alert email occur only if the corresponding settings are enabled and configured. For details, see Logging and Alert email. |
Block Period |
Enter the number of seconds that you want to block subsequent requests from the client after the FortiWeb appliance detects a CSRF attack. This setting is available only if Action is set to Period Block. The valid range is from 1 to 3,600 seconds (1 hour). See also Monitoring currently blocked IPs. |
Severity |
When FortiWeb records violations of this rule in the attack log, each log message contains a Severity Level ( The default value is Low. |
Trigger Action | Select the trigger, if any, that FortiWeb uses when it logs or sends an alert email about a CSRF attack. For details, see Viewing log messages. |
Host Status |
Enable to apply this rule only to HTTP requests for specific web hosts. Also configure Host. Disable to match the rule based on the URL and any parameter filter only. |
Host |
Select a protected host names entry (either a web host name or IP address) that the This option is available only if Host Status is enabled. |
Request Type |
Select whether Full URL contains a literal URL (Simple String), or a regular expression designed to match multiple URLs (Regular Expression). When you select Regular Expression, you do not have to enter the complete URL for Full URL. For example, there are two ways you can configure the item to match the URL |
Full URL |
Enter either a literal URL or regular expression. |
Parameter Filter | Select to specify a parameter name and value to match. The parameter can be located in either the URL or the HTTP body of a request. For details, see Parameter filters. |
Parameter Name | Enter the parameter name to match. |
Parameter Value Type | Select whether Parameter Value contains a literal URL (Simple String), or a regular expression designed to match multiple values (Regular Expression). |
Parameter Value | Enter either a literal URL or regular expression. To match any parameter value, for Parameter Value Type, select Regular Expression, and enter * (asterisk). |