Introduction

Objectives

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 Core to take them into account, when required.

  1. Collect usage of protection mecanism(s) used by ACME organization, in an interview.
    1. usage of presentation layer validator, standard or custom
    2. the names of the sanitization vetted libraries, standard or custom
    3. for SQL injection prevention, usage of parameter binding, aka SQL Bind Variables/Parameters
  2. 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.
    1. Presence of JAR or assemblies could be a first sign
    2. Dependency inside Maven pom.xml is a better sign
    3. Presence of a protection mechanism is not a proof the application is 100% covered.  

Methodology presentation

The default configuration will cover 90% of the cases for public sanitization library (with AIP Core >= 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 Core

The User Input Security engine does not recognize logical test as a valid sanitization but it does not stop the flow (for our engine):

if(filePathName.contains("./"))        // checking for ./covers both ./ and ../              
   {                  
     throw new HNRuntimeException("Directory Traversal Attempt :: " + filePathName);              
}

nor this one :

Private Sub navigateToPreviousPage()
 
    ValidateControls()
    If Page.IsValid Then
        updateAppoints()
        updateCampaign()
    Response.Redirect(PageNavigation.GetPreviousPage(PageName))
    End If
End Sub

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.

Custom validator

     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

Samples:

  • Struts Validator
  • JSF Validator
  • Apache Wicket Validator
  • Spring MVC Form Validator or filter

Also, XSS can be prevented in JSP by using JSTL<c:out> tag or fn:escapeXml() EL function when (re)displaying user-controlled input. See XSS prevention in JSP/Servlet web application.

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

java.sql.PreparedStatement.setString(int parameterIndex, String x)

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.

java.sql.CallableStatement

has similar methods, with named parameters: setString(String parameterName, String x)

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(...)

See https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html

public String findCustomerNameById(int custId){
	String sql = "SELECT NAME FROM CUSTOMER WHERE CUST_ID = ?";
	String name = (String)getJdbcTemplate().queryForObject(              // Query given SQL to create a prepared statement from SQL and an argument to bind to the query, expecting a result object.
			sql, new Object[] { custId }, String.class);
	return name;
}

Comparison of vulnerable code versus protected code with different mangling (sample from FindSecBugs):

JdbcTemplate jdbc = new JdbcTemplate();

// Vulnerable Code:   queryForObject(String sql, Class<T> requiredType) : the concatenation makes the difference : VULNERABLE
int count = jdbc.queryForObject("select count(*) from Users where name = '"+paramName+"'", Integer.class);

// Protected Code:    queryForObject(String sql, Class<T> requiredType, Object... args)   : the extra parameter for binding makes the difference : PROTECTED
int count = jdbc.queryForObject("select count(*) from Users where name = ?", Integer.class, paramName);

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:

javax.persistence.Query.setParameter(String name, Object value)
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

See https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.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

See https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.named-parameters.

Other patterns

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):

package com.logicbig.example;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface EmployeeRepository extends CrudRepository<Employee, Long> {
@Query("SELECT e FROM Employee e WHERE e.dept = :dept AND "
+ "(SELECT COUNT(DISTINCT e2.salary) FROM Employee e2 "
+ "WHERE e.salary < e2.salary AND e2.dept = :dept) < :topSalNum "
+ "ORDER BY e.salary DESC")
List<Employee> findByDeptTopNSalaries(@Param("topSalNum") long topSalaryNum, @Param("dept") String dept);
}

Sample with Hibernate

Similarly to JPA, Hibernate makes provision of parameter binding method for the Query class:

Named Parameters in Queries
org.hibernate.Query.setParameter(String name, Object value)
Positional Parameters in Queries
org.hibernate.Query.setParameter(integer position, Object value)

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):

See https://dev.mysql.com/doc/x-devapi-userguide/en/parameter-binding.html and MySQL Connector/J X DevAPI Reference.


