Skip to main content

Pattern Examples

Source/Passthrough Pattern Examples

The following passthrough pattern defines that, when calling any method of org.apache.commons.httpclient.util.URIUtil class with one or more parameters with a name beginning with encode, all flags of a null argument must be assigned and a URL_ENCODE flag must be added to a returned value:

<Rule>
<RuleId>SOURCE_00AF03C6</RuleId>
<Patterns>
<Pattern patternId="75b459">
<Categories>
<Category>JavaWeb</Category>
</Categories>
<Definitions>
<Class id="class">
<Supers includeSelf="true">
<Class>
<Name>
<Value>org.apache.commons.httpclient.util.URIUtil</Value>
</Name>
</Class>
</Supers>
<Method id="method">
<Name>
<Regex>encode.*</Regex>
</Name>
<Parameters>
<WildCard min="1" />
</Parameters>
</Method>
</Class>
<Instruction id="target_invoke">
<Class>
<Ref id="class" reftype="classref" />
</Class>
<Method>
<Ref id="method" reftype="methodref" />
</Method>
<Arguments>
<Argument id="arg0">
<Pos>0</Pos>
</Argument>
</Arguments>
</Instruction>
</Definitions>
<Condition>
<InstructionCondition>
<Ref id="target_invoke" reftype="instructionref" />
</InstructionCondition>
</Condition>
<ChangeFlags>
<FlagsSet>
<To>
<Argument>
<Return />
</Argument>
</To>
<From>
<Argument>
<Ref id="arg0" reftype="argumentref" />
</Argument>
</From>
<FlagsDiff>+URL_ENCODE</FlagsDiff>
</FlagsSet>
</ChangeFlags>
</Pattern>
</Patterns>
</Rule>

Source patterns are written in the same manner and only differ from passthrough patterns by the absence of From element from the Flagset.

Sink pattern example

The following sink pattern defines that calling a dangerousMethod method of org.example.DangerousClass class with a null int parameter and one or several additional parameters is insecure, if the first parameter has a TAINTED flag:

<Rule>
<RuleId>TEST_RULE</RuleId>
<Patterns>
<Pattern patternId="123abc">
<Categories>
<Category>JavaWeb</Category>
</Categories>
<Severity>1</Severity>
<Definitions>
<Class id="class">
<Supers includeSelf="true">
<Class>
<Name>
<Value>org.example.DangerousClass</Value>
</Name>
</Class>
</Supers>
<Method id="method">
<Name>
<Regex>dangerousMethod</Regex>
</Name>
<Parameters>
<Parameter>
<Type>int</Type>
</Parameter>
<WildCard min="1" />
</Parameters>
</Method>
</Class>
<Instruction id="target_invoke">
<Class>
<Ref id="class" reftype="classref" />
</Class>
<Method>
<Ref id="method" reftype="methodref" />
</Method>
<Arguments>
<Argument>
<Pos>1</Pos>
<Flags>
<Flag>TAINTED</Flag>
</Flags>
</Argument>
</Arguments>
</Instruction>
</Definitions>
<Condition>
<InstructionCondition>
<Ref id="target_invoke" reftype="instructionref" />
</InstructionCondition>
</Condition>
<ReportValues>
<ReportValue key="bad_instruction">
<Ref id="target_invoke" reftype="instructionref" />
</ReportValue>
</ReportValues>
</Pattern>
</Patterns>
</Rule>

Writing a Pattern for C# and PHP

Structure of source/passthrough pattern for C# and PHP:

<Pattern>
<Categories>
<Category>LANG</Category>
</Categories>
<XPath>self::node[] </XPath>
<Instruction>node </Instruction>
<ChangeFlags>
<FlagSet>

</FlagSet>
</ChangeFlags>
</Pattern>

The value of a LANG text field is the respective language for which the pattern is written, i.e. CS or PHP.

XPath element defines a call of a specified method of a specified class with specified arguments. The value of an XPath element is an XPath query beginning with a self axis with subsequent element:

  • For C#: member_access2 or primary_expression_start (depending on whether a class method or constructor is the key element).
  • For PHP: memberAccess or functionCall (depending on whether a class method or constructor is the key element).

Instruction element has the following value:

  • For C#: member_access2 or primary_expression_start (depending on which element XPath query starts with).
  • For PHP: memberAccess or functionCall (depending on which element XPath query starts with).

