Skip to main content

Core Ruleset: 920xxx

Rules with the 920xxx prefix protect web applications from protocol based attack vectors. These include things like validating and verifying only known request protocols, validating extensions and HTTP headers.

Paranoia Level 1 (default)

Rule: 920120

Prevent multipart/form-data name evasion attempts. This checks for the existence of meta-characters if post fields and ensures that post data matches rfc2183 specification.

This rule cannot be configured.

Message: Attempted multipart/form-data bypass

Example:

curl --request POST \
--url http://localhost:8088/ \
--header 'Content-Length: 0' \
--header 'Content-Type: application/octet-stream'
Rule: 920160

Ensure that the content-length header is all digits as per the rfc2616-sec14 specification.

Message: Content-Length HTTP header is not numeric

Example:

curl --request POST \
--url http://localhost:8088/ \
--header 'Content-Length: asdf'

# noblock
Rule: 920170

Prevent GET and HEAD requests from receiving request bodies, while the HTTP spec doesn't restrict request bodies for GET requests - application and web servers do not use this feature as a result this means an attacker could use the vector to send bodies to unsuspecting web applications.

Message: GET or HEAD Request with Body Content

Example:

curl --request GET \
--url http://localhost:8088/ \
--header 'Content-Length: 14' \
--header 'Content-Type: application/json' \
--data '{"test": true}'

# blocked 10001
Rule: 920171

A sibling rule to 920170 - this prevents the use of the Transfer-Encoding HTTP header with GET and HEAD requests. The transfer-encoding header allows a client to tell the server what encoding is being used when sending a request body.

Message: GET or HEAD Request with Transfer-Encoding

Example:

curl --request GET \
--url http://localhost:8088/ \
--header 'Content-Length: 14' \
--header 'Content-Type: application/jso n' \
--header 'Transfer-Encoding: gzip' \
--data '{"test": true}'

# noblock, skips 10001
Rule: 920180

Ensure a client that is using HTTP/1 protocols to send Content-Length or Transfer-Encoding headers with POST requests.

Message: POST without Content-Length or Transfer-Encoding headers

Example:

curl --request POST \
--url http://localhost:8088/ \
--header 'Content-Type: application/json' \
--data '{"test": true}'

# noblock
Rule: 920181

A sibling rule to 920180 - this rule requires that only one header from Content-Length and Transfer-Encoding is used in the request as per RFC7230 3.3.2.

Message: Content-Length and Transfer-Encoding headers present.

Example:

curl --request POST \
--url http://localhost:8088/ \
--header 'Content-Length: 14' \
--header 'Content-Type: application/json' \
--header 'Transfer-Encoding: gzip' \
--data '{"test": true}'

# noblock
Rule: 920190

Validates the Request-Range request header. This does a byte comparison of the header value and ensures that if the last byte position is present it is not a value less than the first byte position. This prevents potential memory allocation issues when attempt to locate parts of the HTTP message. This was found in 2011 and is a DOS vector - it could prevent exhaust the web servers memory causing it to crash.

Message: Range: Invalid Last Byte Value

Example:

curl --request POST \
--url http://localhost:8088/ \
--header 'Content-Length: 14' \
--header 'Content-Type: application/json' \
--header 'Range: bytes=15-32' \
--data '{"test": true}'

# noblock
Rule: 920210

The HTTP specification states that the Connection header should not have duplicates, most bots and automated request tools don't respect this rule of the specification and make invalid requests and will include keep-alive keep-alive or close close in the Connection header.

Message: Multiple/Conflicting Connection Header Data Found

Example:

curl --request GET \
--url http://localhost:8088/ \
--header 'Connection: close close'

# noblock
Rule: 920220

Validate encoding for the request URI for URL encoding inconsistencies.

Message: URL Encoding Abuse Attack Attempt

Example:

curl --request GET \
--url 'http://localhost:8088/?s=a%20b%20c%25'

# noblock
Rule: 920240
A sibling rule to `920220`, this inspects POST requests with the content type `application/x-www-form-urlencoding` and verifies the request body for URL encoding inconsistencies.