// Using the .bind() function to bind parameters :
DocResult myRes2 = myColl.find("name = :param1 AND age = :param2").bind("param1","jack").bind("param2",17).execute();


Sample with ADO.NET

Parametrized queries prevents from SQL injection.

How to Fix SQL Injection Using Microsoft .Net Parameterized Queries
// Build the query statement using parameterized query.
string sql = "SELECT UserId FROM User WHERE " +
                "UserName = @UserName AND Password = @Password";
  
using (SqlCommand cmd = new SqlCommand(sql))
  
{
    // Create the parameter objects as specific as possible.
    cmd.Parameters.Add("@UserName", System.Data.SqlDbType.NVarChar, 50);
    cmd.Parameters.Add("@Password", System.Data.SqlDbType.NVarChar, 25);
  
    // Add the parameter values.  Validation should have already happened.
    cmd.Parameters["@UserName"].Value = UserName;
    cmd.Parameters["@Password"].Value = Password;
    cmd.Connection = connnection;
  
    try
    {
        cmd.Connection.Open();
        var userId = cmd.ExecuteScalar();
    }
    catch (SqlException sx)
    {
        // Handle exceptions before moving on.
    }
}

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.

Common sanitization libraries encountered in JEE and .NET analyses

jar file name (sample)Sanitization library / frameworkSupport in AIP CoreComments - Sample - Known Limitations
owasp-esapi-java-1.1.1.jarOWASP ESAPI

(tick)

20 apps using org.owasp.esapi

method encodeForHTML also included in sanitization.blackbox.xml (for OWASP Benchmark analysis)

encoder-1.2.1.jar

encoder-jsp-1.2.1.jar

OWASP Java Encoder

(tick) since 8.3.18

2 apps usig org.owasp.encoder

(high-performance encoding for XSS prevention)

owasp-java-html-sanitizer-20190610.1.jar

OWASP Java HTML Sanitizer

See OWASP_Java_HTML_Sanitizer_Project

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>");

commons-lang3-3.6.jar

commons-text-1.1.jar

commons-text-1.7.jar

Apache Commons Lang StringEscapeUtils

Apache Commons Text StringEscapeUtils

(tick)

org.apache.commons.lang3.StringEscapeUtils is Deprecated.
as of 3.6, use commons-textStringEscapeUtils instead : org.apache.commons.text.StringEscapeUtils

Escapes and unescapes Strings for Java, Java Script, HTML and XML.

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-3.2.16.RELEASE.jar

spring-web-4.2.3.RELEASE.jar

Spring Web HtmlUtils org.springframework.web.util.HtmlUtils.htmlEscape() 

(tick) since 8.3.15

Utility class for HTML escaping. Escapes and unescapes based on the W3C HTML 4.01 recommendation, handling character entity references.

See also Stack Exchange - Preventing XSS attacks in a Spring MVC application controller

method htmlEscape also included in sanitization.blackbox.xml (for OWASP Benchmark analysis)

AntiXssLibrary.DLL

now in System.Web.dll since .NET framework 4.5

Microsoft Anti-XSS library

(tick)

Preventing Cross-site scripting attacks using Microsoft Anti-Cross Site Scripting Library V3.0 (Anti-XSS V3.0)!

.NET AntiXSS Library

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 Core 8.3.7.

See https://stackoverflow.com/questions/18185449/system-web-security-antixss-antixssencoder-vs-microsoft-security-application-ant

Missing namespace / class : [HtmlSanitizationLibrary]Microsoft.Security.Application.Sanitizer.GetSafeHtmlFragment([mscorlib]System.String)


Microsoft ASP .NET 4.5 dynamic encoding (question)