ChangeFlags element contains one or more FlagsSet. Each FlagsSet element shows how flags must be changed for a specified set of entities (arguments).

FlagsSet element contains the following elements: To, From, FlagsDiff and optional clearAll, attribute that may be either true or false.

To and From elements define entities that are involved in flag changing. The following entities can be flagged: Argument, Range.

Argument element defines a condition for one actual argument and contains a pos attribute (positions numbering starts from 0).

The Range element contains PosMin and PosMax attributes and defines a group of consecutive arguments starting from the PosMin index and ending with (inclusive) the PosMax index (index numbering starts from 0).

The FlagsDiff element contains a string specifying a flag change. The change type is specified as a diff attribute that may have one of the following values:

  • add: add FLAG
  • remove: remove FLAG if it exists
  • inverse: change value of FLAG if it exists

Structure of sink pattern for C# and PHP:

<Pattern>
<XPath>//node</XPath>
</Pattern>

Writing Patterns for Other Languages

To analyze languages that cannot be compiled into Java bytecode, an intermediate AST representation is used. In this case, search patterns are defined in terms of Xpath queries to this representation.

General structure of Xpath-based XML pattern:

<Pattern>
<XPath>//node</XPath>
</Pattern>

Different languages are translated to intermediate representation differently. This is why XPath queries for different source languages have different structures. Examples of XPath queries for supported languages are provided below (editable parameters are highlighted in bold font).

Writing Pattern for JavaScript

Call of testMethod method of testClass class with an integer constant less than 128 as the first argument:

//singleExpression[
singleExpression[singleExpression/text()='testClass']
[identifierName/text()='testMethod']
][
arguments/argumentList[
singleExpression[1]/literal/numericLiteral[number(text()) < 128]
]
]

Writing Pattern for LotusScript

Call of testMethod method of testClass class:

//iCS_B_MemberProcedureCall[
implicitCallStmt_InStmt/
iCS_S_VariableOrProcedureCall/
ambiguousIdentifier[text()[1] = 'TestClass']
][
ambiguousIdentifier/
ambiguousKeyword[text()[1] = 'TestMethod']
]

Writing Pattern for TypeScript

Call of testFunction function with a constant argument that satisfies the regular expression:

//callExpression[
memberExpression/identifierName[text()[1] = 'testFunction']
][
arguments//literal[matches(text()[1], '.*val.*', 'i')]
]

Writing Pattern for VBScript

Call of TestMethod method of TestClass class with a constant string as the third argument:

//iCS_B_MemberProcedureCall[
implicitCallStmt_InStmt//
ambiguousIdentifier[
matches(@class, '^TestClass$', 'i')
]
][
ambiguousIdentifier/
ambiguousKeyword/text()[1] = 'TestMethod'
][
argsCall/argCall[3]//
literal[text()[1]]
]

Writing Pattern for Python

Call of test_method method of TestClass class with a string-type argument with length of less than 16 characters:

//power[
atom[1]/text()[1] = 'TestClass'
][
trailer[1]/text()[1] = 'test_method'
][
trailer[2]/arglist/argument//
arith_expr/term/factor/power/atom/string[
string-length(text()[1])&lt;16
]
]

Writing Pattern for Perl

Call of insecure_operator() method with two arguments:

//listOperatorCall[
listOperatorName[text()[1] = 'insecure_operator']
][
list/operators[
operator[1]
][
operator[2]
][
not(operator[3])
]
]

Writing Pattern for Objective-C and C

Call of TEST_FUNC1 or TEST_FUNC2 function:

