title | keywords | description | |||||
---|---|---|---|---|---|---|---|
csrf |
|
The CSRF Plugin can be used to protect your API against CSRF attacks using the Double Submit Cookie method. |
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
.
Name | Type | Required | Default | Description |
---|---|---|---|---|
name | string | False | apisix-csrf-token |
Name of the token in the generated cookie. |
expires | number | False | 7200 |
Expiration time in seconds of the CSRF cookie. Set to 0 to skip checking expiration time. |
key | string | True | Secret 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.
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.
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
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
}
}
}'