Skip to main content
Version: 2.8

Improper Input Validation Security Feature

Overview

HTTP input validation is performed to ensure only properly formed data enters the workflow in a server, preventing malformed data from persisting in the database and exploiting the weaknesses of various downstream components. Input validation should be completed as early as possible in the data flow, preferably as soon as the data is received from the external party.

Input validation vulnerabilities are covered by CWE-20.

The Input Validation security feature is enabled using the ARMR http rule, and can be used to ensure that various HTTP request components adhere to predefined, expected formats.

It is recommended that HTTP input validation is not used as the primary method of preventing attacks such as XSS and SQL Injection. However, if implemented properly, it can significantly contribute to reducing the impact of such attacks.

Given (Condition)

To enable the input validation security feature using the ARMR http rule the user specifies the request declaration.

requestThis 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 URI |

When (Event)

validateTwo separate key-value pairs are required for this declaration to switch on input validation protection. Valid values for the first key include:- parameterscookiesheadersValid values for the second key include:- is
headers* The headers key is used to enable input validation of HTTP request headers.
  • The value of the headers key defines the names of one or more HTTP request headers whose values must be validated.

  • Empty header names are not allowed. | | | parameters | - The parameters key is used to enable input validation of HTTP request parameters.

  • The value of the parameters key defines the names of one or more HTTP request parameters whose values must be validated.

  • Empty parameter names are not allowed | | | cookies | * The cookies key is used to enable input validation of HTTP request cookies.

  • The value of the cookies key defines the names of one or more HTTP request cookies whose values must be validated.

  • Empty cookie names are not allowed | | | is | - The is key indicates the values that are permitted, or the validation rules that must be adhered to, for the given validation target.

  • Possible values for the is key are:

    • integer

    • integer-positive

    • integer-unsigned

    • alphanumeric

    • sql-no-single-quotes

    • sql-no-double-quotes

    • html-no-single-quotes

    • html-no-double-quotes

    • html-attribute-unquoted

    • html-text

  • Alternatively, the user may specify a valid regular expression (according to the platform's regular expression syntax)

  • In addition, the value can be a list comprised of more than one of any of the above types |

Then (Action)

protectHTTP targets that fail validation are stripped from the request.If configured, a log message is generated with details of the event.
detectMonitoring mode: the application behaves as normal.If configured, a log message is generated with details of the HTTP request target that fails validation.A log message must be specified with this action.
allowCan be used to allow specific HTTP request targets that adhere to a particular format that is a subset of a format already covered by an ARMR http rule for the same target in protect mode.

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.

Examples

The following example shows how the user may configure the HTTP Input Validation feature to validate the HTTP request parameter “number”. The mod ensures that this value is an integer and therefore does not contain any unexpected characters. Protection is enabled for the specific page “xss.jsp”.

app("HTTP Input Validation mod"):
requires(version: ARMR/2.8)
http("HTTP single parameter validation"):
request(paths: "/spiracle/xss.jsp")
validate(parameters: ["number"], is: [integer])
protect(message: "number parameter was not an integer", severity: 5)
endhttp
endapp

Logging

A log entry similar to the following is generated when the above ARMR http rule identifies an unexpected value for the given HTTP target:

<12>1 2021-03-29T11:55:47.243+01:00 userX_system java 15891 - - CEF:0|ARMR:HTTP Input Validation mod|HTTP Input Validation mod|2.8|HTTP single parameter validation|Execute Rule|Medium|rt=Mar 29 2021 11:55:47.243 +0100 dvchost=userX_system procid=15891 appVersion=1 ruleType=http securityFeature=http input validation act=protect msg=number parameter was not an integer parameters=number validationRule=integer value=<script>alert(1)</script> httpRequestUri=/spiracle/xss.jsp internalHttpRequestUri=/spiracle/xss.jsp remoteIpAddress=0:0:0:0:0:0:0:1 httpSessionId=E654F722AAFA3BF44F0D0BD4FB91134C httpCookies=JSESSIONID\=E654F722AAFA3BF44F0D0BD4FB91134C

Further examples

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

app("HTTP Input Validation mod - with stacktrace"):
requires(version: ARMR/2.8)
http("HTTP single parameter validation"):
request(paths: "/spiracle/xss.jsp")
validate(parameters: ["number"], is: [integer])
protect(message: "number parameter was not an integer", severity: 5, stacktrace: "full")
endhttp
endapp

Logging

A log entry similar to the following is generated when the above ARMR http rule identifies an unexpected value for the given HTTP target:

<12>1 2021-03-29T11:57:06.951+01:00 userX_system java 15891 - - CEF:0|ARMR:HTTP Input Validation mod - with stacktrace|HTTP Input Validation mod - with stacktrace|2.8|HTTP single parameter validation|Execute Rule|Medium|rt=Mar 29 2021 11:57:06.951 +0100 dvchost=userX_system procid=15891 appVersion=1 ruleType=http securityFeature=http input validation act=protect msg=number parameter was not an integer stacktrace=org.apache.jsp.xss_jsp._jspService(xss_jsp.java:119)\norg.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)\njavax.servlet.http.HttpServlet.service(HttpServlet.java:731)\nsun.reflect.GeneratedMethodAccessor32.invoke(Unknown Source)\nsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\njava.lang.reflect.Method.invoke(Method.java:498)\norg.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:439)\norg.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:395)\norg.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)\njavax.servlet.http.HttpServlet.service(HttpServlet.java:731)\nsun.reflect.GeneratedMethodAccessor32.invoke(Unknown Source)\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.GeneratedMethodAccessor46.invoke(Unknown Source)\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) parameters=number validationRule=integer value=<script>alert(1)</script> httpRequestUri=/spiracle/xss.jsp internalHttpRequestUri=/spiracle/xss.jsp remoteIpAddress=0:0:0:0:0:0:0:1 httpSessionId=E654F722AAFA3BF44F0D0BD4FB91134C httpCookies=JSESSIONID\=E654F722AAFA3BF44F0D0BD4FB91134C

