expression¶
public void doSomething() {
this.getName();
String test =
"example";
}
Anything that can be evaluated and results in a value or nothing.
Note
In most cases, searching for an expression will be too broad and it may be better to search for something more specific, such as methodcall or instanceCreation.
Contents
Generic Expression Configuration options¶
type¶
Checks the result type of the expression.
search:
expression:
type: "String"
public void doSomething() {
this.do(
"example"
);
}
See also
The examples above use shorthands, see type target for more advanced configurations
value¶
Sensei will try to determine what the value of the expression would be at runtime. This is particularly powerful when analyzing string expressions.
Sensei can determine the actual value of the string, even when a String has been built using StringBuilders, StringBuffers or by concatenation with other strings. The analysis also takes into account if the String cannot be determined at compile time. To do so, a special character will be added to the determined value.
The determined value will be compared against the string target.
search:
methodcall:
name: "log"
args:
1: # configured using the expression target
value:
contains: "bank account"
public void doSomething(String banknumber) {
StringBuilder builder = new StringBuilder();
builder.append("User with bank account ");
builder.append(banknumber);
builder.append(" has logged in");
this.log(builder.toString());
}
Note
This example uses an advanced configuration for the value option.
integerValue¶
When the expression results as an integer value, this can be used to search for specific values. The value will be checked using the integer target.
containsUntrustedInput¶
This will invoke the same analysis that has to be performed for the value
option. Afterward, it will
check if this determined value contains untrusted input. Sensei considers everything that cannot be
determined at compile time as untrusted. These include mutable fields, parameters, and other non-constant
variables.
search:
methodcall:
name: "query"
args:
1: # configured using the expression target
containsUntrustedInput: true
public void getUser(String name) {
String sql = "SELECT * FROM users WHERE name = '" + name "'";
Database.query(sql);
}
When false
, this analysis can also be used to test if an expression only contains constants.
trustNonTextualsByDefault¶
Since concatenating numbers, booleans or other non-textual primitives with strings, entails fewer security implications, Sensei has chosen to trust them by default. However, this behavior can be changed via this property.
'trustNonTextualsByDefault' should only be used in combination with containsUntrustedInput.
search:
methodcall:
name: "query"
args:
1: # configured using the expression target
containsUntrustedInput: true
trustNonTextualsByDefault: false
public void getUser(int id) {
String sql = "SELECT * FROM users WHERE id = " + id;
Database.query(sql);
}
trustedSources¶
As explained in value
, Sensei considers any value that is unknown at compile time as untrusted.
However, it's possible to override this behavior and choose which elements are
considered secure. This option allows users to tell Sensei that their sanitization routines are secure.
This property should only be used in combination with containsUntrustedInput.
search:
methodcall:
name: "query"
args:
1: # configured using the expression target
containsUntrustedInput: true
trustedSources:
- methodcall:
name: "htmlEncode"
public void getUser(int id) {
String content = "<html><p>Hello " + htmlEncode(name) + "</p></html>";
Response.sendHTML(content);
}
Note
This property is configured as a list of Targets
referenceTo¶
Checks if the expression is a reference.
Generic Configuration options¶
The following options are generic and available for every target.
anyOf¶
Similar to the logical operator OR: one or more descendant options should match.
search:
<target>:
anyOf:
- name: "illegal"
- name: "alsoIllegal"
allOf¶
Similar to the logical operator AND: all descendant options must match.
search:
<target>:
allOf:
- annotation: "HttpPost"
- annotation: "AllowUnAuthorized"
with¶
The only purpose to use this field is to make the recipe easier to read. It provides no additional functionality.
search:
<target>:
with:
annotation: "HttpPost"
not, without¶
Works as the logical operator NOT. It will negate the result of the descendant options. Sensei presents the
user with both options. They display the same behavior, but certain scenarios tend to read better using
without
.
search:
<target>:
not:
annotation: "HttpPost"
search:
<target>:
without:
annotation: "HttpPost"
in¶
Performs a structural search, this option is mainly used to narrow down recipes. Examples of this would be to only analyze and mark code inside a certain class or method that has a specific annotation. However, we haven't limited this option to only support these two scenarios. More advanced configuration can be achieved.
search:
<target>:
in:
class:
name:
contains: "Controller"
search:
<target>:
in:
method:
annotation:
type: "HttpPost"
label¶
Labels do not modify the behavior of searching elements, but they allow addressing a specific element in a quick fix.
search:
element:
tagName: inner
attribute:
name: data
in:
element:
label: outerelement
availableFixes:
- name: add the 'type' attribute on the outer element
actions:
- add:
attribute:
name: type
value: '"unsafe"'
target: label:outerelement
- <outer>
+ <outer type="unsafe">
<inner data="test"/>
</outer>