HTML encode binding shortcut (<%#:) . Note the ':' after the '<%'.

see sample at Developer guide XSS


ASP.NET 4.5

ASP.NET Core

(question)

For ASP.NET 4.5, see https://docs.microsoft.com/en-us/aspnet/whitepapers/whats-new-in-aspnet-45-and-visual-studio-2012#_Toc318097382

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 System.Text.Encodings.Web namespace.

For ASP.NET see https://docs.microsoft.com/en-us/aspnet/aspnet/overview/web-development-best-practices/what-not-to-do-in-aspnet-and-what-to-do-instead#security


Microsoft ASP.NET Built-in Features to Fend Off Web Attacks

Applies to
   Microsoft ASP.NET 1.x
   Microsoft ASP.NET 2.0
 

 (question)

 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.dllHtmlSanitizer

HtmlSanitizer is a .NET library for cleaning HTML fragments and documents from constructs that can lead to XSS attacks

 See https://github.com/mganss/HtmlSanitizer

class Ganss.XSS.HtmlSanitizer

Sanitize()and SanitizeDocument()methods  could be considered as vetted methods for XSS. 3 signatures each.





 antisamy-1.5.7.jar

OWASP AntiSamy

a library for HTML and CSS encoding.

For ensuring user-supplied HTML/CSS is in compliance within an application's rules.
It's an API that helps you make sure that clients don't supply malicious cargo code in the HTML they supply for their profile, comments, etc., that get persisted on the server. 
https://javadoc.io/doc/org.owasp.antisamy/antisamy/latest/org/owasp/validator/html/AntiSamy.html

  • org.owasp.validator.html.AntiSamy   , all the scan() methods


jsoup-1.13.1.jar

jsoup: Java HTML Parser

jsoup is a Java library for working with real-world HTML.


<div >UNTRUSTED HTML</div >   Defense:
– HTML Validation (JSoup, AntiSamy, HTML Sanitizer)

import org.jsoup.Jsoup;
import org.jsoup.helper.Validate;
https://jsoup.org/cookbook/cleaning-html/whitelist-sanitizer
csrfguard-3.0.0.jarOWASP CSRFGuardN/A

import org.owasp.csrfguard.CsrfGuard;

OWASP CSRFGuard

CSRF not managed by Dataflow analyzer, but worth to be mentionned in this paragraph.

Other useful reading on sanitization and validation techniques

Validation methods configuration in AIP Core

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 Core

Sanitisation methods can be configured in AIP Core 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 Core 8.3.14)

A standard configuration is delivered, thanks to 2 configuration files, located in AIP Core 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 Core 8.3.15)

A total redesign has been done in AIP Core 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.

See User Input Security - manually configuring blackbox methods.

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.ESAPI.blackbox.xml
  • OWASP.Java Encoder_V01.01.blackbox.xml ; still awaited in AIP Core.

Sample snippet from typical custom sanitization blackbox

Sample sanitization definition in a custom blackbox XML file
<?xml version="1.0" encoding="utf-8"?>
<BlackBox name="sample_sanitization" xmlns="http://tempuri.org/BlackBoxes.xsd">
    <Class mangling="org.apache.commons.lang3.StringEscapeUtils">
		<Methods>
			<Method signature="escapeHtml4(java.lang.String)">
				<Flow source="1" sink="0" mode="clear" />
				<Flow source="0" sink="-1" mode="assign" />
			</Method>
		</Methods>
	</Class> 
</BlackBox>

Snippet comment

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 :

%PROGRAMDATA%/CAST/CAST/<version>/QR[QRId]/

where QRId can be any of the 8 following rules: 

FolderRule name
QR7740CWE-79: Avoid cross-site scripting DOM vulnerabilities
QR7742

CWE-89: Avoid SQL injection vulnerabilities

QR7746CWE-90: Avoid LDAP injection vulnerabilities
QR7748CWE-78: Avoid OS command injection vulnerabilities
QR7750CWE-91: Avoid XPath injection vulnerabilities
QR7752CWE-73: Avoid file path manipulation vulnerabilities
QR8044CWE-117: Avoid Log forging vulnerabilities
QR8098CWE-134: Avoid uncontrolled format string