Message: URL Encoding Abuse Attack Attempt

Example:

curl --request POST \
--url http://localhost:8088/ \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data s=a%20b%20c%25
Rule: 920250

Validates UTF8 character encoding for the request. This requires that the application is configured to verify this TX:CRS_VALIDATE_UTF8_ENCODING

Message: UTF8 Encoding Abuse Attack Attempt

Example:

curl --request POST \
--url http://localhost:8088/ \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 's=À'
Rule: 920260

Disallow the use of full-width unicode characters as they may be subject to decoding evasions. Most web servers will handle this correctly.

Message: Unicode Full/Half Width Abuse Attack Attempt

Example:

curl --request POST \
--url http://localhost:8088/ \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'cmd=ア '
Rule: 920270

This rule restricts the types of characters that are sent by a request. This rule increases the scope of characters verified based on the configured paranoia level.

  • PL1: Full ASCII range without null characters
  • PL2: Full visible ASCII range including tab and newline
  • PL3: Visible lower ASCII range without percent
  • PL4: ASCII 38,44-46,48-58,61,65-90,95,97-122, A-Z a-z 0-9 = - _ . , : &

Each rule will validate against URI, headers and the request body.

Message: Invalid character in request (null character)

Example:

curl --request POST \
--url http://localhost:8088/ \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'cmd=	'

# noblock
Rule: 920280

Missing or empty host header.

Message: Request Missing a Host Header

Example:

curl --request GET \
--url http://localhost:8088/ \
--header 'Host: '
Rule: 920310

Missing or empty Accept header provided.

Message: Request Has an Empty Accept Header

Example:

curl --request GET \
--url http://localhost:8088/ \
--header 'Accept:'
Rule: 920330

Missing or empty Accept user agent provided.

Message: Empty User Agent Header

Example:

curl --request GET \
--url http://localhost:8088/ \
--header 'User-Agent:'
Rule: 920340

Validate that the client is sending Content-Type when they send a request body. The RFCs do not state that there must be a correlating content type header, however this can indicate a non-compliant browser and in some circumstances can cause servers to misbehave.

This rule will only block requests when paranoia level is 2 or higher.

Message: Request Containing Content, but Missing Content-Type header

Example:

curl --request POST \
--url http://localhost:8088/ \
--data '{"test":true}'
Rule: 920350

Prevents IP addresses from being sent as the Host header, the RFC doesn't restrict this however this is a common request pattern for malicious clients and is blocked by default.

Please note the WAF does not verify the legitimacy of an IP address, it verifies that it matches known patterns for IPv4 and IPv6.

Message: Host header is a numeric IP address

Example:

curl --request POST \
--url http://localhost:8088/ \
--header 'Content-Type: application/json' \
--header 'Host: 1.1.1.1' \
--data '{"test":true}'

Paranoia Level 3

Rules in this section will only apply when you configure your paranoia level to 3 or higher.

Rule: 920510

Verify that only supported cache control headers can be sent by clients. This helps protect against bot traffic that impersonates browsers but constructs incorrect request headers.

Default configuration: HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0

Message: Invalid Cache-Control request header

Example:

curl --request GET \
--url http://localhost:8088/ \
--header 'Cache-Control: non-standard-cache-control'

Paranoia Level 4

Rules in this section will only apply when you configure your paranoia level to 4 or higher.

Rule: 920460

Attempts to identify irrelevant escape character patterns in request payloads as most parsers will ignore overloaded escapes and process them as expected.

Has synergy with rule 932160

Message: Accept-Encoding header exceeded sensible length

Example:

curl --request GET \
--url http://localhost:8088/ \
--header 'Accept-Encoding: deflate;q=1.0, gzip;q=1.0, br;q=1.0, compress;q=1.0, identity;q=1.0, *;q=1.0'

Request restrictions

The following rules enforce restrictions on clients making requests; they range from validating arguments provided fall under a certain character length to validating file extensions.

By default, the configuration values are not included and these rules will not be checked. As these rules are restrictive, they can impact the way the clients intend to interact with the web server - to enable these settings with QuantWAF please contact support.