//CallExpr[
./*[1]//FunctionDecl[
@name = 'TEST_FUNC1' or @name = 'TEST_FUNC2'
]
]

Writing Pattern for C++

Call of “bad_function” function:

<Patterns>
<Pattern id="kjdfbgv132">
<Condition>
<callExpr>
<callee>
<functionDecl>
<hasName id="bad_function"/>
</functionDecl>
</callee>
</callExpr>
</Condition>
<Action>
<Report id="bad_function" severity="1" confidence="5"/>
</Action>
</Pattern>
</Patterns>

Writing Pattern for PL/SQL

Call of test_proc procedure of test_class class with a constant argument:

//function_call[
routine_name[
./id/id_expression/regular_id[
matches(text(), '^test_class$', 'i')
]
][
./id_expression/regular_id[
matches(text(), '^test_proc$', 'i')
]
]
][
function_argument[
.//constant
]
]

Writing Pattern for Rust

Hardcoded my_variable variable:

//let[
assignee/pattern//identifier[
matches(text(), 'my_variable')
]
][
initialization/expression[
count(*) = 1 and literal[text()[1]]
]
]

Writing Pattern for T-SQL

Call of TESTFUNC function with the following constant string argument: TEST_STRING_CONSTANT:

//function_call[
scalar_function_name/func_proc_name/
id/simple_id[
matches(text()[1], '^TESTFUNC$', 'i')
]
][
expression_list/expression[1]/
constant[
matches(text()[1], '^TEST_STRING_CONSTANT$', 'i')
]
]

Writing Pattern for ABAP

Call of test_func function:

//statement/
callStatement/
call_method_static_short/
methodId1/
methodId[1]/
anySingleToken[
matches(text()[1], 'test_func', 'i')
]

Writing Pattern for Apex

Call a constructor with the fifth argument's value equal to bad_value:

//statement/callStatement/call_method_static_short/
methodId1/methodId[1]/
anySingleToken[
matches(text()[1], 'test_func', 'i')
]

Writing Pattern for Go

Call of testFunc function:

//primaryExpr[
primaryExpr/operand/operandName[
matches(text()[1], '^testFunc$', 'i')
]
]

Writing Pattern for Ruby

Call of test_method method with an integer argument:

//function_call[
function_name[1]/id/text()[1] = 'test_method'
][
function_call_param_list[1]/
function_call_params/
function_param/
function_unnamed_param/
int_result/
int_t
]

Writing Pattern for Groovy

Call of testMethod method:

//expression[
callExpressionRule[
selectorName/IDENTIFIER[
matches(text()[1], '^testMethod$', 'i')
]
]
]

Writing Pattern for Dart

Call of TestMethod method of TestClass class:

//postfixExpression[
primary/identifier/identifierNotFUNCTION[
text()[1] = 'testClass'
]
][
selector/assignableSelector/unconditionalAssignableSelector/
identifier/identifierNotFUNCTION[
text()[1] = 'testMethod'
]
]

Writing Pattern for Delphi

Call of test_func function:

//statement[.//designator//ident[matches(text()[1], '^test_func$')]] [ .//expression//factor[(intNum|stringFactor[string-length(text()[1]) > 0])]]

Writing Pattern for Pascal

Call of test_func function:

//methodOrFunctionId/extendedIdentifier/identifier/ident[
matches(text()[1], '^test_func$', 'i')
]

Writing Pattern for HTML5

Attribute attribute with value bad_value:

//htmlElement[
htmlAttribute[
htmlAttributeName[matches(text()[1], 'attribute', 'i')]
]
[
htmlAttributeValue[matches(text()[1], 'bad_value', 'i')]
]
]

Writing Pattern for VB.NET

Call of TestMethod method of TestClass class with a constant string as the third argument:

//iCS_B_MemberProcedureCall[
implicitCallStmt_InStmt//
ambiguousIdentifier[matches(@class, '^TestClass$', 'i')]
][
ambiguousIdentifier/
ambiguousKeyword/text()[1] = 'TestMethod'
][
argsCall/
argCall[3]//
literal[text()[1]]
]

Writing Pattern for VBA

Call of the TestFunction function with a hardcoded string as an argument:

//iCS_S_VariableOrProcedureCall[
ambiguousIdentifier[matches(text()[1], '^TestFunction$', 'i')]
][
subscripts/subscript[1]/
ambiguousIdentifier/literal
]

Writing Pattern for Visual Basic 6.0

Call of TestMethod method of TestClass class with a constant string as the third argument:

//iCS_B_MemberProcedureCall[
implicitCallStmt_InStmt//
ambiguousIdentifier[matches(@class, '^TestClass$', 'i')]
][
ambiguousIdentifier/
ambiguousKeyword/text()[1] = 'TestMethod'
][
argsCall/
argCall[3]//literal[text()[1]]
]

Writing Pattern for Solidity

Call of testfunc function:

//functionName/identifier[
matches(text()[1], '^testfunc$', 'i')
]

Writing Pattern for Vyper

Call of insecure_function() function:

//atom_name[
text()[1] = 'insecure_function'
]

Writing Pattern for COBOL

Hardcoded sensitiveData variable:

//moveToStatement[
moveToSendingArea/literal
]/identifier

//cobolWord[
matches(text()[1], '^sensitiveData$', 'i')
]