CSRF
Apply a CSRF filter to the gateway to help prevent cross-site request forgery attacks.
To help prevent CSRF attacks, you can use this policy to create a CSRF filter. For each route that you apply the policy to, the filter checks to make sure that a request’s origin matches its destination. If the origin and destination do not match, a 403 Forbidden error code is returned. Note that because CSRF attacks specifically target state-changing requests, the filter only acts on HTTP requests that have a state-changing method such as POST or PUT.
For more information, see the following resources.
- Envoy docs for CSRF, which describe the four enablement modes: disabled, enabled, ignored, and shadow mode.
- Gloo Gateway API docs
If you import or export resources across workspaces, your policies might not apply. For more information, see Import and export policies.
Before you begin
This guide assumes that you use the same names for components like clusters, workspaces, and namespaces as in the getting started. If you have different names, make sure to update the sample configuration files in this guide.
- Set up Gloo Mesh Gateway in a single cluster.
- Install Bookinfo and other sample apps.
Configure an HTTP listener on your gateway and set up basic routing for the sample apps.
Configure CSRF policies
You can apply a CSRF policy at the route level. For more information, see Applying policies.
Review the following sample configuration file. Continue to the Verify CSRF policies section for example steps on how to check that the CSRF filter is working.
apiVersion: security.policy.gloo.solo.io/v2
kind: CSRFPolicy
metadata:
annotations:
cluster.solo.io/cluster: ""
name: csrf-policy
namespace: bookinfo
spec:
applyToRoutes:
- route:
labels:
route: ratings
config:
additionalOrigins:
- regex: allowThisOne.solo.io
filterEnabled: true
Review the following table to understand this configuration.
Setting | Description |
---|---|
spec.applyToRoutes | Use labels to configure which routes to apply the policy to. This example label matches the app and route from the example route table that you apply separately. If omitted and you do not have another selector such as applyToDestinations , the policy applies to all routes in the workspace. |
spec.config.additionalOrigins | Set any additional origins to allow besides the destination origin. For allowed string matching, see the API reference. |
spec.config.filterEnabled | Set to true so that the CSRF policy is enforced. Replace with shadowEnabled: true to track metrics but not enforce blocking. |
Enable CSRF metrics
- To enable CSRF metrics, edit the
istio-ingressgateway
deployment. If your gateway is in a different namespace, update the command accordingly.kubectl edit deploy $(kubectl get deployment -l "app=istio-ingressgateway" -n gloo-mesh-gateways -o jsonpath='{.items[].metadata.name}') -n gloo-mesh-gateways
- Add the following annotation to the
istio-ingressgateway
.spec: template: metadata: annotations: proxy.istio.io/config: | proxyStatsMatcher: inclusionRegexps: - .*csrf.*
Now, when you port-forward the istio-ingressgateway
pod on the Envoy admin port 15000, you can review CSRF metrics. These metrics track the number of valid requests, the number of total invalid requests, and the number of invalid requests due to a missing origin.
- Continue to the Verify CSRF policies section for example steps on how to check the metrics.
- For more information about the metrics, see the Envoy docs.
Example use case: Shadow-enabled metrics. You might not want to block all requests with mismatching origin headers, but still track such requests. To do so, you can set up your CSRF policy with shadowEnabled: true
instead of filterEnabled: true
. With shadow enabled, requests are not blocked. However, the metrics still show when requests do not have the allowed origin header.
Verify CSRF policies
Update and apply the example CSRF policy in the cluster with the Bookinfo workspace in your example setup.
kubectl apply -f - << EOF apiVersion: security.policy.gloo.solo.io/v2 kind: CSRFPolicy metadata: annotations: cluster.solo.io/cluster: "" name: csrf-policy namespace: bookinfo spec: applyToRoutes: - route: labels: route: ratings config: additionalOrigins: - regex: allowThisOne.solo.io filterEnabled: true EOF
Send a request to the ratings app through the ingress gateway that the route table is attached to. Do not include an origin header in the request. Note that because CSRF attacks specifically target state-changing requests, the filter only acts on HTTP requests that have a state-changing method such as POST or PUT.
Note that the response is a 403 Forbidden error code because no origin is set.
HTTP/1.1 403 Forbidden
Send the request again. This time, set the origin to a different domain than you used in the policy, such as
http://istio.io
.Note that the response is still a 403 Forbidden error code because the origins do not match.
HTTP/1.1 403 Forbidden
Send the request again. This time, set the origin to match the allowed origin in your CSRF policy.
Note that the response is successful.
HTTP/1.1 200 OK
If you enabled CSRF metrics, port-forward the
istio-ingressgateway
pod on the Envoy admin port 15000. If your gateway is in a different namespace, update the command accordingly.kubectl port-forward -n gloo-mesh-gateways $(kubectl get pods -l "app=istio-ingressgateway" -n gloo-mesh-gateways -o jsonpath='{.items[].metadata.name}') 15000
Open your browser to the localhost stats to review CSRF metrics. In the output, search for
csrf
.- Example metrics:
http.outbound_0.0.0.0_8443.csrf.request_valid: 1 http.outbound_0.0.0.0_8443.csrf.request_invalid: 1 http.outbound_0.0.0.0_8443.csrf.missing_source_origin: 1
Cleanup
You can optionally remove the resources that you set up as part of this guide.
kubectl -n bookinfo delete csrfpolicy csrf-policy