This article will discuss an issue where a client application is sending requests to the API Gateway using "unwise" characters which violate RFC 2396.
The above request URL fails due to the { and } characters used in the request from the client which were not URL-encoded and thus violate RFC 2396.
In such a scenario, the client will often receive a "HTTP 400 Bad Request" response from the API Gateway.
This security check for unsafe or unwise characters is performed at the Tomcat layer of the API Gateway appliance rather than the Gateway application code itself, which is why there are no entries of such failures in the SSG log files.
In customer's words:
I have a client application which is reporting 400 Bad Request errors, failing to be processed by the Gateway. We don't see any errors or warnings in the logs and are unsure why these requests are failing. We need to understand why this is happening and how to fix it. This used to work in older versions of the Gateway, why is this failing now?
This article applies to all supported API Gateway versions. The more secure behaviour and compliance with RFC 2396 was first introduced in version 9.2.
The root cause of this issue is because the sending client application is using what are considered "unwise" characters and were not URL-encoded which violates RFC 2396. In this case, RFC 2396 states that the following characters are to be considered unwise and should not be accepted (see Additional Information for more on RFC 2396):
unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
If any of those characters are used in the request URL / URI and are not properly URL-encoded, the API Gateway will not process the character per compliance for RFC 2396. The HTTP/1.1 specification requires that certain characters are %nn encoded when used in URI query strings. Unfortunately, many user agents including all the major browsers are not compliant with this specification and use these characters in un-encoded form.
For security reasons, it is not recommended to apply this workaround permanently. The permanent solution would be to correct the client application sending the request to better conform to RFC 2396 by not using unwise characters, or at the very least actively URL-encoding them.
The steps below are to be considered a temporary workaround only.
It is very important to only specify the minimum amount of unwise characters necessary to allow the failing requests. It is considered poor practice to accept all unwise characters as accepting more unwise or unsafe characters will widen the vector for attacks.
This same property can be set either via a bind mount or preferably through the docker-compose file.
docker-compose.yml example:
EXTRA_JAVA_ARGS: -Dtomcat.util.http.parser.HttpParser.requestTargetAllow={}|\^[]`
If the workarounds above do not work, there is one more step that can be taken:
This secondary workaround comes from the Apache Tomcat documentation. This workaround should only be used if the above workarounds do not work. Per the Tomcat documentation for that property:
The HTTP/1.1 specification requires that certain characters are %nn encoded when used in URI query strings. Unfortunately, many user agents including all the major browsers are not compliant with this specification and use these characters in unencoded form. To prevent Tomcat rejecting such requests, this attribute may be used to specify the additional characters to allow. If not specified, no additional characters will be allowed. The value may be any combination of the following characters: " < > [ \ ] ^ ` { | } . Any other characters present in the value will be ignored.
If both workarounds do not work, then the actual root cause needs to be addressed (as recommended earlier) which will be on the client application side and ensure that it conforms to RFC 2396 and the HTTP/1.1 standard by at least URL-encoding the characters.
Docker environment variables for API Gateway: https://techdocs.broadcom.com/us/en/ca-enterprise-software/layer7-api-management/api-gateway/10-0/using-the-container-gateway/environment-variables-for-the-container-gateway.html
RFC 2396 passage on unwise characters and special characters:
2.4.3. Excluded US-ASCII Characters
Although they are disallowed within the URI syntax, we include here a
description of those US-ASCII characters that have been excluded and
the reasons for their exclusion.
The control characters in the US-ASCII coded character set are not
used within a URI, both because they are non-printable and because
they are likely to be misinterpreted by some control mechanisms.
control = <US-ASCII coded characters 00-1F and 7F hexadecimal>
The space character is excluded because significant spaces may
disappear and insignificant spaces may be introduced when URI are
transcribed or typeset or subjected to the treatment of word-
processing programs. Whitespace is also used to delimit URI in many
contexts.
space = <US-ASCII coded character 20 hexadecimal>
The angle-bracket "<" and ">" and double-quote (") characters are
excluded because they are often used as the delimiters around URI in
text documents and protocol fields. The character "#" is excluded
because it is used to delimit a URI from a fragment identifier in URI
references (Section 4). The percent character "%" is excluded because
it is used for the encoding of escaped characters.
delims = "<" | ">" | "#" | "%" | <">
Other characters are excluded because gateways and other transport
agents are known to sometimes modify such characters, or they are
used as delimiters.
unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
Data corresponding to excluded characters must be escaped in order to
be properly represented within a URI.