Skip to main content
Version: 2.3

ARMR SQL Rule

Overview

SQL injection (SQLi) attack consists of the insertion or “injection” of a SQL query via the input data from the client to the application. The ARMR sql rule can be used to enable protection against SQL injection attacks.

SQL Injection vulnerabilities are covered by CWE-89.

Given (Conditions)

The user can specify two conditions in the ARMR sql rule - input and vendor.

inputThis allows the user to specify the source of the untrusted data. The following three sources are supported:- http data introduced via HTTP/HTTPS requests
  • database data introduced via JDBC connections

  • deserialization data introduced via Java or XML deserializationThe rule will trigger if the source of the untrusted data matches that specified in the rule.If no value is specified then a default value of http is used.An exception will be thrown if an unsupported value is provided. | | | vendor | This is an optional declaration that allows the user to specify the database type to be protected. The following databases are supported:- db2

  • mariadb

  • mssql

  • mysql

  • oracle

  • sybase

  • postgresIn addition, a value of any may be specified which will enable the agent to automatically detect the database type used by the application.One of the listed database types, or the value any, must be specified if the vendor declaration is present.If no vendor declaration is specified then a default value of any is used. | | | | options | Depending on the database configuration, the following optional parameters are also supported to allow the agent to accurately detect SQL injection attacks:- ansi-quotes - mysql and mariadb: corresponds to the ANSI_QUOTES server mode.

  • no-backslash-escapes - mysql and mariadb: corresponds to the NO_BACKSLASH_ESCAPES server mode.

  • quoted-identifiers - mssql and sybase: corresponds to the QUOTED_IDENTIFIER flag |

When (Event)

injectionThis condition allows the user to specify the type of injection:- successful-attempt the rule will trigger upon detecting a valid SQLi payload that would have resulted in a successful SQLi attack, exploiting the underlying database.
  • failed-attempt the rule will trigger upon detecting an invalid SQLi payload that would have resulted in an unsuccessful SQLi attack, which could expose the underlying database configuration or vendor.If no value is specified then a default value of successful-attempt is used.In addition, the user may optionally specify the following parameter:- permit: query-provided the rule will not trigger in the case where the entire SQL query (and not just part of it) has come from any of the untrusted sources defined in the input declaration.An exception will be thrown if an unsupported value is provided. |

Multiple sql rules are allowed in the same ARMR mod providing they have different injection types.

Then (Action)

The action statement specifies the action the agent takes whenever an attack is detected. There are two supported actions protect and detect:

protectA valid SQL injection attack is not allowed to be processed by the database.If configured, a log message is generated with details of the event.
detectMonitoring mode: the application behaves as normal. SQLi attack are allowed by the agent.If configured, a log message is generated with details of the event.A log message must be specified with this action.

In the case of protect, if no additional configuration is given, the rule will take a default action depending on which of the injection types has occurred. A specific action can be configured for this rule to send an HTTP response with a specified status code and a message as body. These configurations are further described in the table below.

successful-attemptfailed-attempt
protectA SQLException is thrown by the agent to indicate the SQL statement is invalid, letting the server handle the exception gracefully.The HTTP connection, from which the malicious data that exploited the SQL statement originated, is disconnected.
detectThe SQL injection attack is allowed to be processed by the database.The invalid SQL statement is allowed to be processed by the database.

As part of the action statement, the user may optionally specify the parameter stacktrace: “full”. When this parameter is specified, the stacktrace of the location of the attempted exploit is included in the security log entry.

Payload whitelisting can be applied using the Waratek command-line option com.waratek.AllowSQLiPayloads. The value supplied should be a comma-separated list of strings to substring-match against SQLi payloads to be whitelisted and therefore not register as an SQL injection attack. Example: com.waratek.AllowSQLiPayloads=AND,OR

Example

The following sql rule is used to protect a MySQL database from SQL injection attacks.

The input and injection conditions are satisfied when the untrusted data originates from an HTTP/HTTPS request, and the resulting SQL statement is either a valid query that will exploit the database, or an invalid query that may disclose information about the database configuration or vendor.

An action of protect is defined to ensure that the agent does not allow any malicious SQL statement to be processed by the database. A log message and severity are both specified which will be included in any generated log entries if an attack is detected.

app("SQL mod"):
requires(version: ARMR/2.3)
sql("Protect MySql database from SQL Injection attacks"):
vendor(mysql)
input(http)
injection(successful-attempt, failed-attempt)
protect(message: "SQL injection attack detected and blocked", severity: High)
endsql
endapp

Logging

When the sql rule is triggered a log entry similar to the following is generated:

