PingGateway 2024.11

CSRF protection

In a Cross Site Request Forgery (CSRF) attack, a user unknowingly executes a malicious request on a website where they’re authenticated. A CSRF attack usually includes a link or script in a web page. When a user accesses the link or script, the page executes an HTTP request on the site where the user is authenticated.

CSRF attacks interact with HTTP requests as follows:

  • CSRF attacks can execute POST, PUT, and DELETE requests on the targeted server. For example, a CSRF attack can transfer funds out of a bank account or change a user’s password.

  • Because of same-origin policy, CSRF attacks cannot access any response from the targeted server.

When PingGateway processes POST, PUT, and DELETE requests, it checks a custom HTTP header in the request. If a CSRF token isn’t present in the header or not valid, PingGateway rejects the request and returns a valid CSRF token in the response.

Rogue websites that attempt CSRF attacks operate in a different website domain to the targeted website. Because of same-origin policy, rogue websites can’t access a response from the targeted website, and can’t, therefore, access the response or CSRF token.

The following example shows the data flow when an authenticated user sends a POST request to an application protected against CSRF:

csrf-legit

The following example shows the data flow when an authenticated user sends a POST request from a rogue site to an application protected against CSRF:

csrf-ilegit
  1. Set up SSO, so that AM authenticates users to the sample app through PingGateway:

    1. Set up AM and PingGateway as described in Use the default journey.

    2. Remove the condition in sso.json, so that the route matches all requests:

      "condition": "${find(request.uri.path, '^/home/sso')}"
  2. Test the setup without CSRF protection:

    1. Go to https://ig.example.com:8443/bank/index, and log in to the Sample App Bank through AM, as user demo, password Ch4ng31t.

    2. Send a bank transfer of $10 to Bob, and note that the transfer is successful.

    3. Go to http://localhost:8081/bank/attack-autosubmit to simulate a CSRF attack.

      In deployments that use a different protocol, hostname, or port for PingGateway, append the igUrl parameter, as follows:

      http://localhost:8081/bank/attack-autosubmit?igUrl=protocol://hostname:port

      When you access this page, a hidden HTML form is automatically submitted to transfer $1000 to the rogue user, using the PingGateway session cookie to authenticate to the bank.

      In the bank transaction history, note that $1000 is debited.

  3. Test the setup with CSRF protection:

    1. In PingGateway, replace sso.json with the following route:

      {
        "name": "Csrf",
        "baseURI": "http://app.example.com:8081",
        "heap": [
          {
            "name": "SystemAndEnvSecretStore-1",
            "type": "SystemAndEnvSecretStore"
          },
          {
            "name": "AmService-1",
            "type": "AmService",
            "config": {
              "agent": {
                "username": "ig_agent",
                "passwordSecretId": "agent.secret.id"
              },
              "secretsProvider": "SystemAndEnvSecretStore-1",
              "url": "http://am.example.com:8088/openam/"
            }
          },
          {
            "name": "FailureHandler-1",
            "type": "StaticResponseHandler",
            "config": {
              "status": 403,
              "headers": {
                "Content-Type": [ "text/plain; charset=UTF-8" ]
              },
              "entity": "Request forbidden"
            }
          }
        ],
        "handler": {
          "type": "Chain",
          "config": {
            "filters": [
              {
                "name": "SingleSignOnFilter-1",
                "type": "SingleSignOnFilter",
                "config": {
                  "amService": "AmService-1"
                }
              },
              {
                "name": "CsrfFilter-1",
                "type": "CsrfFilter",
                "config": {
                  "cookieName": "iPlanetDirectoryPro",
                  "failureHandler": "FailureHandler-1"
                }
              }
            ],
            "handler": "ReverseProxyHandler"
          }
        }
      }

      Notice the following features of the route compared to sso.json:

      • The CsrfFilter checks the AM session cookie for the X-CSRF-Token header. If a CSRF token isn’t present in the header or not valid, the filter rejects the request and provides a valid CSRF token in the header.

    2. Go to https://ig.example.com:8443/bank/index, and send a bank transfer of $10 to Alice.

      Because there is no CSRF token, PingGateway responds with an HTTP 403, and provides the token.

    3. Send the transfer again, and note that because the CSRF token is provided the transfer is successful.

    4. Go to http://localhost:8081/bank/attack-autosubmit to automatically send a rogue transfer.

      In deployments that use a different protocol, hostname, or port for PingGateway, append the igUrl parameter, as follows:

      http://localhost:8081/bank/attack-autosubmit?igUrl=protocol://hostname:port

      Because there is no CSRF token, PingGateway rejects the request and provides the CSRF token. However, because the rogue site is in a different domain to ig.example.com it can’t access the CSRF token.