From 8c2e3ede37d6a73b184bfc4500e5f2d488542a81 Mon Sep 17 00:00:00 2001 From: Pedro Sousa <680496+pedrosousa@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:45:53 +0100 Subject: [PATCH] [WAF] Use JWT claims in custom rules (and rate limiting rules) (#17629) --- .../check-jwt-claim-to-protect-admin-user.mdx | 20 +++++++++++++ .../waf/rate-limiting-rules/parameters.mdx | 30 +++++++++++-------- 2 files changed, 37 insertions(+), 13 deletions(-) create mode 100644 src/content/docs/waf/custom-rules/use-cases/check-jwt-claim-to-protect-admin-user.mdx diff --git a/src/content/docs/waf/custom-rules/use-cases/check-jwt-claim-to-protect-admin-user.mdx b/src/content/docs/waf/custom-rules/use-cases/check-jwt-claim-to-protect-admin-user.mdx new file mode 100644 index 000000000000000..41d620bf42b5a45 --- /dev/null +++ b/src/content/docs/waf/custom-rules/use-cases/check-jwt-claim-to-protect-admin-user.mdx @@ -0,0 +1,20 @@ +--- +pcx_content_type: configuration +title: Issue challenge for admin user in JWT claim based on attack score +head: + - tag: title + content: Issue challenge for admin user in JWT claim based on attack score +--- + +:::note +To use claims inside a JSON Web Token (JWT), you must first set up a [token validation configuration](/api-shield/security/jwt-validation/configure/) in API Shield. +::: + +This example configures additional protection for requests with a JSON Web Token (JWT) with a user claim of `admin`, based on the request's [attack score](/waf/detections/attack-score/). + +Create a custom rule that issues a Managed Challenge if the user claim in a JWT is `admin` and the attack score is below 40. + +- **Expression**: `(lookup_json_string(http.request.jwt.claims[""][0], "user") eq "admin" and cf.waf.score < 40)` +- **Action**: _Managed Challenge_ + +In this example, `` is your [token configuration ID](/api-shield/security/jwt-validation/configure/) found in JWT Validation and `user` is the JWT claim. diff --git a/src/content/docs/waf/rate-limiting-rules/parameters.mdx b/src/content/docs/waf/rate-limiting-rules/parameters.mdx index 2ca1771cbced1bd..9a4f63029f46bfb 100644 --- a/src/content/docs/waf/rate-limiting-rules/parameters.mdx +++ b/src/content/docs/waf/rate-limiting-rules/parameters.mdx @@ -36,27 +36,27 @@ Set of parameters defining how Cloudflare tracks the request rate for the rule. Use one or more of the following characteristics: -| Dashboard value | API value | Notes | -| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| N/A(implicitly included) | `cf.colo.id`(mandatory) | [Do not use in expressions](#do-not-use-cfcoloid-as-a-field-in-expressions) | -| IP | `ip.src` | [Incompatible with **IP with NAT support**](#incompatible-characteristics) | -| IP with NAT support | `cf.unique_visitor_id` | [Incompatible with **IP**](#incompatible-characteristics) | -| **Header value of** (enter header name) | `http.request.headers[""]` | [Use lowercased header name in API](#use-a-lowercased-header-name-for-api-users) and [Missing field versus empty value](#missing-field-versus-empty-value) | -| **Cookie value of** (enter cookie name) | `http.request.cookies[""]` | [Recommended configurations](#recommended-configurations-when-using-cookie-value-of) and [Missing field versus empty value](#missing-field-versus-empty-value) | -| **Query value of** (enter parameter name) | `http.request.uri.args[""]` | [Missing field versus empty value](#missing-field-versus-empty-value) | +| Dashboard value | API value | Notes | +| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| N/A(implicitly included) | `cf.colo.id`(mandatory) | [Do not use in expressions](#do-not-use-cfcoloid-as-a-field-in-expressions) | +| IP | `ip.src` | [Incompatible with **IP with NAT support**](#incompatible-characteristics) | +| IP with NAT support | `cf.unique_visitor_id` | [Incompatible with **IP**](#incompatible-characteristics) | +| **Header value of** (enter header name) | `http.request.headers[""]` | [Use lowercased header name in API](#use-a-lowercased-header-name-for-api-users) and [Missing field versus empty value](#missing-field-versus-empty-value) | +| **Cookie value of** (enter cookie name) | `http.request.cookies[""]` | [Recommended configurations](#recommended-configurations-when-using-cookie-value-of) and [Missing field versus empty value](#missing-field-versus-empty-value) | +| **Query value of** (enter parameter name) | `http.request.uri.args[""]` | [Missing field versus empty value](#missing-field-versus-empty-value) | | **Host** | `http.host` | | **Path** | `http.request.uri.path` | | **AS Num** | `ip.geoip.asnum` | | **Country** | `ip.geoip.country` | | **JA3 Fingerprint** | `cf.bot_management.ja3_hash` | | **JA4** | `cf.bot_management.ja4` | -| **JSON string value of** (enter key) | `lookup_json_string(http.request.body.raw, "")` | [Missing field versus empty value](#missing-field-versus-empty-value) and [`lookup_json_string()` function reference](/ruleset-engine/rules-language/functions/#lookup_json_string) | -| **JSON integer value of** (enter key) | `lookup_json_integer(http.request.body.raw, "")` | [Missing field versus empty value](#missing-field-versus-empty-value) and [`lookup_json_integer()` function reference](/ruleset-engine/rules-language/functions/#lookup_json_integer) | -| **Form input value of** (enter field name) | `http.request.body.form[""]` | [Missing field versus empty value](#missing-field-versus-empty-value) | -| **JWT claim of** (enter token configuration ID, claim name) | `lookup_json_string(http.request.jwt.claims[""][0], "")` | [Missing field versus empty value](#missing-field-versus-empty-value) and [JWT Validation reference](/api-shield/security/jwt-validation/transform-rules/) | +| **JSON string value of** (enter key) | `lookup_json_string(http.request.body.raw, "")` | [Missing field versus empty value](#missing-field-versus-empty-value) and [`lookup_json_string()` function reference](/ruleset-engine/rules-language/functions/#lookup_json_string) | +| **JSON integer value of** (enter key) | `lookup_json_integer(http.request.body.raw, "")` | [Missing field versus empty value](#missing-field-versus-empty-value) and [`lookup_json_integer()` function reference](/ruleset-engine/rules-language/functions/#lookup_json_integer) | +| **Form input value of** (enter field name) | `http.request.body.form[""]` | [Missing field versus empty value](#missing-field-versus-empty-value) | +| **JWT claim of** (enter token configuration ID, claim name) | `lookup_json_string(http.request.jwt.claims[""][0], "")` | [Requirements for claims in JWT](#requirements-for-using-claims-inside-a-json-web-token-jwt), [missing field versus empty value](#missing-field-versus-empty-value) and [JWT Validation reference](/api-shield/security/jwt-validation/transform-rules/) | | **Body** | `http.request.body.raw` | | **Body size** (select operator, enter size) | `http.request.body.size` | -| **Custom** (enter expression) | Enter a custom expression. You can use a function such as `substring()` or `lower()`, or enter a more complex expression. | [Functions](/ruleset-engine/rules-language/functions/) | +| **Custom** (enter expression) | Enter a custom expression. You can use a function such as `substring()` or `lower()`, or enter a more complex expression. | [Functions](/ruleset-engine/rules-language/functions/) | The available characteristics depend on your Cloudflare plan. Refer to [Availability](/waf/rate-limiting-rules/#availability) for more information. @@ -223,6 +223,10 @@ If you use **Cookie value of** as a rate limiting rule characteristic, follow th - Create a [custom rule](/waf/custom-rules/) that blocks requests with more than one value for the cookie. - Validate the cookie value at the origin before performing any demanding server operations. +### Requirements for using claims inside a JSON Web Token (JWT) + +To use claims inside a JSON Web Token (JWT), you must first set up a [token validation configuration](/api-shield/security/jwt-validation/configure/) in API Shield. + ## Configuration restrictions - If the rule expression [includes IP lists](/waf/tools/lists/use-in-expressions/), you must enable the **Also apply rate limiting to cached assets** parameter.