The following mod ensures the HTTP request cookie named “loginId” is a positive integer. This applies to the “index.jsp” page of the application only.

app("HTTP Input Validation mod 2"):
requires(version: ARMR/2.8)
http("HTTP cookie validation"):
request(paths: "/webapp/index.jsp")
validate(cookies: ["loginId"], is: [integer-positive])
protect(message: "loginId cookie was not a positive integer", severity: 5)
endhttp
endapp

The following mod ensures the HTTP request parameters “firstname” and “lastname” both adhere to the given regular expression. This applies to the “index.jsp” page of the application only.

app("HTTP Input Validation mod 3"):
requires(version: ARMR/2.8)
http("HTTP multiple parameter validation"):
request(paths: "/webapp/index.jsp")
validate(parameters: ["firstname", "lastname"], is: ["[a-z]+"])
protect(message: "unexpected characters found in name parameters", severity: 5)
endhttp
endapp

The following mod ensures the HTTP request parameter “price” is a positive integer. This applies to all HTTP endpoints.

app("HTTP Input Validation mod 4"):
requires(version: ARMR/2.8)
http("HTTP single parameter validation for all HTTP requests"):
request()
validate(parameters: ["price"], is: [integer-positive])
protect(message: "invalid value for price HTTP parameter", severity: 7)
endhttp
endapp

The following mod ensures the HTTP request cookie “name” is html that does not contain either single or double quote characters. This applies to the two pages of the application “testPageA.jsp“ and “testPageB.jsp“.

app("HTTP Input Validation mod 5"):
requires(version: ARMR/2.8)
http("HTTP single cookie with multiple validation rules"):
request(paths: ["/webapp/testPageA.jsp", "/webapp/testPageB.jsp"])
validate(cookies: ["name"], is: [html-no-single-quotes, html-no-double-quotes])
protect(message: "invalid value for name HTTP cookie", severity: High)
endhttp
endapp

The following mod ensures the HTTP request header “someHeader” is a valid html text. This applies to all HTTP endpoints.

app("HTTP Input Validation mod 6"):
requires(version: ARMR/2.8)
http("HTTP single header validation for all HTTP requests"):
request()
validate(headers: ["someHeader"], is: [html-text])
protect(message: "invalid value for someHeader HTTP request header", severity: 7)
endhttp
endapp

The following mod will detect occurrences of both of the HTTP request parameters “items” and “total” that contain either single or double-quote characters. This applies to all HTTP endpoints.

app("HTTP Input Validation mod 7"):
requires(version: ARMR/2.8)
http("Monitoring mode - multiple parameters with multiple validation rules"):
request()
validate(parameters: ["items", "total"], is: [sql-no-single-quotes, sql-no-double-quotes])
detect(message: "Invalid value for HTTP parameter", severity: 7)
endhttp
endapp

The following mod ensures the HTTP request parameter “items” is an integer. This applies to all HTTP endpoints. An empty string is given as the message parameter therefore a default log message will be generated.

app("HTTP Input Validation mod 8"):
requires(version: ARMR/2.8)
http("HTTP single parameter validation for all HTTP requests - default log message"):
request()
validate(parameters: ["items"], is: [integer])
protect(message: "", severity: 7)
endhttp
endapp

The following mod ensures the HTTP request header “someHeader” does not contain any double-quote characters. This applies to all HTTP endpoints. Logging is switched off by the omission of the log message parameter.

app("HTTP Input Validation mod 9"):
requires(version: ARMR/2.8)
http("HTTP single header validation for all HTTP requests - no log message"):
request()
validate(headers: ["someHeader"], is: [html-no-double-quotes])
protect(severity: 4)
endhttp
endapp

The following mod ensures the HTTP request parameter “number” is an integer. This applies to all HTTP endpoints in /myApplication.

app("HTTP Input Validation mod 10"):
requires(version: ARMR/2.8)
http("HTTP single parameter validation for all HTTP requests in myApplication"):
request(paths: ["/myApplication/*"])
validate(parameters: ["number"], is: [integer])
protect(message: "number parameter was not an integer", severity: 5)
endhttp
endapp

The following mod ensures the HTTP request parameter “number” is an integer. This applies to all HTTP endpoints containing /vulnerable.

app("HTTP Input Validation mod 11"):
requires(version: ARMR/2.8)
http("HTTP single parameter validation for all HTTP requests that contain vulnerable"):
request(paths: ["*/vulnerable*"])
validate(parameters: ["number"], is: [integer])
protect(message: "number parameter was not an integer", severity: 5)
endhttp
endapp