ARMR Sanitization Rule
Overview
The ARMR Sanitization rule can be used to verify data entering the workflow of a server via a HTTP request. Such data is referred to here as a payload, and may be in the form of a String, JSON, or XML. Each payload is then matched against known safe and unsafe patterns. The unsafe patterns include common Cross-Site-Scripting, SQL Injection, and Path Traversal attacks. Any payload that matches an unsafe pattern will be marked for sanitization, which means that a payload has been found to be potentially malicious and an action will need to be taken. If the rule action is configured in protect mode, the payload will be prevented from being used by the system and a CEF event will be generated. Configuring the rule in detect mode will generate a CEF event and allow the workflow to continue uninterrupted. It is also possible that a payload may not cleanly match with any of the safe or unsafe patterns. Such payloads are labelled as undetermined values. For such cases, the rule can be configured to automatically mark all undetermined values as being safe or unsafe. Safe undetermined values will be logged, where unsafe undetermined values will be handled by the action.
Given (Condition)
Directive | Attribute | Necessity | Description |
---|---|---|---|
request | paths | mandatory | This determines the HTTP endpoints for which protection is enabled. An optional key value pair can be supplied to this declaration where the key is paths and the value can be one of the following (indicating specifically targeted HTTP endpoints)- a quoted string |
-
a list of one or more quoted-strings
-
the wildcard character (*) is supported to cover multiple URIs. This can be specified as:
-
a prefix
*/target.jsp
-
a suffix
/myApplication/*
-
both a prefix and a suffix
*/target*
-
-
if the wildcard character is one of the characters in the path itself, it has to be escaped using the backslash character
\*
If no value is specified then protection will be applied to all HTTP endpoints by default.If a string value is specified then it must:- not be empty -
be a valid relative URIThe
paths
can be configured similar to,-request(paths: ["/api/user", "/api/cart"])
| |undetermined
|values
| mandatory | If a payload cannot be cleanly identified as beingsafe
orunsafe
then the rule will consider these values as being undetermined. If undetermined values are configured as unsafe, then it will be handled by the action. Ifvalues
are considered safe, then they will be logged for visibility but the action will not take effect.Thevalues
can be configured only as,-undetermined(values: safe)
-
undetermined(values: unsafe)
Undetermined values are treated assafe
by default.An undetermined value is likely of interest to security engineers. Once satisfied that an application is able to safely handle undetermined values, there is a rule syntax to stop the generation of security events in this case:-undetermined(values: safe, logging: off)
| |ignore
|payload
| optional | The rule is used to verify data entering the workflow of a server against known safe and unsafe patterns. Such data is referred to here as a payload, and may be in the form of a String, JSON, or XML. If the rule has marked a payload as being unsafe, but it has been reasoned that the payload is actually safe to use, then this configuration can be used to ignore those payloads. An array of payload values can be specified.Thepayload
can be configured similar to,-ignore(payload: ["abcd", "efgh", "1234"])
Thepayload
can be configured along with theattribute
in the sameignore
declaration.ignore(payload: ["abcd", "efgh", "1234"],
attribute: ["field1", "keyname2"])
| | |attribute
| optional | If the ARMR Sanitization has marked a payload as being unsafe, but it has been reasoned that the assignment of that value, or indeed any value, within the codebase won’t be used in a malicious way, then this configuration will allow the assignment to happen for the attribute. An attribute could be a class field, or a map value, or URL query parameter. An array of attribute names can be specified.Theattribute
can be configured similar to,-ignore(attribute: ["field1", "keyname2"])
Theattribute
can be configured along with thepayload
in the sameignore
declaration.ignore(attribute: ["field1", "keyname2"],
payload: ["abcd", "efgh", "1234"])
|
When (Event)
The rule actively examines payloads coming from HTTP requests that use the javax.servlet.ServletRequest
API and JSON/XML parsing within Spring Boot applications.
API |
---|
javax.servlet.ServletRequest.getParameter(Ljava/lang/String;)Ljava/lang/String; |
javax.servlet.ServletRequest.getParameterMap()Ljava/util/Map; |
javax.servlet.ServletRequest.getParameterValues()[Ljava/lang/String; |
javax.servlet.ServletInputStream.readLine([BII)I |
Spring Boot - JSON to Object Conversion |
Spring Boot - XML to Object Conversion |
Then (Action)
protect | Payloads that are marked for sanitization will be blocked by either throwing an exception, or replacing the malicious value with a null reference. Doing so will prevent the HTTP request from being processed. If logging is configured, a CEF entry is added to the log file with details of the event. This information includes the payload that was marked for sanitization, the HTTP endpoint, the affected class, and the attribute associated with the payload and class. |
detect | Monitoring mode: the application behaves as normal.A CEF entry is added to the log file with details of the event. This information includes the payload that was marked for sanitization, the HTTP endpoint, the affected class, and the attribute associated with the payload and class.A log message must be specified with this action. |
Examples
Basic Single Rule Configuration
The following example shows the basic configuration for a single ARMR Sanitization rule.
The rule will:
-
enable sanitization in
protect
mode for any HTTP request. Anyunsafe
payload caught by the sanitization rule inprotect
mode will generate a CEF log entry, and will be blocked from being consumed by the application. -
consider any
undetermined
value to besafe
. All safe undetermined values will generate a CEF log entry, but will not be handled by the action. -
log a
high
severity CEF entry with a custom message of “A payload has been marked for sanitization“.
app("SECURITY POLICY"):
requires(version: ARMR/2.7)
sanitization("SANITIZATION :01"):
request()
undetermined(values: safe)
protect(message: "A payload has been marked for sanitization", severity: high)
endsanitization
endapp
Advanced Multiple Rule Configuration
The following example shows a more detailed configuration with multiple ARMR Sanitization rules.
The first rule will:
-
enable sanitization in
detect
mode for any HTTP request that is not mapped by the rule namedSANITIZATION :02
. Anyunsafe
payload caught by the sanitization rule indetect
mode will generate a CEF log entry. It is recommended to review and report any suspicious entries in the CEF log as further sanitization rules can be configured based on this data. -
consider any
undetermined
values to beunsafe
. All unsafe values are handled by the action, which in this case will be handled by thedetect
action. -
log a
medium
severity CEF entry using the default message.
The second rule will:
-
enable sanitization in
protect
mode, but only for the URIs"/api/user/regiester", "/api/shop/basket/add"
. Any unsafe payload caught by the sanitization rule inprotect
mode will generate a CEF log entry, and will be blocked from being consumed by the application. -
consider any
undetermined
value asunsafe
. All unsafe values are handled by the action, which in this case will be theprotect
action. -
ignore the
payload: ["1=1=1 Air Force 1=1=1"]
because this is the actual name of a product being sold by the online store that could be added to the basket. A review of this value found that it could be safely ignored. The result of not ignoring this particular payload would have resulted in the ARMR Sanitization rule blocking it due to the detection of SQL Injection. -
ignore the
attribute: ["time"]
because this is a field of a class that is assigned a value coming from an HTTP request. After reviewing the business logic of how this field is being used in the application, it was decided that values assigned to this field cannot be used in a malicious way making it safe to ignore. This will avoid the ARMR Sanitization rule protecting against values that are of no concern. -
log a high severity CEF entry with a custom message of “sensitive API endpoint under attack” .
app("SECURITY POLICY"):
requires(version: ARMR/2.7)
sanitization("SANITIZATION :01"):
request()
undetermined(values: unsafe)
detect(message: "", severity: medium)
endsanitization
sanitization("SANITIZATION :02"):
request(paths: ["/api/user/regiester",
"/api/shop/basket/add"])
undetermined(values: unsafe)
ignore(payload: ["1=1=1 Air Force 1=1=1"],
attribute: ["time"])
protect(message: "sensitive API endpoint under attack", severity: high)
endsanitization
endapp
Logging
A log entry similar to the following is generated when an unsafe payload for protect and detect is caught by the sanitization rule, and when a safe undetermined value is caught.
Protect Mode
<10>1 2021-02-19T20:06:56.939Z localhost java 19559 - - CEF:0|ARMR:ARMR|ARMR|2.7|SANITIZATION :01|Execute Rule|High|rt=Feb 19 2021 20:06:56.939 +0000 dvchost=localhost procid=19559 appVersion=1 ruleType=sanitization securityFeature=sanitization datainput act=protect msg=A payload has been classified as malicious reason=SQLI taintSource=HTTP_SERVLET httpRequestUri=/api/forum/print/requestbody/as/map httpRequestMethod=GET internalHttpRequestUri=/api/forum/print/requestbody/as/map className=java.util.LinkedHashMap attribute=MAP_KEY["message"] payload=' OR '1'\='1 remoteIpAddress=127.0.0.1 localIpAddress=127.0.0.1 localPort=8080
Detect Mode
<10>1 2021-02-19T20:15:25.002Z localhost java 19559 - - CEF:0|ARMR:ARMR|ARMR|2.7|SANITIZATION :01|Execute Rule|High|rt=Feb 19 2021 20:15:25.002 +0000 dvchost=localhost procid=19559 appVersion=1 ruleType=sanitization securityFeature=sanitization datainput act=detect msg=A payload has been classified as malicious reason=XSS taintSource=HTTP_SERVLET httpRequestUri=/api/forum/print/xml/requestbody/complex httpRequestMethod=GET internalHttpRequestUri=/api/forum/print/xml/requestbody/complex className=com.example.data.entity.xml.ForumEntityXml attribute=OBJECT_FIELD["message"] payload=<script> remoteIpAddress=127.0.0.1 localIpAddress=127.0.0.1 localPort=8080
Safe Undetermined
<10>1 2021-02-19T20:09:43.593Z localhost java 19559 - - CEF:0|ARMR:ARMR|ARMR|2.7|SANITIZATION :01|Execute Rule|High|rt=Feb 19 2021 20:09:43.592 +0000 dvchost=localhost procid=19559 appVersion=1 ruleType=sanitization securityFeature=sanitization datainput msg=A payload could not be classified reason=UNDETERMINED taintSource=HTTP_SERVLET httpRequestUri=/api/forum/add/json httpRequestMethod=GET internalHttpRequestUri=/api/forum/add/json className=com.example.data.entity.ForumEntity attribute=OBJECT_FIELD["message"] payload=< > remoteIpAddress=127.0.0.1 localIpAddress=127.0.0.1 localPort=8080