Skip to main content
Version: 3.11

csrf

Description#

The csrf Plugin can be used to protect your API against CSRF attacks using the Double Submit Cookie method.

This Plugin considers the GET, HEAD and OPTIONS methods to be safe operations (safe-methods) and such requests are not checked for interception by an attacker. Other methods are termed as unsafe-methods.

Attributes#

NameTypeRequiredDefaultDescription
namestringFalseapisix-csrf-tokenName of the token in the generated cookie.
expiresnumberFalse7200Expiration time in seconds of the CSRF cookie. Set to 0 to skip checking expiration time.
keystringTrueSecret key used to encrypt the cookie.

NOTE: encrypt_fields = {"key"} is also defined in the schema, which means that the field will be stored encrypted in etcd. See encrypted storage fields.

Enable Plugin#

The example below shows how you can enable the Plugin on a specific Route:

note

You can fetch the admin_key from config.yaml and save to an environment variable with the following command:

admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT-d '
{
"uri": "/hello",
"plugins": {
"csrf": {
"key": "edd1c9f034335f136f87ad84b625c8f1"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:9001": 1
}
}
}'

The Route is now protected and trying to access it with methods other than GET will be blocked with a 401 status code.

Sending a GET request to the /hello endpoint will send back a cookie with an encrypted token. The name of the token can be set through the name attribute of the Plugin configuration and if unset, it defaults to apisix-csrf-token.

note

A new cookie is returned for each request.

For subsequent requests with unsafe-methods, you need to read the encrypted token from the cookie and append the token to the request header by setting the field name to the name attribute in the Plugin configuration.

Example usage#

After you have configured the Plugin as shown above, trying to directly make a POST request to the /hello Route will result in an error:

curl -i http://127.0.0.1:9080/hello -X POST
HTTP/1.1 401 Unauthorized
...
{"error_msg":"no csrf token in headers"}

To get the cookie with the encrypted token, you can make a GET request:

curl -i http://127.0.0.1:9080/hello
HTTP/1.1 200 OK
Set-Cookie: apisix-csrf-token=eyJyYW5kb20iOjAuNjg4OTcyMzA4ODM1NDMsImV4cGlyZXMiOjcyMDAsInNpZ24iOiJcL09uZEF4WUZDZGYwSnBiNDlKREtnbzVoYkJjbzhkS0JRZXVDQm44MG9ldz0ifQ==;path=/;Expires=Mon, 13-Dec-21 09:33:55 GMT

This token must then be read from the cookie and added to the request header for subsequent unsafe-methods requests.

For example, you can use js-cookie to read the cookie and axios to send requests:

const token = Cookie.get('apisix-csrf-token');

const instance = axios.create({
headers: {'apisix-csrf-token': token}
});

Also make sure that you carry the cookie.

You can also use curl to send the request:

curl -i http://127.0.0.1:9080/hello -X POST -H 'apisix-csrf-token: eyJyYW5kb20iOjAuNjg4OTcyMzA4ODM1NDMsImV4cGlyZXMiOjcyMDAsInNpZ24iOiJcL09uZEF4WUZDZGYwSnBiNDlKREtnbzVoYkJjbzhkS0JRZXVDQm44MG9ldz0ifQ==' -b 'apisix-csrf-token=eyJyYW5kb20iOjAuNjg4OTcyMzA4ODM1NDMsImV4cGlyZXMiOjcyMDAsInNpZ24iOiJcL09uZEF4WUZDZGYwSnBiNDlKREtnbzVoYkJjbzhkS0JRZXVDQm44MG9ldz0ifQ=='
HTTP/1.1 200 OK

Delete Plugin#

To remove the csrf Plugin, you can delete the corresponding JSON configuration from the Plugin configuration. APISIX will automatically reload and you do not have to restart for this to take effect.

curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
{
"uri": "/hello",
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'