diff --git a/src/content/docs/waf/rate-limiting-rules/best-practices.mdx b/src/content/docs/waf/rate-limiting-rules/best-practices.mdx index 3edf0e190c16a01..1602ec3a7e90d40 100644 --- a/src/content/docs/waf/rate-limiting-rules/best-practices.mdx +++ b/src/content/docs/waf/rate-limiting-rules/best-practices.mdx @@ -392,24 +392,19 @@ This type of rate limiting requires that the server scores every served request For example, the following rule defines a total complexity budget of 1,000 per hour: -| Setting | Value | -| --------------------------- | ------------------------------------- | -| Matching criteria | URI Path contains `/graphql` | -| Expression | `http.request.uri.path eq "/graphql"` | -| Counting characteristics | Cookie (`session_id`) | -| Score rate (score / period) | 1,000 / 1 hour | -| Score location | Response header (`score`) | -| Action | Block | +| Setting | Value | +| ------------------------ | ------------------------------------- | +| Matching criteria | URI Path contains `/graphql` | +| Expression | `http.request.uri.path eq "/graphql"` | +| Counting characteristics | Cookie (`session_id`) | +| Score per period | 1,000 | +| Period | 1 hour | +| Response header name | `score` | +| Action | Block | _This example rule requires Advanced Rate Limiting and payload inspection._ -:::note - -Currently, you can only create complexity-based (or score-based) rules such as the one above [via API](/waf/rate-limiting-rules/create-api/#example-d---complexity-based-rate-limiting-rule). - -::: - -When the origin server processes a request, it adds a `score` HTTP header to the response with a value representing how much work the origin has performed to handle it — for example, `400`. In the next hour, the same client can perform requests up to an additional budget of `600`. As soon as this budget is exceeded, later requests will be blocked until the timeout expires. +When the origin server processes a request, it adds a `score` HTTP header to the response with a value representing how much work the origin has performed to handle it — for example, `100`. In the next hour, the same client can perform requests up to an additional budget of `900`. As soon as this budget is exceeded, later requests will be blocked until the timeout expires. ### Limit any individual query’s complexity diff --git a/src/content/docs/waf/rate-limiting-rules/create-api.mdx b/src/content/docs/waf/rate-limiting-rules/create-api.mdx index acfa001e54239fe..f76681de1d58b70 100644 --- a/src/content/docs/waf/rate-limiting-rules/create-api.mdx +++ b/src/content/docs/waf/rate-limiting-rules/create-api.mdx @@ -128,19 +128,19 @@ The new rule does not consider requests for cached assets when calculating the r ### Example D - Complexity-based rate limiting rule :::note -[Complexity-based rate limiting](/waf/rate-limiting-rules/request-rate/#complexity-based-rate-limiting) is available in beta and can only be configured via API. +[Complexity-based rate limiting](/waf/rate-limiting-rules/request-rate/#complexity-based-rate-limiting) is only available to Enterprise customers with Advanced Rate Limiting. ::: This example adds a rate limiting rule to the `http_ratelimit` phase entry point ruleset for the zone with ID `$ZONE_ID`. The phase entry point ruleset already exists, with ID `$RULESET_ID`. -The new rule is a complexity-based rate limiting rule that takes the `my-score` HTTP response header into account to calculate a total complexity score for the client. The counter with the total score is updated when there is a match for the rate limiting rule's counting expression (in this case, the same as the rule expression since `counting_expression` is an empty string). When this total score becomes larger than `400` during a period of `60` seconds, any later client requests will be blocked for a period of `600` seconds (10 minutes). +The new rule is a complexity-based rate limiting rule that takes the `my-score` HTTP response header into account to calculate a total complexity score for the client. The counter with the total score is updated when there is a match for the rate limiting rule's counting expression (in this case, the same as the rule expression since `counting_expression` is an empty string). When this total score becomes larger than `400` during a period of `60` seconds (one minute), any later client requests will be blocked for a period of `600` seconds (10 minutes). diff --git a/src/content/docs/waf/rate-limiting-rules/parameters.mdx b/src/content/docs/waf/rate-limiting-rules/parameters.mdx index 051e8c5e2a9fdd9..72bf24c7727a89f 100644 --- a/src/content/docs/waf/rate-limiting-rules/parameters.mdx +++ b/src/content/docs/waf/rate-limiting-rules/parameters.mdx @@ -84,12 +84,21 @@ If you set a custom counting expression, it will not automatically extend the ru For example, you might want to perform rate limiting for clients sending more than five requests to `/api/` resulting in a `403` HTTP status code from the origin server. In this case, the matching expression would be `starts_with(http.request.uri.path, "/api/")` and the counting expression would be `http.response.code eq 403 and starts_with(http.request.uri.path, "/api/")`. If the counting expression did not include the matching expression (that is, if you had set the counting expression to `http.response.code eq 403`), any response with a `403` status code on any URL would increase the counter. ::: +### When rate exceeds + +- Field name in the API: _N/A_ (different API fields required according to the selected option) + +The rate limiting counting can be: + +- **Request based**: Performs rate limiting based on the number of incoming requests during a given period. This is the only counting method when complexity-based rate limiting is not available. +- **Complexity based**: Performs rate limiting based on the [complexity](/waf/rate-limiting-rules/request-rate/#complexity-based-rate-limiting) or cost of handling requests during a given period. Only available to Enterprise customers with Advanced Rate Limiting. + ### When rate exceeds > Requests - Data type: - Field name in the API: `requests_per_period` -The number of requests over the period of time that will trigger the rule. +The number of requests over the period of time that will trigger the rule. Applies to request-based rate limiting. ### When rate exceeds > Period @@ -100,6 +109,20 @@ The period of time to consider (in seconds) when evaluating the request rate. Th The available API values are: `10`, `60` (one minute), `120` (two minutes), `300` (five minutes), `600` (10 minutes), or `3600` (one hour). +### When rate exceeds > Score per period + +- Data type: +- Field name in the API: `score_per_period` + +Maximum score per period. When this value is exceeded, the rule action will execute. Applies to [complexity-based rate limiting](/waf/rate-limiting-rules/request-rate/#complexity-based-rate-limiting). + +### When rate exceeds > Response header name + +- Data type: +- Field name in the API: `score_response_header_name` + +Name of HTTP header in the response, set by the origin server, with the score for the current request. Applies to [complexity-based rate limiting](/waf/rate-limiting-rules/request-rate/#complexity-based-rate-limiting). + ### Then take action - Data type: @@ -111,9 +134,9 @@ Use one of the following values in the API: `block`, `challenge`, `js_challenge` If you select the _Block_ action, you can define a custom response using the following parameters: -- [**With response type**](#with-response-type-for-block-action) -- [**With response code**](#with-response-code-for-block-action) -- [**Response body**](#response-body-for-block-action) +- [With response type](#with-response-type-for-block-action) +- [With response code](#with-response-code-for-block-action) +- [Response body](#response-body-for-block-action) #### With response type (for _Block_ action) diff --git a/src/content/docs/waf/rate-limiting-rules/request-rate.mdx b/src/content/docs/waf/rate-limiting-rules/request-rate.mdx index a6b5dc98f08cb85..c1872c98f3e283b 100644 --- a/src/content/docs/waf/rate-limiting-rules/request-rate.mdx +++ b/src/content/docs/waf/rate-limiting-rules/request-rate.mdx @@ -116,22 +116,23 @@ Request 4 matches the rule expression and therefore Cloudflare evaluates the rat ## Complexity-based rate limiting :::note -Complexity-based rate limiting is available in beta to Enterprise customers with Advanced Rate Limiting, and can only be configured via API. +Only available to Enterprise customers with Advanced Rate Limiting. ::: A complexity-based rate limiting rule performs rate limiting based on the complexity or cost of handling requests during a given period, instead of the number of requests in the same period. A common use case is to score each request with an estimate of the cost (or complexity) required to serve that request. The rate limiting rule can then enforce a maximum limit on the total complexity that each client can put on the application over a given period, regardless of the total number of requests sent by that client. -When you configure a complexity-based rate limiting rule, the origin server must include an HTTP header in the response with its complexity score. +When you configure a complexity-based rate limiting rule, the origin server must include an HTTP header in the response with its complexity score. This score corresponds to the complexity (or cost) of serving the current request. The score value must be between 1 and 1,000,000. Complexity-based rate limiting rules must contain the following properties: -- **Score** (API field: `score_per_period`): Maximum score per period. When this value is exceeded, the rule action will execute. -- **Score response header name** (API field: `score_response_header_name`): Name of HTTP header in the response, set by the origin server, with the score for the current request. The score corresponds to the complexity (or cost) of serving the current request. The score value must be between 1 and 1,000,000. +- [Score per period](/waf/rate-limiting-rules/parameters/#when-rate-exceeds--score-per-period): Maximum score per period. When this value is exceeded, the rule action will execute. +- [Period](/waf/rate-limiting-rules/parameters/#when-rate-exceeds--period): The period of time to consider when evaluating the request rate. +- [Response header name](/waf/rate-limiting-rules/parameters/#when-rate-exceeds--response-header-name): Name of HTTP header in the response, set by the origin server, with the score for the current request. Cloudflare keeps counters with the total score of all requests with the same values for the rule characteristics that match the rule expression. The score increases by the value provided by the origin in the response when there is a match for the counting expression (by default, it is the same as the rule expression). When the total score is larger than the configured maximum score per period, the rule action is applied. If the origin server does not provide the HTTP response header with a score value or if the score value is outside of the allowed range, the corresponding rate limiting counter will not be updated. -For an example of a complexity-based rate limiting rule, refer to [Create rate limiting rules via API](/waf/rate-limiting-rules/create-api/#example-d---complexity-based-rate-limiting-rule). +For an example of a complexity-based rate limiting rule, refer to [Rule examples](/waf/rate-limiting-rules/use-cases/#example-4). diff --git a/src/content/docs/waf/rate-limiting-rules/use-cases.mdx b/src/content/docs/waf/rate-limiting-rules/use-cases.mdx index 049e865719d43df..bcf888a9c3c7115 100644 --- a/src/content/docs/waf/rate-limiting-rules/use-cases.mdx +++ b/src/content/docs/waf/rate-limiting-rules/use-cases.mdx @@ -41,7 +41,7 @@ Rule characteristics: - _Data center ID_ (included by default when creating the rule in the dashboard) - _IP Address_ -- _HTTP Header_ > `x-api-key` +- _Header value of_ > `x-api-key` @@ -58,6 +58,44 @@ Rule characteristics: - _Data center ID_ (included by default when creating the rule in the dashboard) - _IP Address_ -- _HTTP Header_ > `user-agent` +- _Header value of_ > `user-agent` + +## Example 4 + +:::note +[Complexity-based rate limiting](/waf/rate-limiting-rules/request-rate/#complexity-based-rate-limiting) is only available to Enterprise customers with Advanced Rate Limiting. +::: + +The following [rate limiting rule](/waf/rate-limiting-rules/create-zone-dashboard/) performs complexity-based rate limiting. The rule takes into account the `my-score` HTTP response header provided by the origin server to calculate a total complexity score for the client with the provided API key. + +The counter with the total score is updated when there is a match for the rate limiting rule's [counting expression](/waf/rate-limiting-rules/parameters/#increment-counter-when) (in this case, the same as the rule expression since a counting expression was not provided). When this total score becomes larger than `400` during a period of one minute, any later client requests will be blocked for a period of 10 minutes. + + + +Expression:
+`(http.request.uri.path wildcard "/graphql/*")` + +Rule characteristics: + +- _Data center ID_ (included by default when creating the rule in the dashboard) +- _Header value of_ > `x-api-key` + +When rate exceeds: **Complexity based** + +- Score per period: `400` +- Period: _1 minute_ +- Response header name: `my-score` + +Then take action: + +- Choose action: _Block_ + +With the following behavior: **Block for the selected duration** + +- Duration: _10 minutes_ + +
+ +For an API example with this rule configuration, refer to [Create a rate limiting rule via API](/waf/rate-limiting-rules/create-api/#example-d---complexity-based-rate-limiting-rule).