Rule: 920380

Maximum number of request arguments that a client can send.

Default configuration: 255

Message: Too many arguments in request

Example:

curl --request GET \
--url 'http://localhost:8088/?range(1,257)
Rule: 920360

Limit the number of characters that a URL argument can be named.

Default configuration: 100

Message: Argument name too long

Example:

    curl --request GET \
--url 'http://localhost:8088/?str_repeat(0,200)=true'
Rule: 920370

Limit the number of characters that a URL argument value can be.

Default configuration: 400

Message: Argument value too long

Example:

curl --request GET \
--url 'http://localhost:8088/?s=str_repeat(0,1000)'
Rule: 920390

Total argument exceeds configured sizes.

Default configuration: 64000

Message: Total arguments size exceeded

Example:

curl --request GET \
--url 'http://localhost:8088/?repeat(str_repeat(0,100)=str_repeat(0,1000), 1000)'
Rule: 920400

Single file upload size limits.

Default configuration: 1048576

Message: Uploaded file size too large

Rule: 920410

Total file size exceeds configured limit.

Default configuration: 1048576

Message: Uploaded file size too large

Rule: 920470

Provides generic allow list protection for which content types the WAF will permit. If the request does not present a valid content-type header the WAF will perform basic mime type sniffing to evaluate the file type against the allow list.s

Default configuration: |application/x-www-form-urlencoded| |multipart/form-data| |multipart/related| |text/xml| |application/xml| |application/soap+xml| |application/x-amf| |application/json| |application/cloudevents+json| |application/cloudevents-batch+json| |application/octet-stream| |application/csp-report| |application/xss-auditor-report| |text/plain|

Message: Illegal Content-Type header

Example:

curl --request GET \
--url 'http://localhost:8088/?repeat(str_repeat(0,100)=str_repeat(0,1000), 1000)'
Rule: 920430

Restrict which HTTP protocols can be used to make requests.

Default configuration: HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0

Message: HTTP protocol version is not allowed by policy

Example:

curl --request GET \
--url 'http://localhost:8088/?repeat(str_repeat(0,100)=str_repeat(0,1000), 1000)'
Rule: 920440

Restricts accessible file extensions that can be requested from your site. This protects against unintended files from being access from the server.

Message: URL file extension is blocked by policy

Configuration:

.asa, .asax, .ascx, .axd, .backup, .bak, .bat, .cdx, .cer, .cfg, .cmd, .com, .config, .conf, .cs, .csproj, .csr, .dat, .db, .dbf, .dll, .dos, .htr, .htw, .ida, .idc, .idq, .inc, .ini, .key, .licx, .lnk, .log, .mdb, .old, .pass, .pdb, .pol, .printer, .pwd, .rdb, .resources, .resx, .sql, .swp, .sys, .vb, .vbs, .vbproj, .vsdisco, .webinfo, .xsd, .xsx,
Rule: 920450

Restricts which HTTP headers can be sent to your site. More information on this can be found at https://access.redhat.com/security/vulnerabilities/httpoxy.

Configuration

proxy, lock-token, content-range, if
Rule: 920500

Prevents common backup or working extensions.

Default configuration: HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0

Message: Attempt to access a backup or working file

Example:

curl --request GET \
--url 'http://localhost:8088/index.php~'
Rule: 920520

Restrict the length of Accept-Encoding to 50 characters. The character length is based on the allowed values list provided by the RFC.

Default configuration: HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0

Message: Accept-Encoding header exceeded sensible length

Example:

curl --request GET \
--url http://localhost:8088/ \
--header 'Accept-Encoding: deflate;q=1.0, gzip;q=1.0, br;q=1.0, compress;q=1.0, identity;q=1.0, *;q=1.0'
Rule: 920530

Restrict multiple instances of charset being set with the content type.

Message: Multiple charsets detected in content type header

Example:

curl --http0.9 \
--request GET \
--url http://localhost:8088/ \
--header 'Content-Type: application/json; charset=utf-8; charset=utf-8'