<10>1 2021-03-30T17:33:55.538+01:00 userX_system java 32008 - - CEF:0|ARMR:SQL mod|SQL mod|2.3|Protect MySql database from SQL Injection attacks|Execute Rule|High|rt=Mar 30 2021 17:33:55.537 +0100 dvchost=userX_system procid=32008 appVersion=1 act=protect msg=SQL injection attack detected and blocked databaseVendor=mysql httpSessionId=3153E581A645E2A54D3C12D3928473BC taintSource=HTTP_SERVLET httpRequestUri=/spiracle/Get_int httpCookies=JSESSIONID\=3153E581A645E2A54D3C12D3928473BC remoteIpAddress=0:0:0:0:0:0:0:1

Further Examples

The following mod is the same as the previous example, with the stacktrace also logged:

app("SQL mod - with stacktrace"):
requires(version: ARMR/2.3)
sql("Protect MySql database from SQL Injection attacks"):
vendor(mysql)
input(http)
injection(successful-attempt, failed-attempt)
protect(message: "SQL injection attack detected and blocked", severity: High, stacktrace: "full")
endsql
endapp

Logging

When the above ARMR sql rule is triggered a log entry similar to the following is generated:

<10>1 2021-04-01T11:30:25.075+01:00 userX_system java 25024 - - CEF:0|ARMR:SQL mod - with stacktrace|SQL mod - with stacktrace|2.3|Protect MySql database from SQL Injection attacks|Execute Rule|High|rt=Apr 01 2021 11:30:25.073 +0100 dvchost=userX_system procid=25024 appVersion=1 act=protect msg=SQL injection attack detected and blocked stacktrace=com.waratek.spiracle.sql.util.SelectUtil.executeQuery(SelectUtil.java:67)\ncom.waratek.spiracle.sql.servlet.oracle.Get_int.executeRequest(Get_int.java:77)\ncom.waratek.spiracle.sql.servlet.oracle.Get_int.doGet(Get_int.java:52)\njavax.servlet.http.HttpServlet.service(HttpServlet.java:624)\njavax.servlet.http.HttpServlet.service(HttpServlet.java:731)\nsun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\nsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\nsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\njava.lang.reflect.Method.invoke(Method.java:498)\norg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)\norg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)\norg.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)\nsun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\nsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\nsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\njava.lang.reflect.Method.invoke(Method.java:498)\norg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)\norg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)\norg.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)\norg.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)\norg.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)\norg.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)\norg.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)\norg.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)\norg.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)\norg.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442)\norg.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1082)\norg.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:623)\norg.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)\njava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\njava.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\norg.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\njava.lang.Thread.run(Thread.java:748) databaseVendor=mysql httpSessionId=Unknown taintSource=HTTP_SERVLET httpRequestUri=/spiracle/Get_int httpCookies= remoteIpAddress=0:0:0:0:0:0:0:1

The following mod enables the agent to automatically detect the database type in use by the application. The mod protects against valid SQL injection attacks that originate from an HTTP/HTTPS request.

app("SQL mod 2"):
requires(version: ARMR/2.2)
sql("Protect database from successful SQL Injection attacks"):
vendor(any)
input(http)
injection(successful-attempt)
protect(message: "SQL injection attack detected and blocked", severity: Very-High)
endsql
endapp

The following mod monitors a MSSQL database, detecting valid SQL injection attacks that originate from a JDBC connection.

app("SQL mod 3"):
requires(version: ARMR/2.2)
sql("Protect MSSQL database from successful stored SQL Injection attacks"):
vendor(mssql)
input(database)
injection(successful-attempt)
detect(message: "SQL injection attack detected", severity: 5)
endsql
endapp

The following mod protects an Oracle database against valid SQL injection attacks that originate from an HTTP /HTTPS request. If the entire SQL query has originated from an HTTP/HTTPS request then the mod will let it through to the database.

app("SQL mod 4"):
requires(version: ARMR/2.2)
sql("Protect Oracle database from successful SQL Injection attacks"):
vendor(oracle)
input(http)
injection(successful-attempt, permit: query-provided)
protect(message: "SQL injection attack detected and blocked", severity: 8)
endsql
endapp

The following mod does not specify the vendor declaration, enabling, by default, the agent to automatically detect the database type in use by the application. The mod protects against invalid attempts at SQL injection that originate from various untrusted sources. Logging is switched off by the omission of the log message parameter.

app("SQL mod 5"):
requires(version: ARMR/2.2)
sql("Protect database from unsuccessful SQL Injection attacks from various sources"):
input(http, database, deserialization)
injection(failed-attempt)
protect()
endsql
endapp