To protect against injection vulnerabilities, the software developer has several means at his disposal. In order to get accurate analysis results, the AIA needs to discover if any of these mechanisms have been used in the application, and how to configure AIP to take them into account, when required.
- Collect usage of protection mecanism(s) used by ACME organization, in an interview.
- usage of presentation layer validator, standard or custom
- the names of the sanitization vetted libraries, standard or custom
- for SQL injection prevention, usage of parameter binding, aka SQL Bind Variables/Parameters
- If the collection of information is not possible or incomplete upfront, the AIA must use his knowledge to detect the presence of the mechanism(s) in the source code itself and/or in the SecurityAnalyzer.log.
- Presence of JAR or assemblies could be a first sign
- Dependency inside Maven pom.xml is a better sign
- Presence of a protection mechanism is not a proof the application is 100% covered.
The default configuration will cover 90% of the cases for public sanitization library (with AIP >= 8.3.15). Then, once flaws are found and validation or any interview / observation reveals some specific configuration should be done, add a custom blackbox file to define the specific methods as sanitization (mode=clear). Then the invalid violations (protected by a sanitization method) will be removed from list of violations, and the remaining violations are deemed true positives.
Sanitization methods general information
This part should be configured at the end of the on-boarding process, in order to ensure no other road block will stop the engine during graph exploration. Therefore, it must be configured after a first pass with at least one violation (or at least a flaw reported in SecurityAnalyzer.log), then use the configuration to remove this violation.
However, some specific validation technics cannot be taken into account automatically. You will have to live with them, and just document the reason why the violation paths including them are harmless. "Sanitization" is sometime also referred to as "neutralization" or "cleansing". It removes the unwanted characters from a tainted input. Whereas the validator rejects user input.
Sanitization limitations in AIP
The User Input Security engine does not recognize logical test as a valid sanitization but it does not stop the flow (for our engine):
nor this one :
Please note that only sanitization methods that modify the string (cleaners) are supported. Verification methods which test the string (checkers, i.e "if(verifyString(x))" ) are not supported and no sanitization method can be declared for these kind of methods
Check for sanitization strategy
As a rule of thumb - as a front-end developer, you should validate or sanitize user input at the earliest opportunity (in the presentation layer), except for SQL injection prevention, where sanitization with parameter binding is recommended, and it will take place just before the SQL execute API.
a.Custom taglib (JSTL)
b.Check each string entry for its target format (regexp), and move it from String to target data type ASAP (date, structure, …)
c.Custom filter sample : com.acme.view.common.MyController.cleanXSS(java.lang.String)
Use the presentation layer's validation framework
- Struts Validator
- JSF Validator
- Apache Wicket Validator
- Spring MVC Form Validator or filter
For SQL injection prevention, parameter binding
Prepared Statement CallableStatement, JDBC, JPA as well as ADO.NET allow usage of bind variables that prevent the attacker from modifying the intent of the query. See OWASP SQL Injection Prevention Cheat Sheet - Defense Option 1: Prepared Statements (with Parameterized Queries). Here the strategy for a user Input Security analysis configuration is as follows:
- Define the SQL method (execute Query) as Target-SQL : start a search from the bottom.
- Define the variable binding (setString, setXYZ, setParameter, ...) as sanitization for SQL injection : stops the flow.
- In addition, "The JDBC driver will escape this data appropriately before the query is executed; making sure that data is used just as data" (See How to How to Fix SQL Injection using the Java Persistence API (JPA))
Sample with JDBC
Sets the designated parameter to the given Java String value. Many other methods exist : setBoolean, setDouble, setDate, setInt, SetLong etc. and they are all considered as valid protection against injection.
Sample with Springframework JdbcTemplate
JdbcTemplate provides a number of methods performing parameter binding:
- 15 signatures of query(...)
- 7 signatures of queryForList(...)
- 6 signatures of queryForMap(...)
- 6 signatures of queryForObject(...)
- 2 signatures of queryForRowSet(...)
Comparison of vulnerable code versus protected code with different mangling (sample from FindSecBugs):
Sample with JPA
Named Parameters in Queries
Named parameters are query parameters that are prefixed with a colon (:). Named parameters in a query are bound to an argument by the following method:
Positional Parameters in Queries
You can use positional parameters instead of named parameters in queries. Positional parameters are prefixed with a question mark (?) followed by the numeric position of the parameter in the query. The javax.persistence.Query.setParameter(integer position, Object value) method is used to set the parameter values.
Samples with Spring Data JPA
Spring Data JPA with Query Methods
Derived queries with the predicates IsStartingWith, StartingWith, StartsWith, IsEndingWith, EndingWith, EndsWith, IsNotContaining, NotContaining, NotContains, IsContaining, Containing, Contains the respective arguments for these queries will get sanitized. This means if the arguments actually contain characters recognized by LIKE as wildcards these will get escaped so they match only as literals. The escape character used can be configured by setting the escapeCharacter of the @EnableJpaRepositories annotation.
Spring Data JPA with Named Parameters
JPA supports either position-based parameter binding or named parameter with @Param annotation. @Param works with both @Query and @NamedQuery (reference https://www.logicbig.com/tutorials/spring-framework/spring-data/query-named-parameters.html):
Sample with Hibernate
Similarly to JPA, Hibernate makes provision of parameter binding method for the Query class:
Named Parameters in Queries
Positional Parameters in Queries
There are also several methods such as setParameterList() to bind multiple values to a named query parameter, and one setParameters() to bind values and types to positional parameters.
Sample with mySQL
Similarly to PreparedStatement, JPA, Hibernate and mySQL fluent API for Java makes provision of parameter binding methods for the Statement interface of X DevAPI (com.mysql.cj.xdevapi.Statement):
- Collection interface: Representation of a document collection. This interface allows access to and manipulation of the collection through add/find/modify/remove statements.
- Statement (all known sub-interfaces): AddStatement, DeleteStatement, FindStatement, InsertStatement, ModifyStatement, RemoveStatement, SelectStatement, SqlStatement, UpdateStatement - a statement is a query or state-affecting command against a database that returns a result.
Sample with ADO.NET
Parametrized queries prevents from SQL injection.
See complete article at How to Fix SQL Injection Using Microsoft .Net Parameterized Queries.
Using LINQ to SQL or LINQ to Dataset
Using these modern .NET Entity frameworks ensure the parameters are binded, and thus prevent from SQL injection...to a limited extented according to Fortify.
- LINQ Prevent SQL Injection
- Fortify : SQL Injection: LINQ
- Roslyn Security Guard - Potential SQL injection with LINQ API
- LINQ queries are not susceptible to SQL injection attacks in the traditional sense
- Or choose a common sanitization library, see below for a list of the librariess encountered at our customers (direct usage, or with a wrapper to fix any gap in the checks):
Common sanitization libraries encountered in JEE and .NET analyses
|jar file name (sample)||Sanitization library / framework||Support in AIP||Comments - Sample - Known Limitations|
20 apps using org.owasp.esapi
method encodeForHTML also included in sanitization.blackbox.xml (for OWASP Benchmark analysis)
2 apps usig org.owasp.encoder
(high-performance encoding for XSS prevention)
If your application handles markup -- untrusted input that is supposed to contain HTML -- it can be very difficult to validate. Encoding is also difficult, since it would break all the tags that are supposed to be in the input. Therefore, you need a library that can parse and clean HTML formatted text.
import org.owasp.html.Sanitizers; import org.owasp.html.PolicyFactory; PolicyFactory sanitizer = Sanitizers.FORMATTING.and(Sanitizers.BLOCKS); String cleanResults = sanitizer.sanitize("<p>Hello, <b>World!</b>");
Apache Commons Lang StringEscapeUtils
Apache Commons Text StringEscapeUtils
org.apache.commons.lang3.StringEscapeUtils is Deprecated.
Escapes and unescapes
method [commons-lang-2.6]org.apache.commons.lang.StringEscapeUtils.escapeHtml(ref [rt]java.lang.String) also included in sanitization.blackbox.xml (for OWASP Benchmark analysis)
|Spring Web HtmlUtils org.springframework.web.util.HtmlUtils.htmlEscape()|
Utility class for HTML escaping. Escapes and unescapes based on the W3C HTML 4.01 recommendation, handling character entity references.
method htmlEscape also included in sanitization.blackbox.xml (for OWASP Benchmark analysis)
now in System.Web.dll since .NET framework 4.5
|Microsoft Anti-XSS library|
Preventing Cross-site scripting attacks using Microsoft Anti-Cross Site Scripting Library V3.0 (Anti-XSS V3.0)!
Predefined in standard configuration file : 8.3.6\configuration\DataflowSecurity\DotNet\FlawSpec_DotNet.xml
Sibling methods Microsoft.Security.Application.Encoder.HtmlEncode and Microsoft.Security.Application.Encoder.UrlEncode are defined starting with AIP 8.3.7.
Missing namespace / class : [HtmlSanitizationLibrary]Microsoft.Security.Application.Sanitizer.GetSafeHtmlFragment([mscorlib]System.String)
|Microsoft ASP .NET 4.5 dynamic encoding|
HTML encode binding shortcut (<%#:) . Note the ':' after the '<%'.
see sample at Developer guide XSS
For ASP.NET Core see https://docs.microsoft.com/en-us/aspnet/core/security/cross-site-scripting#accessing-encoders-in-code : use the default encoders contained in the
Microsoft ASP.NET Built-in Features to Fend Off Web Attacks
ValidateRequest function that provides limited sanitization.
ValidateRequest attribute on the @Page directive, is on by default.
<%@ Page ValidateRequest="false" %> is a violation (turned off)
HtmlSanitizer is a .NET library for cleaning HTML fragments and documents from constructs that can lead to XSS attacks.
a library for HTML and CSS encoding.
For ensuring user-supplied HTML/CSS is in compliance within an application's rules.
jsoup: Java HTML Parser
jsoup is a Java library for working with real-world HTML.
<div >UNTRUSTED HTML</div > Defense:
CSRF not managed by Dataflow analyzer, but worth to be mentionned in this paragraph.
Other useful reading on sanitization and validation techniques
- Is OWASP ESAPI still the recommended way to secure JSP pages? (provides alternatives to ESAPI)
- Custom Annotation in Java for SQL Injection Safe Parameters
- Sanitizing user inputs with Spring MVC framework (Stackoverflow)
- Check List for Spring Security Implementation: Watch your foes
- Spring Validation Example – Spring MVC Form Validator
Validation methods configuration in AIP
Validation mecanism can hardly be configured in Dataflow configuration today (when the corresponding framework is not supported, the validators are neither).
This is not a big issue : you just have to perform the rest of the configuration, find flaws, and once they are found, filter out manually the ones that are protected by a trusted validator.
This filtering could be further automated as a custom, since QR detail procedures are accessible.
Sanitization methods configuration in AIP
Sanitisation methods can be configured in AIP since first generation of dataflow (6.4 / 7.0).
A defined sanitization method will stop the flow, so no flaw will be found with a defined sanitization in its flow path..
Please note, the DataflowRunner on-the-fly blackboxing does not generate any sanitization decision (to avoid any false negative by abusive decision).
The means to configure/define sanitization methods are multiple:
Standard sanitization through Flawspec XML files (up to AIP 8.3.14)
A standard configuration is delivered, thanks to 2 configuration files, located in AIP subfolders DotNet and J2EE of \configuration\DataflowSecurity.
The current configuration is not documented in DOC83, so it is worth reading to see what CAST considers as valid sanitization, and what is missing for your application.
Also, some methods of rt.jar and mscorlib.dll are declared as "clear" in the standard predefined methods : these are mostly .close() and .flush() for certain OutputStream classes.
Standard sanitization through Predefined Methods (from AIP 8.3.15)
A total redesign has been done in AIP 8.3.15:
- more precise definitions: a sanitization method stops the flow for only a set of flaw searches, not for all.
- more standard libraries supported; out-of-the-box accurate results
- high-level documentation (supported libraries) is available for all in User Input Security - predefined methods
Custom sanitization through custom blackbox files (generic sanitization)
Since 8.3.3, this configuration can be made specific to the search (XSS, HTTP Response Splitting, Log Forging, ...) to avoid for instance encodeForSQL() stopping a flaw for XSS injection. (since encodeForSQL does characters neutralization for...SQL, so not valid for XSS). Also, some flaws (OS Command injection and others) do not have vetted sanitization methods : it is not a matter of annoying characters: you don't want any user input flying to the command, so no dynamic content here.
Dataflow SME kit provides sample sanitization blackbox files in folder 6. Blackbox for JEE . Some have been promoted in standard configuration in 8.3.3+, 8.3.15, and above :
- OWASP.Java Encoder_V01.01.blackbox.xml ; still awaited in AIP.
Sample snippet from typical custom sanitization blackbox
This snippet reads as follows:
- Define escapeHtml4(java.lang.String) method of class org.apache.commons.lang3.StringEscapeUtils as a vetted sanitization.
- Whenever a tainted input comes into object intance (self = sink="0" ),
- as first parameter : (java.lang.String) as source="1" ,
- then stop the flow : mode="clear"
- The flow being stopped, whenever the engine encounters this method in a graph exploration, it stops the current search, and goes to the next one.
How to define your own blackbox file
Take the above snippet as a sample, and just replace the class and method name by yours. The flow tags are unchanged, they are always the same for sanitization method taking one parameter.
Custom sanitization through custom blackbox files (specific sanitization per QR)
Same as above, but you copy the .blackbox.xml file in a folder structure that will tell which specific flaw search you want to stop. That way, a method like encodeForSQL will stop only the searches originating from SQL targets, and won't affect XSS, File Path manipulation or the other searches. Location of the specific blackbox file :
where QRId can be any of the 8 following rules:
|QR7740||CWE-79: Avoid cross-site scripting DOM vulnerabilities|
CWE-89: Avoid SQL injection vulnerabilities
|QR7746||CWE-90: Avoid LDAP injection vulnerabilities|
|QR7748||CWE-78: Avoid OS command injection vulnerabilities|
|QR7750||CWE-91: Avoid XPath injection vulnerabilities|
|QR7752||CWE-73: Avoid file path manipulation vulnerabilities|
|QR8044||CWE-117: Avoid Log forging vulnerabilities|
|QR8098||CWE-134: Avoid uncontrolled format string|