Merge remote-tracking branch 'upstream/main' into JsonHijacking

This commit is contained in:
haby0
2021-03-24 15:52:01 +08:00
1762 changed files with 46263 additions and 15293 deletions

View File

@@ -1,6 +1,7 @@
/**
* Provides a library for writing QL tests whose success or failure is based on expected results
* embedded in the test source code as comments, rather than a `.expected` file.
* embedded in the test source code as comments, rather than the contents of an `.expected` file
* (in that the `.expected` file should always be empty).
*
* To add this framework to a new language:
* - Add a file `InlineExpectationsTestPrivate.qll` that defines a `LineComment` class. This class
@@ -233,7 +234,9 @@ private string expectationPattern() {
exists(string tag, string tags, string value |
tag = "[A-Za-z-_][A-Za-z-_0-9]*" and
tags = "((?:" + tag + ")(?:\\s*,\\s*" + tag + ")*)" and
value = "((?:\"[^\"]*\"|'[^']*'|\\S+)*)" and
// In Python, we allow both `"` and `'` for strings, as well as the prefixes `bru`.
// For example, `b"foo"`.
value = "((?:[bru]*\"[^\"]*\"|[bru]*'[^']*'|\\S+)*)" and
result = tags + "(?:=" + value + ")?"
)
}

View File

@@ -0,0 +1,120 @@
import org.apache.commons.jexl2.*;
import java.io.StringWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.function.Consumer;
public class Jexl2Injection {
private static void runJexlExpression(String jexlExpr) {
JexlEngine jexl = new JexlEngine();
Expression e = jexl.createExpression(jexlExpr);
JexlContext jc = new MapContext();
e.evaluate(jc);
}
private static void runJexlExpressionWithJexlInfo(String jexlExpr) {
JexlEngine jexl = new JexlEngine();
Expression e = jexl.createExpression(
jexlExpr, new DebugInfo("unknown", 0, 0));
JexlContext jc = new MapContext();
e.evaluate(jc);
}
private static void runJexlScript(String jexlExpr) {
JexlEngine jexl = new JexlEngine();
Script script = jexl.createScript(jexlExpr);
JexlContext jc = new MapContext();
script.execute(jc);
}
private static void runJexlScriptViaCallable(String jexlExpr) {
JexlEngine jexl = new JexlEngine();
Script script = jexl.createScript(jexlExpr);
JexlContext jc = new MapContext();
try {
script.callable(jc).call();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static void runJexlExpressionViaGetProperty(String jexlExpr) {
JexlEngine jexl = new JexlEngine();
jexl.getProperty(new Object(), jexlExpr);
}
private static void runJexlExpressionViaSetProperty(String jexlExpr) {
JexlEngine jexl = new JexlEngine();
jexl.setProperty(new Object(), jexlExpr, new Object());
}
private static void runJexlExpressionViaUnifiedJEXLParseAndEvaluate(String jexlExpr) {
JexlEngine jexl = new JexlEngine();
UnifiedJEXL unifiedJEXL = new UnifiedJEXL(jexl);
unifiedJEXL.parse(jexlExpr).evaluate(new MapContext());
}
private static void runJexlExpressionViaUnifiedJEXLParseAndPrepare(String jexlExpr) {
JexlEngine jexl = new JexlEngine();
UnifiedJEXL unifiedJEXL = new UnifiedJEXL(jexl);
unifiedJEXL.parse(jexlExpr).prepare(new MapContext());
}
private static void runJexlExpressionViaUnifiedJEXLTemplateEvaluate(String jexlExpr) {
JexlEngine jexl = new JexlEngine();
UnifiedJEXL unifiedJEXL = new UnifiedJEXL(jexl);
unifiedJEXL.createTemplate(jexlExpr).evaluate(new MapContext(), new StringWriter());
}
private static void testWithSocket(Consumer<String> action) throws Exception {
try (ServerSocket serverSocket = new ServerSocket(0)) {
try (Socket socket = serverSocket.accept()) {
byte[] bytes = new byte[1024];
int n = socket.getInputStream().read(bytes);
String jexlExpr = new String(bytes, 0, n);
action.accept(jexlExpr);
}
}
}
// below are tests for the query
public static void testWithJexlExpressionEvaluate() throws Exception {
testWithSocket(Jexl2Injection::runJexlExpression);
}
public static void testWithJexlExpressionEvaluateWithInfo() throws Exception {
testWithSocket(Jexl2Injection::runJexlExpressionWithJexlInfo);
}
public static void testWithJexlScriptExecute() throws Exception {
testWithSocket(Jexl2Injection::runJexlScript);
}
public static void testWithJexlScriptCallable() throws Exception {
testWithSocket(Jexl2Injection::runJexlScriptViaCallable);
}
public static void testWithJexlEngineGetProperty() throws Exception {
testWithSocket(Jexl2Injection::runJexlExpressionViaGetProperty);
}
public static void testWithJexlEngineSetProperty() throws Exception {
testWithSocket(Jexl2Injection::runJexlExpressionViaSetProperty);
}
public static void testWithUnifiedJEXLParseAndEvaluate() throws Exception {
testWithSocket(Jexl2Injection::runJexlExpressionViaUnifiedJEXLParseAndEvaluate);
}
public static void testWithUnifiedJEXLParseAndPrepare() throws Exception {
testWithSocket(Jexl2Injection::runJexlExpressionViaUnifiedJEXLParseAndPrepare);
}
public static void testWithUnifiedJEXLTemplateEvaluate() throws Exception {
testWithSocket(Jexl2Injection::runJexlExpressionViaUnifiedJEXLTemplateEvaluate);
}
}

View File

@@ -0,0 +1,196 @@
import java.io.StringWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.function.Consumer;
import org.apache.commons.jexl3.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@Controller
public class Jexl3Injection {
private static void runJexlExpression(String jexlExpr) {
JexlEngine jexl = new JexlBuilder().create();
JexlExpression e = jexl.createExpression(jexlExpr);
JexlContext jc = new MapContext();
e.evaluate(jc);
}
private static void runJexlExpressionWithJexlInfo(String jexlExpr) {
JexlEngine jexl = new JexlBuilder().create();
JexlExpression e = jexl.createExpression(new JexlInfo("unknown", 0, 0), jexlExpr);
JexlContext jc = new MapContext();
e.evaluate(jc);
}
private static void runJexlScript(String jexlExpr) {
JexlEngine jexl = new JexlBuilder().create();
JexlScript script = jexl.createScript(jexlExpr);
JexlContext jc = new MapContext();
script.execute(jc);
}
private static void runJexlScriptViaCallable(String jexlExpr) {
JexlEngine jexl = new JexlBuilder().create();
JexlScript script = jexl.createScript(jexlExpr);
JexlContext jc = new MapContext();
try {
script.callable(jc).call();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static void runJexlExpressionViaGetProperty(String jexlExpr) {
JexlEngine jexl = new JexlBuilder().create();
jexl.getProperty(new Object(), jexlExpr);
}
private static void runJexlExpressionViaSetProperty(String jexlExpr) {
JexlEngine jexl = new JexlBuilder().create();
jexl.setProperty(new Object(), jexlExpr, new Object());
}
private static void runJexlExpressionViaJxltEngineExpressionEvaluate(String jexlExpr) {
JexlEngine jexl = new JexlBuilder().create();
JxltEngine jxlt = jexl.createJxltEngine();
jxlt.createExpression(jexlExpr).evaluate(new MapContext());
}
private static void runJexlExpressionViaJxltEngineExpressionPrepare(String jexlExpr) {
JexlEngine jexl = new JexlBuilder().create();
JxltEngine jxlt = jexl.createJxltEngine();
jxlt.createExpression(jexlExpr).prepare(new MapContext());
}
private static void runJexlExpressionViaJxltEngineTemplateEvaluate(String jexlExpr) {
JexlEngine jexl = new JexlBuilder().create();
JxltEngine jxlt = jexl.createJxltEngine();
jxlt.createTemplate(jexlExpr).evaluate(new MapContext(), new StringWriter());
}
private static void runJexlExpressionViaCallable(String jexlExpr) {
JexlEngine jexl = new JexlBuilder().create();
JexlExpression e = jexl.createExpression(jexlExpr);
JexlContext jc = new MapContext();
try {
e.callable(jc).call();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
private static void testWithSocket(Consumer<String> action) throws Exception {
try (ServerSocket serverSocket = new ServerSocket(0)) {
try (Socket socket = serverSocket.accept()) {
byte[] bytes = new byte[1024];
int n = socket.getInputStream().read(bytes);
String jexlExpr = new String(bytes, 0, n);
action.accept(jexlExpr);
}
}
}
// below are tests for the query
public static void testWithJexlExpressionEvaluate() throws Exception {
testWithSocket(Jexl3Injection::runJexlExpression);
}
public static void testWithJexlExpressionEvaluateWithInfo() throws Exception {
testWithSocket(Jexl3Injection::runJexlExpressionWithJexlInfo);
}
public static void testWithJexlScriptExecute() throws Exception {
testWithSocket(Jexl3Injection::runJexlScript);
}
public static void testWithJexlScriptCallable() throws Exception {
testWithSocket(Jexl3Injection::runJexlScriptViaCallable);
}
public static void testWithJexlEngineGetProperty() throws Exception {
testWithSocket(Jexl3Injection::runJexlExpressionViaGetProperty);
}
public static void testWithJexlEngineSetProperty() throws Exception {
testWithSocket(Jexl3Injection::runJexlExpressionViaSetProperty);
}
public static void testWithJxltEngineExpressionEvaluate() throws Exception {
testWithSocket(Jexl3Injection::runJexlExpressionViaJxltEngineExpressionEvaluate);
}
public static void testWithJxltEngineExpressionPrepare() throws Exception {
testWithSocket(Jexl3Injection::runJexlExpressionViaJxltEngineExpressionPrepare);
}
public static void testWithJxltEngineTemplateEvaluate() throws Exception {
testWithSocket(Jexl3Injection::runJexlExpressionViaJxltEngineTemplateEvaluate);
}
public static void testWithJexlExpressionCallable() throws Exception {
testWithSocket(Jexl3Injection::runJexlExpressionViaCallable);
}
@PostMapping("/request")
public ResponseEntity testWithSpringControllerThatEvaluatesJexlFromPathVariable(
@PathVariable String expr) {
runJexlExpression(expr);
return ResponseEntity.ok(HttpStatus.OK);
}
@PostMapping("/request")
public ResponseEntity testWithSpringControllerThatEvaluatesJexlFromRequestBody(
@RequestBody Data data) {
String expr = data.getExpr();
runJexlExpression(expr);
return ResponseEntity.ok(HttpStatus.OK);
}
@PostMapping("/request")
public ResponseEntity testWithSpringControllerThatEvaluatesJexlFromRequestBodyWithNestedObjects(
@RequestBody CustomRequest customRequest) {
String expr = customRequest.getData().getExpr();
runJexlExpression(expr);
return ResponseEntity.ok(HttpStatus.OK);
}
public static class CustomRequest {
private Data data;
CustomRequest(Data data) {
this.data = data;
}
public Data getData() {
return data;
}
}
public static class Data {
private String expr;
Data(String expr) {
this.expr = expr;
}
public String getExpr() {
return expr;
}
}
}

View File

@@ -0,0 +1,195 @@
edges
| Jexl2Injection.java:10:43:10:57 | jexlExpr : String | Jexl2Injection.java:14:9:14:9 | e |
| Jexl2Injection.java:17:55:17:69 | jexlExpr : String | Jexl2Injection.java:22:9:22:9 | e |
| Jexl2Injection.java:25:39:25:53 | jexlExpr : String | Jexl2Injection.java:29:9:29:14 | script |
| Jexl2Injection.java:32:50:32:64 | jexlExpr : String | Jexl2Injection.java:38:13:38:18 | script |
| Jexl2Injection.java:44:57:44:71 | jexlExpr : String | Jexl2Injection.java:46:40:46:47 | jexlExpr |
| Jexl2Injection.java:49:57:49:71 | jexlExpr : String | Jexl2Injection.java:51:40:51:47 | jexlExpr |
| Jexl2Injection.java:54:73:54:87 | jexlExpr : String | Jexl2Injection.java:57:9:57:35 | parse(...) |
| Jexl2Injection.java:60:72:60:86 | jexlExpr : String | Jexl2Injection.java:63:9:63:35 | parse(...) |
| Jexl2Injection.java:66:73:66:87 | jexlExpr : String | Jexl2Injection.java:69:9:69:44 | createTemplate(...) |
| Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:78:31:78:38 | jexlExpr : String |
| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:86:24:86:56 | jexlExpr : String |
| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:90:24:90:68 | jexlExpr : String |
| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:94:24:94:52 | jexlExpr : String |
| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:98:24:98:63 | jexlExpr : String |
| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:102:24:102:70 | jexlExpr : String |
| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:106:24:106:70 | jexlExpr : String |
| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:110:24:110:86 | jexlExpr : String |
| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:114:24:114:85 | jexlExpr : String |
| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | Jexl2Injection.java:118:24:118:86 | jexlExpr : String |
| Jexl2Injection.java:86:24:86:56 | jexlExpr : String | Jexl2Injection.java:10:43:10:57 | jexlExpr : String |
| Jexl2Injection.java:86:24:86:56 | jexlExpr : String | Jexl2Injection.java:86:24:86:56 | jexlExpr : String |
| Jexl2Injection.java:90:24:90:68 | jexlExpr : String | Jexl2Injection.java:17:55:17:69 | jexlExpr : String |
| Jexl2Injection.java:90:24:90:68 | jexlExpr : String | Jexl2Injection.java:90:24:90:68 | jexlExpr : String |
| Jexl2Injection.java:94:24:94:52 | jexlExpr : String | Jexl2Injection.java:25:39:25:53 | jexlExpr : String |
| Jexl2Injection.java:94:24:94:52 | jexlExpr : String | Jexl2Injection.java:94:24:94:52 | jexlExpr : String |
| Jexl2Injection.java:98:24:98:63 | jexlExpr : String | Jexl2Injection.java:32:50:32:64 | jexlExpr : String |
| Jexl2Injection.java:98:24:98:63 | jexlExpr : String | Jexl2Injection.java:98:24:98:63 | jexlExpr : String |
| Jexl2Injection.java:102:24:102:70 | jexlExpr : String | Jexl2Injection.java:44:57:44:71 | jexlExpr : String |
| Jexl2Injection.java:102:24:102:70 | jexlExpr : String | Jexl2Injection.java:102:24:102:70 | jexlExpr : String |
| Jexl2Injection.java:106:24:106:70 | jexlExpr : String | Jexl2Injection.java:49:57:49:71 | jexlExpr : String |
| Jexl2Injection.java:106:24:106:70 | jexlExpr : String | Jexl2Injection.java:106:24:106:70 | jexlExpr : String |
| Jexl2Injection.java:110:24:110:86 | jexlExpr : String | Jexl2Injection.java:54:73:54:87 | jexlExpr : String |
| Jexl2Injection.java:110:24:110:86 | jexlExpr : String | Jexl2Injection.java:110:24:110:86 | jexlExpr : String |
| Jexl2Injection.java:114:24:114:85 | jexlExpr : String | Jexl2Injection.java:60:72:60:86 | jexlExpr : String |
| Jexl2Injection.java:114:24:114:85 | jexlExpr : String | Jexl2Injection.java:114:24:114:85 | jexlExpr : String |
| Jexl2Injection.java:118:24:118:86 | jexlExpr : String | Jexl2Injection.java:66:73:66:87 | jexlExpr : String |
| Jexl2Injection.java:118:24:118:86 | jexlExpr : String | Jexl2Injection.java:118:24:118:86 | jexlExpr : String |
| Jexl3Injection.java:17:43:17:57 | jexlExpr : String | Jexl3Injection.java:21:9:21:9 | e |
| Jexl3Injection.java:24:55:24:69 | jexlExpr : String | Jexl3Injection.java:28:9:28:9 | e |
| Jexl3Injection.java:31:39:31:53 | jexlExpr : String | Jexl3Injection.java:35:9:35:14 | script |
| Jexl3Injection.java:38:50:38:64 | jexlExpr : String | Jexl3Injection.java:44:13:44:18 | script |
| Jexl3Injection.java:50:57:50:71 | jexlExpr : String | Jexl3Injection.java:52:40:52:47 | jexlExpr |
| Jexl3Injection.java:55:57:55:71 | jexlExpr : String | Jexl3Injection.java:57:40:57:47 | jexlExpr |
| Jexl3Injection.java:60:74:60:88 | jexlExpr : String | Jexl3Injection.java:63:9:63:39 | createExpression(...) |
| Jexl3Injection.java:66:73:66:87 | jexlExpr : String | Jexl3Injection.java:69:9:69:39 | createExpression(...) |
| Jexl3Injection.java:72:72:72:86 | jexlExpr : String | Jexl3Injection.java:75:9:75:37 | createTemplate(...) |
| Jexl3Injection.java:78:54:78:68 | jexlExpr : String | Jexl3Injection.java:84:13:84:13 | e |
| Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:96:31:96:38 | jexlExpr : String |
| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:104:24:104:56 | jexlExpr : String |
| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:108:24:108:68 | jexlExpr : String |
| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:112:24:112:52 | jexlExpr : String |
| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:116:24:116:63 | jexlExpr : String |
| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:120:24:120:70 | jexlExpr : String |
| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:124:24:124:70 | jexlExpr : String |
| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:128:24:128:87 | jexlExpr : String |
| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:132:24:132:86 | jexlExpr : String |
| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:136:24:136:85 | jexlExpr : String |
| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | Jexl3Injection.java:140:24:140:67 | jexlExpr : String |
| Jexl3Injection.java:104:24:104:56 | jexlExpr : String | Jexl3Injection.java:17:43:17:57 | jexlExpr : String |
| Jexl3Injection.java:104:24:104:56 | jexlExpr : String | Jexl3Injection.java:104:24:104:56 | jexlExpr : String |
| Jexl3Injection.java:108:24:108:68 | jexlExpr : String | Jexl3Injection.java:24:55:24:69 | jexlExpr : String |
| Jexl3Injection.java:108:24:108:68 | jexlExpr : String | Jexl3Injection.java:108:24:108:68 | jexlExpr : String |
| Jexl3Injection.java:112:24:112:52 | jexlExpr : String | Jexl3Injection.java:31:39:31:53 | jexlExpr : String |
| Jexl3Injection.java:112:24:112:52 | jexlExpr : String | Jexl3Injection.java:112:24:112:52 | jexlExpr : String |
| Jexl3Injection.java:116:24:116:63 | jexlExpr : String | Jexl3Injection.java:38:50:38:64 | jexlExpr : String |
| Jexl3Injection.java:116:24:116:63 | jexlExpr : String | Jexl3Injection.java:116:24:116:63 | jexlExpr : String |
| Jexl3Injection.java:120:24:120:70 | jexlExpr : String | Jexl3Injection.java:50:57:50:71 | jexlExpr : String |
| Jexl3Injection.java:120:24:120:70 | jexlExpr : String | Jexl3Injection.java:120:24:120:70 | jexlExpr : String |
| Jexl3Injection.java:124:24:124:70 | jexlExpr : String | Jexl3Injection.java:55:57:55:71 | jexlExpr : String |
| Jexl3Injection.java:124:24:124:70 | jexlExpr : String | Jexl3Injection.java:124:24:124:70 | jexlExpr : String |
| Jexl3Injection.java:128:24:128:87 | jexlExpr : String | Jexl3Injection.java:60:74:60:88 | jexlExpr : String |
| Jexl3Injection.java:128:24:128:87 | jexlExpr : String | Jexl3Injection.java:128:24:128:87 | jexlExpr : String |
| Jexl3Injection.java:132:24:132:86 | jexlExpr : String | Jexl3Injection.java:66:73:66:87 | jexlExpr : String |
| Jexl3Injection.java:132:24:132:86 | jexlExpr : String | Jexl3Injection.java:132:24:132:86 | jexlExpr : String |
| Jexl3Injection.java:136:24:136:85 | jexlExpr : String | Jexl3Injection.java:72:72:72:86 | jexlExpr : String |
| Jexl3Injection.java:136:24:136:85 | jexlExpr : String | Jexl3Injection.java:136:24:136:85 | jexlExpr : String |
| Jexl3Injection.java:140:24:140:67 | jexlExpr : String | Jexl3Injection.java:78:54:78:68 | jexlExpr : String |
| Jexl3Injection.java:140:24:140:67 | jexlExpr : String | Jexl3Injection.java:140:24:140:67 | jexlExpr : String |
| Jexl3Injection.java:145:13:145:37 | expr : String | Jexl3Injection.java:147:27:147:30 | expr : String |
| Jexl3Injection.java:147:27:147:30 | expr : String | Jexl3Injection.java:17:43:17:57 | jexlExpr : String |
| Jexl3Injection.java:153:13:153:34 | data : Data | Jexl3Injection.java:156:27:156:30 | expr : String |
| Jexl3Injection.java:156:27:156:30 | expr : String | Jexl3Injection.java:17:43:17:57 | jexlExpr : String |
| Jexl3Injection.java:163:13:163:52 | customRequest : CustomRequest | Jexl3Injection.java:166:27:166:30 | expr : String |
| Jexl3Injection.java:166:27:166:30 | expr : String | Jexl3Injection.java:17:43:17:57 | jexlExpr : String |
nodes
| Jexl2Injection.java:10:43:10:57 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:14:9:14:9 | e | semmle.label | e |
| Jexl2Injection.java:17:55:17:69 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:22:9:22:9 | e | semmle.label | e |
| Jexl2Injection.java:25:39:25:53 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:29:9:29:14 | script | semmle.label | script |
| Jexl2Injection.java:32:50:32:64 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:38:13:38:18 | script | semmle.label | script |
| Jexl2Injection.java:44:57:44:71 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:46:40:46:47 | jexlExpr | semmle.label | jexlExpr |
| Jexl2Injection.java:49:57:49:71 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:51:40:51:47 | jexlExpr | semmle.label | jexlExpr |
| Jexl2Injection.java:54:73:54:87 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:57:9:57:35 | parse(...) | semmle.label | parse(...) |
| Jexl2Injection.java:60:72:60:86 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:63:9:63:35 | parse(...) | semmle.label | parse(...) |
| Jexl2Injection.java:66:73:66:87 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:69:9:69:44 | createTemplate(...) | semmle.label | createTemplate(...) |
| Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| Jexl2Injection.java:78:31:78:38 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:86:24:86:56 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:86:24:86:56 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:90:24:90:68 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:90:24:90:68 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:94:24:94:52 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:94:24:94:52 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:98:24:98:63 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:98:24:98:63 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:102:24:102:70 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:102:24:102:70 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:106:24:106:70 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:106:24:106:70 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:110:24:110:86 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:110:24:110:86 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:114:24:114:85 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:114:24:114:85 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:118:24:118:86 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl2Injection.java:118:24:118:86 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:17:43:17:57 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:21:9:21:9 | e | semmle.label | e |
| Jexl3Injection.java:24:55:24:69 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:28:9:28:9 | e | semmle.label | e |
| Jexl3Injection.java:31:39:31:53 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:35:9:35:14 | script | semmle.label | script |
| Jexl3Injection.java:38:50:38:64 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:44:13:44:18 | script | semmle.label | script |
| Jexl3Injection.java:50:57:50:71 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:52:40:52:47 | jexlExpr | semmle.label | jexlExpr |
| Jexl3Injection.java:55:57:55:71 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:57:40:57:47 | jexlExpr | semmle.label | jexlExpr |
| Jexl3Injection.java:60:74:60:88 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:63:9:63:39 | createExpression(...) | semmle.label | createExpression(...) |
| Jexl3Injection.java:66:73:66:87 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:69:9:69:39 | createExpression(...) | semmle.label | createExpression(...) |
| Jexl3Injection.java:72:72:72:86 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:75:9:75:37 | createTemplate(...) | semmle.label | createTemplate(...) |
| Jexl3Injection.java:78:54:78:68 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:84:13:84:13 | e | semmle.label | e |
| Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| Jexl3Injection.java:96:31:96:38 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:104:24:104:56 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:104:24:104:56 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:108:24:108:68 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:108:24:108:68 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:112:24:112:52 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:112:24:112:52 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:116:24:116:63 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:116:24:116:63 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:120:24:120:70 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:120:24:120:70 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:124:24:124:70 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:124:24:124:70 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:128:24:128:87 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:128:24:128:87 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:132:24:132:86 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:132:24:132:86 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:136:24:136:85 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:136:24:136:85 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:140:24:140:67 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:140:24:140:67 | jexlExpr : String | semmle.label | jexlExpr : String |
| Jexl3Injection.java:145:13:145:37 | expr : String | semmle.label | expr : String |
| Jexl3Injection.java:147:27:147:30 | expr : String | semmle.label | expr : String |
| Jexl3Injection.java:153:13:153:34 | data : Data | semmle.label | data : Data |
| Jexl3Injection.java:156:27:156:30 | expr : String | semmle.label | expr : String |
| Jexl3Injection.java:163:13:163:52 | customRequest : CustomRequest | semmle.label | customRequest : CustomRequest |
| Jexl3Injection.java:166:27:166:30 | expr : String | semmle.label | expr : String |
#select
| Jexl2Injection.java:14:9:14:9 | e | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:14:9:14:9 | e | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:22:9:22:9 | e | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:22:9:22:9 | e | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:29:9:29:14 | script | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:29:9:29:14 | script | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:38:13:38:18 | script | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:38:13:38:18 | script | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:46:40:46:47 | jexlExpr | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:46:40:46:47 | jexlExpr | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:51:40:51:47 | jexlExpr | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:51:40:51:47 | jexlExpr | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:57:9:57:35 | parse(...) | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:57:9:57:35 | parse(...) | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:63:9:63:35 | parse(...) | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:63:9:63:35 | parse(...) | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl2Injection.java:69:9:69:44 | createTemplate(...) | Jexl2Injection.java:76:25:76:47 | getInputStream(...) : InputStream | Jexl2Injection.java:69:9:69:44 | createTemplate(...) | JEXL injection from $@. | Jexl2Injection.java:76:25:76:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:21:9:21:9 | e | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:21:9:21:9 | e | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:21:9:21:9 | e | Jexl3Injection.java:145:13:145:37 | expr : String | Jexl3Injection.java:21:9:21:9 | e | JEXL injection from $@. | Jexl3Injection.java:145:13:145:37 | expr | this user input |
| Jexl3Injection.java:21:9:21:9 | e | Jexl3Injection.java:153:13:153:34 | data : Data | Jexl3Injection.java:21:9:21:9 | e | JEXL injection from $@. | Jexl3Injection.java:153:13:153:34 | data | this user input |
| Jexl3Injection.java:21:9:21:9 | e | Jexl3Injection.java:163:13:163:52 | customRequest : CustomRequest | Jexl3Injection.java:21:9:21:9 | e | JEXL injection from $@. | Jexl3Injection.java:163:13:163:52 | customRequest | this user input |
| Jexl3Injection.java:28:9:28:9 | e | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:28:9:28:9 | e | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:35:9:35:14 | script | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:35:9:35:14 | script | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:44:13:44:18 | script | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:44:13:44:18 | script | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:52:40:52:47 | jexlExpr | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:52:40:52:47 | jexlExpr | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:57:40:57:47 | jexlExpr | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:57:40:57:47 | jexlExpr | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:63:9:63:39 | createExpression(...) | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:63:9:63:39 | createExpression(...) | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:69:9:69:39 | createExpression(...) | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:69:9:69:39 | createExpression(...) | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:75:9:75:37 | createTemplate(...) | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:75:9:75:37 | createTemplate(...) | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input |
| Jexl3Injection.java:84:13:84:13 | e | Jexl3Injection.java:94:25:94:47 | getInputStream(...) : InputStream | Jexl3Injection.java:84:13:84:13 | e | JEXL injection from $@. | Jexl3Injection.java:94:25:94:47 | getInputStream(...) | this user input |

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-094/JexlInjection.ql

View File

@@ -0,0 +1,47 @@
import org.apache.commons.jexl2.*;
import org.apache.commons.jexl2.introspection.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.function.Consumer;
public class SandboxedJexl2 {
private static void runJexlExpressionWithSandbox(String jexlExpr) {
Sandbox sandbox = new Sandbox();
sandbox.white(SandboxedJexl2.class.getCanonicalName());
Uberspect uberspect = new SandboxUberspectImpl(null, sandbox);
JexlEngine jexl = new JexlEngine(uberspect, null, null, null);
Expression e = jexl.createExpression(jexlExpr);
JexlContext jc = new MapContext();
e.evaluate(jc);
}
private static void runJexlExpressionViaSandboxedUnifiedJexl(String jexlExpr) {
Sandbox sandbox = new Sandbox();
sandbox.white(SandboxedJexl2.class.getCanonicalName());
Uberspect uberspect = new SandboxUberspectImpl(null, sandbox);
JexlEngine jexl = new JexlEngine(uberspect, null, null, null);
UnifiedJEXL unifiedJEXL = new UnifiedJEXL(jexl);
unifiedJEXL.parse(jexlExpr).evaluate(new MapContext());
}
private static void simpleServer(Consumer<String> action) throws Exception {
try (ServerSocket serverSocket = new ServerSocket(0)) {
try (Socket socket = serverSocket.accept()) {
byte[] bytes = new byte[1024];
int n = socket.getInputStream().read(bytes);
String jexlExpr = new String(bytes, 0, n);
action.accept(jexlExpr);
}
}
}
public static void saferJexlExpressionEvaluate() throws Exception {
simpleServer(SandboxedJexl2::runJexlExpressionWithSandbox);
}
public static void saferJexlExpressionEvaluateViaUnifiedJexl() throws Exception {
simpleServer(SandboxedJexl2::runJexlExpressionViaSandboxedUnifiedJexl);
}
}

View File

@@ -0,0 +1,76 @@
import java.net.ServerSocket;
import java.net.Socket;
import java.security.AccessControlException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import org.apache.commons.jexl3.*;
import org.apache.commons.jexl3.introspection.*;
public class SandboxedJexl3 {
private static void runJexlExpressionWithSandbox(String jexlExpr) {
JexlSandbox sandbox = new JexlSandbox(false);
sandbox.white(SandboxedJexl3.class.getCanonicalName());
JexlEngine jexl = new JexlBuilder().sandbox(sandbox).create();
JexlExpression e = jexl.createExpression(jexlExpr);
JexlContext jc = new MapContext();
e.evaluate(jc);
}
private static void runJexlExpressionWithUberspectSandbox(String jexlExpr) {
JexlUberspect sandbox = new JexlUberspectSandbox();
JexlEngine jexl = new JexlBuilder().uberspect(sandbox).create();
JexlExpression e = jexl.createExpression(jexlExpr);
JexlContext jc = new MapContext();
e.evaluate(jc);
}
private static JexlBuilder STATIC_JEXL_BUILDER;
static {
JexlSandbox sandbox = new JexlSandbox(false);
sandbox.white(SandboxedJexl3.class.getCanonicalName());
STATIC_JEXL_BUILDER = new JexlBuilder().sandbox(sandbox);
}
private static void runJexlExpressionViaJxltEngineWithSandbox(String jexlExpr) {
JexlEngine jexl = STATIC_JEXL_BUILDER.create();
JxltEngine jxlt = jexl.createJxltEngine();
jxlt.createExpression(jexlExpr).evaluate(new MapContext());
}
private static class JexlUberspectSandbox implements JexlUberspect {
}
private static void withSocket(Consumer<String> action) throws Exception {
try (ServerSocket serverSocket = new ServerSocket(0)) {
try (Socket socket = serverSocket.accept()) {
byte[] bytes = new byte[1024];
int n = socket.getInputStream().read(bytes);
String jexlExpr = new String(bytes, 0, n);
action.accept(jexlExpr);
}
}
}
// below are examples of safer Jexl usage
// with JexlSandbox
public static void saferJexlExpressionInSandbox() throws Exception {
withSocket(SandboxedJexl3::runJexlExpressionWithSandbox);
}
// with a custom sandbox implemented with JexlUberspect
public static void saferJexlExpressionInUberspectSandbox() throws Exception {
withSocket(SandboxedJexl3::runJexlExpressionWithUberspectSandbox);
}
// with JexlSandbox and JxltEngine
public static void saferJxltExpressionInSandbox() throws Exception {
withSocket(SandboxedJexl3::runJexlExpressionViaJxltEngineWithSandbox);
}
}

View File

@@ -0,0 +1,32 @@
edges
| ScriptEngineTest.java:8:44:8:55 | input : String | ScriptEngineTest.java:12:37:12:41 | input |
| ScriptEngineTest.java:15:51:15:62 | input : String | ScriptEngineTest.java:19:31:19:35 | input |
| ScriptEngineTest.java:23:58:23:69 | input : String | ScriptEngineTest.java:27:31:27:35 | input |
| ScriptEngineTest.java:30:46:30:57 | input : String | ScriptEngineTest.java:34:31:34:35 | input |
| ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:38:56:38:62 | ...[...] : String |
| ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:39:63:39:69 | ...[...] : String |
| ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:40:70:40:76 | ...[...] : String |
| ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:41:58:41:64 | ...[...] : String |
| ScriptEngineTest.java:38:56:38:62 | ...[...] : String | ScriptEngineTest.java:8:44:8:55 | input : String |
| ScriptEngineTest.java:39:63:39:69 | ...[...] : String | ScriptEngineTest.java:15:51:15:62 | input : String |
| ScriptEngineTest.java:40:70:40:76 | ...[...] : String | ScriptEngineTest.java:23:58:23:69 | input : String |
| ScriptEngineTest.java:41:58:41:64 | ...[...] : String | ScriptEngineTest.java:30:46:30:57 | input : String |
nodes
| ScriptEngineTest.java:8:44:8:55 | input : String | semmle.label | input : String |
| ScriptEngineTest.java:12:37:12:41 | input | semmle.label | input |
| ScriptEngineTest.java:15:51:15:62 | input : String | semmle.label | input : String |
| ScriptEngineTest.java:19:31:19:35 | input | semmle.label | input |
| ScriptEngineTest.java:23:58:23:69 | input : String | semmle.label | input : String |
| ScriptEngineTest.java:27:31:27:35 | input | semmle.label | input |
| ScriptEngineTest.java:30:46:30:57 | input : String | semmle.label | input : String |
| ScriptEngineTest.java:34:31:34:35 | input | semmle.label | input |
| ScriptEngineTest.java:37:26:37:38 | args : String[] | semmle.label | args : String[] |
| ScriptEngineTest.java:38:56:38:62 | ...[...] : String | semmle.label | ...[...] : String |
| ScriptEngineTest.java:39:63:39:69 | ...[...] : String | semmle.label | ...[...] : String |
| ScriptEngineTest.java:40:70:40:76 | ...[...] : String | semmle.label | ...[...] : String |
| ScriptEngineTest.java:41:58:41:64 | ...[...] : String | semmle.label | ...[...] : String |
#select
| ScriptEngineTest.java:12:19:12:42 | eval(...) | ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:12:37:12:41 | input | ScriptEngine eval $@. | ScriptEngineTest.java:37:26:37:38 | args | user input |
| ScriptEngineTest.java:19:19:19:36 | eval(...) | ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:19:31:19:35 | input | ScriptEngine eval $@. | ScriptEngineTest.java:37:26:37:38 | args | user input |
| ScriptEngineTest.java:27:19:27:36 | eval(...) | ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:27:31:27:35 | input | ScriptEngine eval $@. | ScriptEngineTest.java:37:26:37:38 | args | user input |
| ScriptEngineTest.java:34:19:34:36 | eval(...) | ScriptEngineTest.java:37:26:37:38 | args : String[] | ScriptEngineTest.java:34:31:34:35 | input | ScriptEngine eval $@. | ScriptEngineTest.java:37:26:37:38 | args | user input |

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-094/ScriptEngine.ql

View File

@@ -0,0 +1,58 @@
import jdk.nashorn.api.scripting.NashornScriptEngine;
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
import javax.script.*;
public class ScriptEngineTest {
public void testWithScriptEngineReference(String input) throws ScriptException {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
// Create with ScriptEngine reference
ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension("js");
Object result = scriptEngine.eval(input);
}
public void testNashornWithScriptEngineReference(String input) throws ScriptException {
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
// Create Nashorn with ScriptEngine reference
ScriptEngine engine = (NashornScriptEngine) factory.getScriptEngine(new String[] { "-scripting" });
Object result = engine.eval(input);
}
public void testNashornWithNashornScriptEngineReference(String input) throws ScriptException {
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
// Create Nashorn with NashornScriptEngine reference
NashornScriptEngine engine = (NashornScriptEngine) factory.getScriptEngine(new String[] { "-scripting" });
Object result = engine.eval(input);
}
public void testCustomScriptEngineReference(String input) throws ScriptException {
MyCustomFactory factory = new MyCustomFactory();
//Create with Custom Script Engine reference
MyCustomScriptEngine engine = (MyCustomScriptEngine) factory.getScriptEngine(new String[] { "-scripting" });
Object result = engine.eval(input);
}
public static void main(String[] args) throws ScriptException {
new ScriptEngineTest().testWithScriptEngineReference(args[0]);
new ScriptEngineTest().testNashornWithScriptEngineReference(args[0]);
new ScriptEngineTest().testNashornWithNashornScriptEngineReference(args[0]);
new ScriptEngineTest().testCustomScriptEngineReference(args[0]);
}
private static class MyCustomScriptEngine extends AbstractScriptEngine {
public Object eval(String var1) throws ScriptException {
return null;
}
}
private static class MyCustomFactory implements ScriptEngineFactory {
public MyCustomFactory() {
}
public ScriptEngine getScriptEngine() { return null; }
public ScriptEngine getScriptEngine(String... args) { return null; }
}
}

View File

@@ -1 +1,2 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.2.3:${testdir}/../../../../stubs/mvel2-2.4.7:${testdir}/../../../../stubs/jsr223-api
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.2.3:${testdir}/../../../../stubs/mvel2-2.4.7:${testdir}/../../../../stubs/jsr223-api:${testdir}/../../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../../stubs/scriptengine

View File

@@ -0,0 +1,5 @@
| InsecureLdapEndpoint.java:19:9:19:92 | setProperty(...) | LDAPS configuration allows insecure endpoint identification |
| InsecureLdapEndpoint.java:50:9:50:40 | setProperties(...) | LDAPS configuration allows insecure endpoint identification |
| InsecureLdapEndpoint.java:68:9:68:40 | setProperties(...) | LDAPS configuration allows insecure endpoint identification |
| InsecureLdapEndpoint.java:84:9:84:94 | setProperty(...) | LDAPS configuration allows insecure endpoint identification |
| InsecureLdapEndpoint.java:102:9:102:40 | setProperties(...) | LDAPS configuration allows insecure endpoint identification |

View File

@@ -0,0 +1,106 @@
import java.util.Hashtable;
import java.util.Properties;
import javax.naming.Context;
public class InsecureLdapEndpoint {
private static String PROP_DISABLE_LDAP_ENDPOINT_IDENTIFICATION = "com.sun.jndi.ldap.object.disableEndpointIdentification";
// BAD - Test configuration with disabled LDAPS endpoint check using `System.setProperty()`.
public Hashtable<String, String> createConnectionEnv() {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldaps://ad.your-server.com:636");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "username");
env.put(Context.SECURITY_CREDENTIALS, "secpassword");
// Disable SSL endpoint check
System.setProperty("com.sun.jndi.ldap.object.disableEndpointIdentification", "true");
return env;
}
// GOOD - Test configuration without disabling LDAPS endpoint check.
public Hashtable<String, String> createConnectionEnv2() {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldaps://ad.your-server.com:636");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "username");
env.put(Context.SECURITY_CREDENTIALS, "secpassword");
return env;
}
// BAD - Test configuration with disabled LDAPS endpoint check using `System.setProperties()`.
public Hashtable<String, String> createConnectionEnv3() {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldaps://ad.your-server.com:636");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "username");
env.put(Context.SECURITY_CREDENTIALS, "secpassword");
// Disable SSL endpoint check
Properties properties = new Properties();
properties.setProperty("com.sun.jndi.ldap.object.disableEndpointIdentification", "true");
System.setProperties(properties);
return env;
}
// BAD - Test configuration with disabled LDAPS endpoint check using `HashTable.put()`.
public Hashtable<String, String> createConnectionEnv4() {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldaps://ad.your-server.com:636");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "username");
env.put(Context.SECURITY_CREDENTIALS, "secpassword");
// Disable SSL endpoint check
Properties properties = new Properties();
properties.put("com.sun.jndi.ldap.object.disableEndpointIdentification", "true");
System.setProperties(properties);
return env;
}
// BAD - Test configuration with disabled LDAPS endpoint check using the `TRUE` boolean field.
public Hashtable<String, String> createConnectionEnv5() {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldaps://ad.your-server.com:636");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "username");
env.put(Context.SECURITY_CREDENTIALS, "secpassword");
// Disable SSL endpoint check
System.setProperty(PROP_DISABLE_LDAP_ENDPOINT_IDENTIFICATION, Boolean.TRUE.toString());
return env;
}
// BAD - Test configuration with disabled LDAPS endpoint check using a boolean value.
public Hashtable<String, String> createConnectionEnv6() {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldaps://ad.your-server.com:636");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "username");
env.put(Context.SECURITY_CREDENTIALS, "secpassword");
// Disable SSL endpoint check
Properties properties = new Properties();
properties.put("com.sun.jndi.ldap.object.disableEndpointIdentification", true);
System.setProperties(properties);
return env;
}
}

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-297/InsecureLdapEndpoint.ql

View File

@@ -0,0 +1,7 @@
edges
| UnvalidatedCors.java:21:22:21:48 | getHeader(...) : String | UnvalidatedCors.java:27:67:27:69 | url |
nodes
| UnvalidatedCors.java:21:22:21:48 | getHeader(...) : String | semmle.label | getHeader(...) : String |
| UnvalidatedCors.java:27:67:27:69 | url | semmle.label | url |
#select
| UnvalidatedCors.java:27:67:27:69 | url | UnvalidatedCors.java:21:22:21:48 | getHeader(...) : String | UnvalidatedCors.java:27:67:27:69 | url | CORS header is being set using user controlled value $@. | UnvalidatedCors.java:21:22:21:48 | getHeader(...) | user-provided value |

View File

@@ -0,0 +1,37 @@
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
public class UnvalidatedCors implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String url = request.getHeader("Origin");
if (!StringUtils.isEmpty(url)) {
String val = response.getHeader("Access-Control-Allow-Origin");
if (StringUtils.isEmpty(val)) {
response.addHeader("Access-Control-Allow-Origin", url);
response.addHeader("Access-Control-Allow-Credentials", "true");
}
}
chain.doFilter(req, res);
}
public void destroy() {}
}

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-346/UnvalidatedCors.ql

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/apache-commons-lang3-3.7

View File

@@ -0,0 +1 @@
| ServiceBean.java:55:24:55:27 | main | Java EE application has a main method. |

View File

@@ -0,0 +1,59 @@
import javax.ejb.SessionBean;
import javax.ejb.EJBException;
import java.rmi.RemoteException;
import javax.ejb.SessionContext;
import javax.naming.Context;
import javax.naming.InitialContext;
public class ServiceBean implements SessionBean {
protected SessionContext ctx;
private String _serviceName;
/**
* Create the session bean (empty implementation)
*/
public void ejbCreate() throws javax.ejb.CreateException {
System.out.println("ServiceBean:ejbCreate()");
}
public void ejbActivate() throws javax.ejb.EJBException, java.rmi.RemoteException {
}
public void ejbPassivate() throws javax.ejb.EJBException, java.rmi.RemoteException {
}
public void ejbRemove() throws javax.ejb.EJBException, java.rmi.RemoteException {
}
public void setSessionContext(SessionContext parm1) throws javax.ejb.EJBException, java.rmi.RemoteException {
}
/**
* Get service name
* @return service name
*/
public String getServiceName() {
return _serviceName;
}
/**
* Set service name
* @param serviceName the service name
*/
public void setServiceName(String serviceName) {
_serviceName = serviceName;
}
/** Do service (no implementation) */
public String doService() {
return null;
}
/** Local unit testing code */
public static void main(String[] args) throws Exception {
ServiceBean b = new ServiceBean();
b.doService();
}
}

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-489/EJBMain.ql

View File

@@ -0,0 +1,25 @@
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.net.URL;
public class ServletContextListenerMain implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("listener starts to work!");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("listener stopped!");
}
// BAD - Implement a main method in servlet listener.
public static void main(String[] args) {
try {
URL url = new URL("https://www.example.com");
url.openConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,2 @@
| ServletContextListenerMain.java:17:21:17:24 | main | Web application has a main method. |
| ServletMain.java:28:21:28:24 | main | Web application has a main method. |

View File

@@ -0,0 +1,33 @@
import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.ServletException;
import javax.servlet.ServletConfig;
import java.io.IOException;
import java.net.URL;
public class ServletMain implements Servlet {
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
public void init(ServletConfig servletConfig) throws ServletException {
}
public ServletConfig getServletConfig() {
return null;
}
public String getServletInfo() {
return null;
}
public void destroy() {
}
// BAD - Implement a main method in servlet.
public static void main(String[] args) throws Exception {
// Connect to my server
URL url = new URL("https://www.example.com");
url.openConnection();
}
}

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-489/WebComponentMain.ql

View File

@@ -0,0 +1 @@
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/ejb-3.2

View File

@@ -0,0 +1,43 @@
edges
| XQueryInjection.java:45:23:45:50 | getParameter(...) : String | XQueryInjection.java:51:35:51:38 | xqpe |
| XQueryInjection.java:59:23:59:50 | getParameter(...) : String | XQueryInjection.java:65:53:65:57 | query |
| XQueryInjection.java:73:32:73:59 | nameStr : String | XQueryInjection.java:79:35:79:38 | xqpe |
| XQueryInjection.java:86:33:86:60 | nameStr : String | XQueryInjection.java:92:53:92:57 | query |
| XQueryInjection.java:100:28:100:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:104:35:104:38 | xqpe |
| XQueryInjection.java:112:28:112:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:116:53:116:56 | name |
| XQueryInjection.java:124:28:124:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:129:35:129:38 | xqpe |
| XQueryInjection.java:137:28:137:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:142:53:142:54 | br |
| XQueryInjection.java:150:23:150:50 | getParameter(...) : String | XQueryInjection.java:155:29:155:32 | name |
| XQueryInjection.java:157:26:157:49 | getInputStream(...) : ServletInputStream | XQueryInjection.java:159:29:159:30 | br |
nodes
| XQueryInjection.java:45:23:45:50 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| XQueryInjection.java:51:35:51:38 | xqpe | semmle.label | xqpe |
| XQueryInjection.java:59:23:59:50 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| XQueryInjection.java:65:53:65:57 | query | semmle.label | query |
| XQueryInjection.java:73:32:73:59 | nameStr : String | semmle.label | nameStr : String |
| XQueryInjection.java:79:35:79:38 | xqpe | semmle.label | xqpe |
| XQueryInjection.java:86:33:86:60 | nameStr : String | semmle.label | nameStr : String |
| XQueryInjection.java:92:53:92:57 | query | semmle.label | query |
| XQueryInjection.java:100:28:100:51 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
| XQueryInjection.java:104:35:104:38 | xqpe | semmle.label | xqpe |
| XQueryInjection.java:112:28:112:51 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
| XQueryInjection.java:116:53:116:56 | name | semmle.label | name |
| XQueryInjection.java:124:28:124:51 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
| XQueryInjection.java:129:35:129:38 | xqpe | semmle.label | xqpe |
| XQueryInjection.java:137:28:137:51 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
| XQueryInjection.java:142:53:142:54 | br | semmle.label | br |
| XQueryInjection.java:150:23:150:50 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| XQueryInjection.java:155:29:155:32 | name | semmle.label | name |
| XQueryInjection.java:157:26:157:49 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
| XQueryInjection.java:159:29:159:30 | br | semmle.label | br |
#select
| XQueryInjection.java:51:35:51:38 | xqpe | XQueryInjection.java:45:23:45:50 | getParameter(...) : String | XQueryInjection.java:51:35:51:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:45:23:45:50 | getParameter(...) | this user input |
| XQueryInjection.java:65:53:65:57 | query | XQueryInjection.java:59:23:59:50 | getParameter(...) : String | XQueryInjection.java:65:53:65:57 | query | XQuery query might include code from $@. | XQueryInjection.java:59:23:59:50 | getParameter(...) | this user input |
| XQueryInjection.java:79:35:79:38 | xqpe | XQueryInjection.java:73:32:73:59 | nameStr : String | XQueryInjection.java:79:35:79:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:73:32:73:59 | nameStr | this user input |
| XQueryInjection.java:92:53:92:57 | query | XQueryInjection.java:86:33:86:60 | nameStr : String | XQueryInjection.java:92:53:92:57 | query | XQuery query might include code from $@. | XQueryInjection.java:86:33:86:60 | nameStr | this user input |
| XQueryInjection.java:104:35:104:38 | xqpe | XQueryInjection.java:100:28:100:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:104:35:104:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:100:28:100:51 | getInputStream(...) | this user input |
| XQueryInjection.java:116:53:116:56 | name | XQueryInjection.java:112:28:112:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:116:53:116:56 | name | XQuery query might include code from $@. | XQueryInjection.java:112:28:112:51 | getInputStream(...) | this user input |
| XQueryInjection.java:129:35:129:38 | xqpe | XQueryInjection.java:124:28:124:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:129:35:129:38 | xqpe | XQuery query might include code from $@. | XQueryInjection.java:124:28:124:51 | getInputStream(...) | this user input |
| XQueryInjection.java:142:53:142:54 | br | XQueryInjection.java:137:28:137:51 | getInputStream(...) : ServletInputStream | XQueryInjection.java:142:53:142:54 | br | XQuery query might include code from $@. | XQueryInjection.java:137:28:137:51 | getInputStream(...) | this user input |
| XQueryInjection.java:155:29:155:32 | name | XQueryInjection.java:150:23:150:50 | getParameter(...) : String | XQueryInjection.java:155:29:155:32 | name | XQuery query might include code from $@. | XQueryInjection.java:150:23:150:50 | getParameter(...) | this user input |
| XQueryInjection.java:159:29:159:30 | br | XQueryInjection.java:157:26:157:49 | getInputStream(...) : ServletInputStream | XQueryInjection.java:159:29:159:30 | br | XQuery query might include code from $@. | XQueryInjection.java:157:26:157:49 | getInputStream(...) | this user input |

View File

@@ -0,0 +1,195 @@
package com.vuln.v2.controller;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.servlet.http.HttpServletRequest;
import javax.xml.namespace.QName;
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQDataSource;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQExpression;
import javax.xml.xquery.XQItemType;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQResultSequence;
import net.sf.saxon.xqj.SaxonXQDataSource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class XQueryInjection {
public static void main(String[] args) throws Exception {
XQDataSource xqds = new SaxonXQDataSource();
XQConnection conn;
try {
String name = "admin";
String query = "declare variable $name as xs:string external;"
+ " for $user in doc(\"users.xml\")/Users/User[name=$name] return $user/password";
conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
expr.bindString(new QName("name"), name,
conn.createAtomicType(XQItemType.XQBASETYPE_STRING));
XQResultSequence result = expr.executeQuery(query);
while (result.next()) {
System.out.println(result.getItemAsString(null));
}
} catch (XQException e) {
e.printStackTrace();
}
}
@RequestMapping
public void testRequestbad(HttpServletRequest request) throws Exception {
String name = request.getParameter("name");
XQDataSource ds = new SaxonXQDataSource();
XQConnection conn = ds.getConnection();
String query = "for $user in doc(\"users.xml\")/Users/User[name='" + name
+ "'] return $user/password";
XQPreparedExpression xqpe = conn.prepareExpression(query);
XQResultSequence result = xqpe.executeQuery();
while (result.next()) {
System.out.println(result.getItemAsString(null));
}
}
@RequestMapping
public void testRequestbad1(HttpServletRequest request) throws Exception {
String name = request.getParameter("name");
XQDataSource xqds = new SaxonXQDataSource();
String query = "for $user in doc(\"users.xml\")/Users/User[name='" + name
+ "'] return $user/password";
XQConnection conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
XQResultSequence result = expr.executeQuery(query);
while (result.next()) {
System.out.println(result.getItemAsString(null));
}
}
@RequestMapping
public void testStringtbad(@RequestParam String nameStr) throws XQException {
XQDataSource ds = new SaxonXQDataSource();
XQConnection conn = ds.getConnection();
String query = "for $user in doc(\"users.xml\")/Users/User[name='" + nameStr
+ "'] return $user/password";
XQPreparedExpression xqpe = conn.prepareExpression(query);
XQResultSequence result = xqpe.executeQuery();
while (result.next()) {
System.out.println(result.getItemAsString(null));
}
}
@RequestMapping
public void testStringtbad1(@RequestParam String nameStr) throws XQException {
XQDataSource xqds = new SaxonXQDataSource();
String query = "for $user in doc(\"users.xml\")/Users/User[name='" + nameStr
+ "'] return $user/password";
XQConnection conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
XQResultSequence result = expr.executeQuery(query);
while (result.next()) {
System.out.println(result.getItemAsString(null));
}
}
@RequestMapping
public void testInputStreambad(HttpServletRequest request) throws Exception {
InputStream name = request.getInputStream();
XQDataSource ds = new SaxonXQDataSource();
XQConnection conn = ds.getConnection();
XQPreparedExpression xqpe = conn.prepareExpression(name);
XQResultSequence result = xqpe.executeQuery();
while (result.next()) {
System.out.println(result.getItemAsString(null));
}
}
@RequestMapping
public void testInputStreambad1(HttpServletRequest request) throws Exception {
InputStream name = request.getInputStream();
XQDataSource xqds = new SaxonXQDataSource();
XQConnection conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
XQResultSequence result = expr.executeQuery(name);
while (result.next()) {
System.out.println(result.getItemAsString(null));
}
}
@RequestMapping
public void testReaderbad(HttpServletRequest request) throws Exception {
InputStream name = request.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(name));
XQDataSource ds = new SaxonXQDataSource();
XQConnection conn = ds.getConnection();
XQPreparedExpression xqpe = conn.prepareExpression(br);
XQResultSequence result = xqpe.executeQuery();
while (result.next()) {
System.out.println(result.getItemAsString(null));
}
}
@RequestMapping
public void testReaderbad1(HttpServletRequest request) throws Exception {
InputStream name = request.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(name));
XQDataSource xqds = new SaxonXQDataSource();
XQConnection conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
XQResultSequence result = expr.executeQuery(br);
while (result.next()) {
System.out.println(result.getItemAsString(null));
}
}
@RequestMapping
public void testExecuteCommandbad(HttpServletRequest request) throws Exception {
String name = request.getParameter("name");
XQDataSource xqds = new SaxonXQDataSource();
XQConnection conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
//bad code
expr.executeCommand(name);
//bad code
InputStream is = request.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
expr.executeCommand(br);
expr.close();
}
@RequestMapping
public void good(HttpServletRequest request) throws XQException {
String name = request.getParameter("name");
XQDataSource ds = new SaxonXQDataSource();
XQConnection conn = ds.getConnection();
String query = "declare variable $name as xs:string external;"
+ " for $user in doc(\"users.xml\")/Users/User[name=$name] return $user/password";
XQPreparedExpression xqpe = conn.prepareExpression(query);
xqpe.bindString(new QName("name"), name,
conn.createAtomicType(XQItemType.XQBASETYPE_STRING));
XQResultSequence result = xqpe.executeQuery();
while (result.next()) {
System.out.println(result.getItemAsString(null));
}
}
@RequestMapping
public void good1(HttpServletRequest request) throws XQException {
String name = request.getParameter("name");
String query = "declare variable $name as xs:string external;"
+ " for $user in doc(\"users.xml\")/Users/User[name=$name] return $user/password";
XQDataSource xqds = new SaxonXQDataSource();
XQConnection conn = xqds.getConnection();
XQExpression expr = conn.createExpression();
expr.bindString(new QName("name"), name,
conn.createAtomicType(XQItemType.XQBASETYPE_STRING));
XQResultSequence result = expr.executeQuery(query);
while (result.next()) {
System.out.println(result.getItemAsString(null));
}
}
}

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-652/XQueryInjection.ql

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/apache-http-4.4.13/:${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/saxon-xqj-9.x/:${testdir}/../../../../stubs/springframework-5.2.3/

View File

@@ -0,0 +1,72 @@
public class Test {
private String field;
public Test fluentNoop() {
return this;
}
public Test modelledFluentMethod() {
// A model in the accompanying .ql file will indicate that the qualifier flows to the return value.
return null;
}
public static Test modelledIdentity(Test t) {
// A model in the accompanying .ql file will indicate that the argument flows to the return value.
return null;
}
public Test indirectlyFluentNoop() {
return this.fluentNoop();
}
public Test fluentSet(String x) {
this.field = x;
return this;
}
public static Test identity(Test t) {
return t;
}
public String get() {
return field;
}
public static String source() {
return "taint";
}
public static void sink(String s) {}
public static void test1() {
Test t = new Test();
t.fluentNoop().fluentSet(source()).fluentNoop();
sink(t.get()); // $hasTaintFlow
}
public static void test2() {
Test t = new Test();
Test.identity(t).fluentNoop().fluentSet(source()).fluentNoop();
sink(t.get()); // $hasTaintFlow
}
public static void test3() {
Test t = new Test();
t.indirectlyFluentNoop().fluentSet(source()).fluentNoop();
sink(t.get()); // $hasTaintFlow
}
public static void testModel1() {
Test t = new Test();
t.indirectlyFluentNoop().modelledFluentMethod().fluentSet(source()).fluentNoop();
sink(t.get()); // $hasTaintFlow
}
public static void testModel2() {
Test t = new Test();
Test.modelledIdentity(t).indirectlyFluentNoop().modelledFluentMethod().fluentSet(source()).fluentNoop();
sink(t.get()); // $hasTaintFlow
}
}

View File

@@ -0,0 +1,41 @@
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.FlowSteps
import TestUtilities.InlineExpectationsTest
class Conf extends DataFlow::Configuration {
Conf() { this = "qltest:dataflow:fluent-methods" }
override predicate isSource(DataFlow::Node n) {
n.asExpr().(MethodAccess).getMethod().hasName("source")
}
override predicate isSink(DataFlow::Node n) {
exists(MethodAccess ma | ma.getMethod().hasName("sink") | n.asExpr() = ma.getAnArgument())
}
}
class Model extends FluentMethod {
Model() { this.getName() = "modelledFluentMethod" }
}
class IdentityModel extends ValuePreservingMethod {
IdentityModel() { this.getName() = "modelledIdentity" }
override predicate returnsValue(int arg) { arg = 0 }
}
class HasFlowTest extends InlineExpectationsTest {
HasFlowTest() { this = "HasFlowTest" }
override string getARelevantTag() { result = "hasTaintFlow" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "hasTaintFlow" and
exists(DataFlow::Node src, DataFlow::Node sink, Conf conf | conf.hasFlow(src, sink) |
sink.getLocation() = location and
element = sink.toString() and
value = ""
)
}
}

View File

@@ -0,0 +1,63 @@
import java.lang.Runtime;
import java.util.function.Function;
public class Executor {
private static final Processor<String> processor = new Processor<String>();
private static String source() { return "taint"; }
public static void main(String[] args) {
exec1(source());
exec2(source());
exec3(source());
exec4(source());
exec5(source());
}
private static void exec1(String command){
command = process(s->s.toUpperCase(),command);
exec(command);
}
private static void exec2(String command){
command = process(s->"Taint stops here.",command);
exec(command);
}
private static void exec3(String command){
command = processor.process(s->s.toUpperCase(),command);
exec(command);
}
private static void exec4(String command){
command = processor.process(s->"Taint stops here.",command);
exec_b(command);
}
private static void exec5(String command){
command = processor.process(s->s.toUpperCase(),command);
exec_b(command);
}
public static String process(Function<String, String> fun, String command){
return processor.process(fun, command);
}
private static void exec(String command){
command = process(s->s.trim(),command);
try {
Runtime.getRuntime().exec(command);
}
catch(Exception e) {}
}
private static void exec_b(String command){
command = processor.process(s->s.trim(),command);
try {
Runtime.getRuntime().exec(command);
}
catch(Exception e) {}
}
}

View File

@@ -0,0 +1,9 @@
import java.util.function.Function;
public class Processor<T> {
public <R> R process(Function<T,R> function, T arg) {
return function.apply(arg);
}
}

View File

@@ -0,0 +1,30 @@
import java.util.function.Function;
public class StringProcessor {
private static final Processor<String> processor = new Processor<String>();
public static void main(String[] args) {
String command = args[0];
lambdaExec(command);
}
public static void lambdaExec(String command){
processor.process(s->exec(s), command);
}
public static String lambdaUnrelated(String command){
return processor.process(s->s+"not related to anything", command);
}
public static String exec(String command){
try {
command = processor.process(s->s.trim(), command);
Runtime.getRuntime().exec(command);
return "Executed: "+command;
} catch(Exception e) {
return null;
}
}
}

View File

@@ -0,0 +1,8 @@
| Executor.java:11:15:11:22 | source(...) | Executor.java:50:39:50:45 | command |
| Executor.java:11:15:11:22 | source(...) | StringProcessor.java:23:39:23:45 | command |
| Executor.java:12:15:12:22 | source(...) | Executor.java:50:39:50:45 | command |
| Executor.java:12:15:12:22 | source(...) | StringProcessor.java:23:39:23:45 | command |
| Executor.java:13:15:13:22 | source(...) | Executor.java:50:39:50:45 | command |
| Executor.java:13:15:13:22 | source(...) | StringProcessor.java:23:39:23:45 | command |
| Executor.java:15:15:15:22 | source(...) | Executor.java:58:39:58:45 | command |
| StringProcessor.java:8:26:8:29 | args | StringProcessor.java:23:39:23:45 | command |

View File

@@ -0,0 +1,24 @@
import java
import semmle.code.java.dataflow.TaintTracking
class Conf extends TaintTracking::Configuration {
Conf() { this = "qltest lambda" }
override predicate isSource(DataFlow::Node src) {
src.asExpr().(VarAccess).getVariable().hasName("args")
or
src.asExpr().(MethodAccess).getMethod().hasName("source")
}
override predicate isSink(DataFlow::Node sink) {
sink.asExpr().(Argument).getCall() =
any(MethodAccess ma |
ma.getMethod().hasName("exec") and
ma.getQualifier().(MethodAccess).getMethod().hasName("getRuntime")
)
}
}
from DataFlow::Node src, DataFlow::Node sink, Conf c
where c.hasFlow(src, sink)
select src, sink

View File

@@ -0,0 +1,36 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import play.filters.csrf.AddCSRFToken;
import play.libs.F;
import play.mvc.BodyParser;
import play.mvc.Controller;
import play.mvc.Http.*;
import play.mvc.Result;
public class PlayResource extends Controller {
@AddCSRFToken
public Result index() {
response().setHeader("X-Play-QL", "1");
return ok("It works!");
}
@BodyParser.Of()
public Result session_redirect_me(String uri) {
String url = request().getQueryString("url");
return redirect(url);
}
public F.Promise<Result> async_promise(String token) {
return F.Promise.pure(ok(token));
}
public CompletionStage<Result> async_completionstage(String uri) {
return CompletableFuture.completedFuture(ok("Async completion Stage"));
}
public String not_playactionmethod(String no_action) {
String return_code = no_action;
return return_code;
}
}

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/springframework-5.2.3:${testdir}/../../../stubs/google-android-9.0.0
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/springframework-5.2.3:${testdir}/../../../stubs/google-android-9.0.0:${testdir}/../../../stubs/playframework-2.6.x:${testdir}/../../../stubs/jackson-databind-2.10:${testdir}/../../../stubs/akka-2.6.x

View File

@@ -23,6 +23,14 @@
| IntentSources.java:33:20:33:33 | getIntent(...) | IntentSources.java:33:20:33:33 | getIntent(...) |
| IntentSources.java:33:20:33:33 | getIntent(...) | IntentSources.java:33:20:33:55 | getStringExtra(...) |
| IntentSources.java:33:20:33:33 | getIntent(...) | IntentSources.java:34:29:34:35 | trouble |
| PlayResource.java:19:37:19:46 | uri | PlayResource.java:19:37:19:46 | uri |
| PlayResource.java:20:18:20:48 | getQueryString(...) | ../../../stubs/playframework-2.6.x/play/mvc/Results.java:634:33:634:42 | url |
| PlayResource.java:20:18:20:48 | getQueryString(...) | PlayResource.java:20:18:20:48 | getQueryString(...) |
| PlayResource.java:20:18:20:48 | getQueryString(...) | PlayResource.java:21:21:21:23 | url |
| PlayResource.java:24:42:24:53 | token | ../../../stubs/playframework-2.6.x/play/mvc/Results.java:94:27:94:40 | content |
| PlayResource.java:24:42:24:53 | token | PlayResource.java:24:42:24:53 | token |
| PlayResource.java:24:42:24:53 | token | PlayResource.java:25:30:25:34 | token |
| PlayResource.java:28:56:28:65 | uri | PlayResource.java:28:56:28:65 | uri |
| RmiFlowImpl.java:4:30:4:40 | path | RmiFlowImpl.java:4:30:4:40 | path |
| RmiFlowImpl.java:4:30:4:40 | path | RmiFlowImpl.java:5:20:5:31 | ... + ... |
| RmiFlowImpl.java:4:30:4:40 | path | RmiFlowImpl.java:5:28:5:31 | path |

View File

@@ -0,0 +1,41 @@
import org.apache.commons.lang3.ObjectUtils;
public class ObjectUtilsTest {
String taint() { return "tainted"; }
private static class IntSource {
static int taint() { return 0; }
}
void sink(Object o) {}
void test() throws Exception {
sink(ObjectUtils.clone(taint())); // $hasValueFlow
sink(ObjectUtils.cloneIfPossible(taint())); // $hasValueFlow
sink(ObjectUtils.CONST(taint())); // $hasValueFlow
sink(ObjectUtils.CONST_SHORT(IntSource.taint())); // $hasValueFlow
sink(ObjectUtils.CONST_BYTE(IntSource.taint())); // $hasValueFlow
sink(ObjectUtils.defaultIfNull(taint(), null)); // $hasValueFlow
sink(ObjectUtils.defaultIfNull(null, taint())); // $hasValueFlow
sink(ObjectUtils.firstNonNull(taint(), null, null)); // $hasTaintFlow $MISSING:hasValueFlow
sink(ObjectUtils.firstNonNull(null, taint(), null)); // $hasTaintFlow $MISSING:hasValueFlow
sink(ObjectUtils.firstNonNull(null, null, taint())); // $hasTaintFlow $MISSING:hasValueFlow
sink(ObjectUtils.getIfNull(taint(), null)); // $hasValueFlow
sink(ObjectUtils.max(taint(), null, null)); // $hasTaintFlow $MISSING:hasValueFlow
sink(ObjectUtils.max(null, taint(), null)); // $hasTaintFlow $MISSING:hasValueFlow
sink(ObjectUtils.max(null, null, taint())); // $hasTaintFlow $MISSING:hasValueFlow
sink(ObjectUtils.median(taint(), null, null)); // $hasTaintFlow $MISSING:hasValueFlow
sink(ObjectUtils.median((String)null, taint(), null)); // $hasTaintFlow $MISSING:hasValueFlow
sink(ObjectUtils.median((String)null, null, taint())); // $hasTaintFlow $MISSING:hasValueFlow
sink(ObjectUtils.min(taint(), null, null)); // $hasTaintFlow $MISSING:hasValueFlow
sink(ObjectUtils.min(null, taint(), null)); // $hasTaintFlow $MISSING:hasValueFlow
sink(ObjectUtils.min(null, null, taint())); // $hasTaintFlow $MISSING:hasValueFlow
sink(ObjectUtils.mode(taint(), null, null)); // $hasTaintFlow $MISSING:hasValueFlow
sink(ObjectUtils.mode(null, taint(), null)); // $hasTaintFlow $MISSING:hasValueFlow
sink(ObjectUtils.mode(null, null, taint())); // $hasTaintFlow $MISSING:hasValueFlow
sink(ObjectUtils.requireNonEmpty(taint(), "message")); // $hasValueFlow
sink(ObjectUtils.requireNonEmpty("not null", taint())); // GOOD (message doesn't propagate to the return)
sink(ObjectUtils.toString(taint(), "default string")); // GOOD (first argument is stringified)
sink(ObjectUtils.toString(null, taint())); // $hasValueFlow
}
}

View File

@@ -0,0 +1,45 @@
import org.apache.commons.lang3.RegExUtils;
import java.util.regex.Pattern;
public class RegExUtilsTest {
String taint() { return "tainted"; }
void sink(Object o) {}
void test() throws Exception {
Pattern cleanPattern = Pattern.compile("clean");
Pattern taintedPattern = Pattern.compile(taint());
sink(RegExUtils.removeAll(taint(), cleanPattern)); // $hasTaintFlow
sink(RegExUtils.removeAll(taint(), "clean")); // $hasTaintFlow
sink(RegExUtils.removeFirst(taint(), cleanPattern)); // $hasTaintFlow
sink(RegExUtils.removeFirst(taint(), "clean")); // $hasTaintFlow
sink(RegExUtils.removePattern(taint(), "clean")); // $hasTaintFlow
sink(RegExUtils.replaceAll(taint(), cleanPattern, "replacement")); // $hasTaintFlow
sink(RegExUtils.replaceAll(taint(), "clean", "replacement")); // $hasTaintFlow
sink(RegExUtils.replaceFirst(taint(), cleanPattern, "replacement")); // $hasTaintFlow
sink(RegExUtils.replaceFirst(taint(), "clean", "replacement")); // $hasTaintFlow
sink(RegExUtils.replacePattern(taint(), "clean", "replacement")); // $hasTaintFlow
sink(RegExUtils.replaceAll("original", cleanPattern, taint())); // $hasTaintFlow
sink(RegExUtils.replaceAll("original", "clean", taint())); // $hasTaintFlow
sink(RegExUtils.replaceFirst("original", cleanPattern, taint())); // $hasTaintFlow
sink(RegExUtils.replaceFirst("original", "clean", taint())); // $hasTaintFlow
sink(RegExUtils.replacePattern("original", "clean", taint())); // $hasTaintFlow
// Subsequent calls don't propagate taint, as regex search patterns don't propagate to the return value.
sink(RegExUtils.removeAll("original", taintedPattern));
sink(RegExUtils.removeAll("original", taint()));
sink(RegExUtils.removeFirst("original", taintedPattern));
sink(RegExUtils.removeFirst("original", taint()));
sink(RegExUtils.removePattern("original", taint()));
sink(RegExUtils.replaceAll("original", taintedPattern, "replacement"));
sink(RegExUtils.replaceAll("original", taint(), "replacement"));
sink(RegExUtils.replaceFirst("original", taintedPattern, "replacement"));
sink(RegExUtils.replaceFirst("original", taint(), "replacement"));
sink(RegExUtils.replacePattern("original", taint(), "replacement"));
sink(RegExUtils.replaceAll("original", taintedPattern, "replacement"));
sink(RegExUtils.replaceAll("original", taint(), "replacement"));
sink(RegExUtils.replaceFirst("original", taintedPattern, "replacement"));
sink(RegExUtils.replaceFirst("original", taint(), "replacement"));
sink(RegExUtils.replacePattern("original", taint(), "replacement"));
}
}

View File

@@ -14,120 +14,120 @@ class StrBuilderTest {
void test() throws Exception {
StrBuilder cons1 = new StrBuilder(taint()); sink(cons1.toString()); // $hasTaintFlow=y
StrBuilder cons1 = new StrBuilder(taint()); sink(cons1.toString()); // $hasTaintFlow
StrBuilder sb1 = new StrBuilder(); sb1.append(taint().toCharArray()); sink(sb1.toString()); // $hasTaintFlow=y
StrBuilder sb2 = new StrBuilder(); sb2.append(taint().toCharArray(), 0, 0); sink(sb2.toString()); // $hasTaintFlow=y
StrBuilder sb3 = new StrBuilder(); sb3.append(CharBuffer.wrap(taint().toCharArray())); sink(sb3.toString()); // $ MISSING: hasTaintFlow=y
StrBuilder sb4 = new StrBuilder(); sb4.append(CharBuffer.wrap(taint().toCharArray()), 0, 0); sink(sb4.toString()); // $ MISSING: hasTaintFlow=y
StrBuilder sb5 = new StrBuilder(); sb5.append((CharSequence)taint()); sink(sb5.toString()); // $hasTaintFlow=y
StrBuilder sb6 = new StrBuilder(); sb6.append((CharSequence)taint(), 0, 0); sink(sb6.toString()); // $hasTaintFlow=y
StrBuilder sb7 = new StrBuilder(); sb7.append((Object)taint()); sink(sb7.toString()); // $hasTaintFlow=y
StrBuilder sb1 = new StrBuilder(); sb1.append(taint().toCharArray()); sink(sb1.toString()); // $hasTaintFlow
StrBuilder sb2 = new StrBuilder(); sb2.append(taint().toCharArray(), 0, 0); sink(sb2.toString()); // $hasTaintFlow
StrBuilder sb3 = new StrBuilder(); sb3.append(CharBuffer.wrap(taint().toCharArray())); sink(sb3.toString()); // $ MISSING: hasTaintFlow
StrBuilder sb4 = new StrBuilder(); sb4.append(CharBuffer.wrap(taint().toCharArray()), 0, 0); sink(sb4.toString()); // $ MISSING: hasTaintFlow
StrBuilder sb5 = new StrBuilder(); sb5.append((CharSequence)taint()); sink(sb5.toString()); // $hasTaintFlow
StrBuilder sb6 = new StrBuilder(); sb6.append((CharSequence)taint(), 0, 0); sink(sb6.toString()); // $hasTaintFlow
StrBuilder sb7 = new StrBuilder(); sb7.append((Object)taint()); sink(sb7.toString()); // $hasTaintFlow
{
StrBuilder auxsb = new StrBuilder(); auxsb.append(taint());
StrBuilder sb8 = new StrBuilder(); sb8.append(auxsb); sink(sb8.toString()); // $hasTaintFlow=y
StrBuilder sb8 = new StrBuilder(); sb8.append(auxsb); sink(sb8.toString()); // $hasTaintFlow
}
StrBuilder sb9 = new StrBuilder(); sb9.append(new StringBuffer(taint())); sink(sb9.toString()); // $hasTaintFlow=y
StrBuilder sb10 = new StrBuilder(); sb10.append(new StringBuffer(taint()), 0, 0); sink(sb10.toString()); // $hasTaintFlow=y
StrBuilder sb11 = new StrBuilder(); sb11.append(new StringBuilder(taint())); sink(sb11.toString()); // $hasTaintFlow=y
StrBuilder sb12 = new StrBuilder(); sb12.append(new StringBuilder(taint()), 0, 0); sink(sb12.toString()); // $hasTaintFlow=y
StrBuilder sb13 = new StrBuilder(); sb13.append(taint()); sink(sb13.toString()); // $hasTaintFlow=y
StrBuilder sb14 = new StrBuilder(); sb14.append(taint(), 0, 0); sink(sb14.toString()); // $hasTaintFlow=y
StrBuilder sb15 = new StrBuilder(); sb15.append(taint(), "format", "args"); sink(sb15.toString()); // $hasTaintFlow=y
StrBuilder sb16 = new StrBuilder(); sb16.append("Format string", taint(), "args"); sink(sb16.toString()); // $hasTaintFlow=y
StrBuilder sb9 = new StrBuilder(); sb9.append(new StringBuffer(taint())); sink(sb9.toString()); // $hasTaintFlow
StrBuilder sb10 = new StrBuilder(); sb10.append(new StringBuffer(taint()), 0, 0); sink(sb10.toString()); // $hasTaintFlow
StrBuilder sb11 = new StrBuilder(); sb11.append(new StringBuilder(taint())); sink(sb11.toString()); // $hasTaintFlow
StrBuilder sb12 = new StrBuilder(); sb12.append(new StringBuilder(taint()), 0, 0); sink(sb12.toString()); // $hasTaintFlow
StrBuilder sb13 = new StrBuilder(); sb13.append(taint()); sink(sb13.toString()); // $hasTaintFlow
StrBuilder sb14 = new StrBuilder(); sb14.append(taint(), 0, 0); sink(sb14.toString()); // $hasTaintFlow
StrBuilder sb15 = new StrBuilder(); sb15.append(taint(), "format", "args"); sink(sb15.toString()); // $hasTaintFlow
StrBuilder sb16 = new StrBuilder(); sb16.append("Format string", taint(), "args"); sink(sb16.toString()); // $hasTaintFlow
{
List<String> taintedList = new ArrayList<>();
taintedList.add(taint());
StrBuilder sb17 = new StrBuilder(); sb17.appendAll(taintedList); sink(sb17.toString()); // $hasTaintFlow=y
StrBuilder sb18 = new StrBuilder(); sb18.appendAll(taintedList.iterator()); sink(sb18.toString()); // $hasTaintFlow=y
StrBuilder sb17 = new StrBuilder(); sb17.appendAll(taintedList); sink(sb17.toString()); // $hasTaintFlow
StrBuilder sb18 = new StrBuilder(); sb18.appendAll(taintedList.iterator()); sink(sb18.toString()); // $hasTaintFlow
}
StrBuilder sb19 = new StrBuilder(); sb19.appendAll("clean", taint()); sink(sb19.toString()); // $hasTaintFlow=y
StrBuilder sb20 = new StrBuilder(); sb20.appendAll(taint(), "clean"); sink(sb20.toString()); // $hasTaintFlow=y
StrBuilder sb21 = new StrBuilder(); sb21.appendFixedWidthPadLeft(taint(), 0, ' '); sink(sb21.toString()); // $hasTaintFlow=y
StrBuilder sb22 = new StrBuilder(); sb22.appendFixedWidthPadRight(taint(), 0, ' '); sink(sb22.toString()); // $hasTaintFlow=y
StrBuilder sb23 = new StrBuilder(); sb23.appendln(taint().toCharArray()); sink(sb23.toString()); // $hasTaintFlow=y
StrBuilder sb24 = new StrBuilder(); sb24.appendln(taint().toCharArray(), 0, 0); sink(sb24.toString()); // $hasTaintFlow=y
StrBuilder sb25 = new StrBuilder(); sb25.appendln((Object)taint()); sink(sb25.toString()); // $hasTaintFlow=y
StrBuilder sb19 = new StrBuilder(); sb19.appendAll("clean", taint()); sink(sb19.toString()); // $hasTaintFlow
StrBuilder sb20 = new StrBuilder(); sb20.appendAll(taint(), "clean"); sink(sb20.toString()); // $hasTaintFlow
StrBuilder sb21 = new StrBuilder(); sb21.appendFixedWidthPadLeft(taint(), 0, ' '); sink(sb21.toString()); // $hasTaintFlow
StrBuilder sb22 = new StrBuilder(); sb22.appendFixedWidthPadRight(taint(), 0, ' '); sink(sb22.toString()); // $hasTaintFlow
StrBuilder sb23 = new StrBuilder(); sb23.appendln(taint().toCharArray()); sink(sb23.toString()); // $hasTaintFlow
StrBuilder sb24 = new StrBuilder(); sb24.appendln(taint().toCharArray(), 0, 0); sink(sb24.toString()); // $hasTaintFlow
StrBuilder sb25 = new StrBuilder(); sb25.appendln((Object)taint()); sink(sb25.toString()); // $hasTaintFlow
{
StrBuilder auxsb = new StrBuilder(); auxsb.appendln(taint());
StrBuilder sb26 = new StrBuilder(); sb26.appendln(auxsb); sink(sb26.toString()); // $hasTaintFlow=y
StrBuilder sb26 = new StrBuilder(); sb26.appendln(auxsb); sink(sb26.toString()); // $hasTaintFlow
}
StrBuilder sb27 = new StrBuilder(); sb27.appendln(new StringBuffer(taint())); sink(sb27.toString()); // $hasTaintFlow=y
StrBuilder sb28 = new StrBuilder(); sb28.appendln(new StringBuffer(taint()), 0, 0); sink(sb28.toString()); // $hasTaintFlow=y
StrBuilder sb29 = new StrBuilder(); sb29.appendln(new StringBuilder(taint())); sink(sb29.toString()); // $hasTaintFlow=y
StrBuilder sb30 = new StrBuilder(); sb30.appendln(new StringBuilder(taint()), 0, 0); sink(sb30.toString()); // $hasTaintFlow=y
StrBuilder sb31 = new StrBuilder(); sb31.appendln(taint()); sink(sb31.toString()); // $hasTaintFlow=y
StrBuilder sb32 = new StrBuilder(); sb32.appendln(taint(), 0, 0); sink(sb32.toString()); // $hasTaintFlow=y
StrBuilder sb33 = new StrBuilder(); sb33.appendln(taint(), "format", "args"); sink(sb33.toString()); // $hasTaintFlow=y
StrBuilder sb34 = new StrBuilder(); sb34.appendln("Format string", taint(), "args"); sink(sb34.toString()); // $hasTaintFlow=y
StrBuilder sb35 = new StrBuilder(); sb35.appendSeparator(taint()); sink(sb35.toString()); // $hasTaintFlow=y
StrBuilder sb36 = new StrBuilder(); sb36.appendSeparator(taint(), 0); sink(sb36.toString()); // $hasTaintFlow=y
StrBuilder sb37 = new StrBuilder(); sb37.appendSeparator(taint(), "default"); sink(sb37.toString()); // $hasTaintFlow=y
StrBuilder sb38 = new StrBuilder(); sb38.appendSeparator("", taint()); sink(sb38.toString()); // $hasTaintFlow=y
StrBuilder sb27 = new StrBuilder(); sb27.appendln(new StringBuffer(taint())); sink(sb27.toString()); // $hasTaintFlow
StrBuilder sb28 = new StrBuilder(); sb28.appendln(new StringBuffer(taint()), 0, 0); sink(sb28.toString()); // $hasTaintFlow
StrBuilder sb29 = new StrBuilder(); sb29.appendln(new StringBuilder(taint())); sink(sb29.toString()); // $hasTaintFlow
StrBuilder sb30 = new StrBuilder(); sb30.appendln(new StringBuilder(taint()), 0, 0); sink(sb30.toString()); // $hasTaintFlow
StrBuilder sb31 = new StrBuilder(); sb31.appendln(taint()); sink(sb31.toString()); // $hasTaintFlow
StrBuilder sb32 = new StrBuilder(); sb32.appendln(taint(), 0, 0); sink(sb32.toString()); // $hasTaintFlow
StrBuilder sb33 = new StrBuilder(); sb33.appendln(taint(), "format", "args"); sink(sb33.toString()); // $hasTaintFlow
StrBuilder sb34 = new StrBuilder(); sb34.appendln("Format string", taint(), "args"); sink(sb34.toString()); // $hasTaintFlow
StrBuilder sb35 = new StrBuilder(); sb35.appendSeparator(taint()); sink(sb35.toString()); // $hasTaintFlow
StrBuilder sb36 = new StrBuilder(); sb36.appendSeparator(taint(), 0); sink(sb36.toString()); // $hasTaintFlow
StrBuilder sb37 = new StrBuilder(); sb37.appendSeparator(taint(), "default"); sink(sb37.toString()); // $hasTaintFlow
StrBuilder sb38 = new StrBuilder(); sb38.appendSeparator("", taint()); sink(sb38.toString()); // $hasTaintFlow
{
StrBuilder auxsb = new StrBuilder(); auxsb.appendln(taint());
StrBuilder sb39 = new StrBuilder(); auxsb.appendTo(sb39); sink(sb39.toString()); // $hasTaintFlow=y
StrBuilder sb39 = new StrBuilder(); auxsb.appendTo(sb39); sink(sb39.toString()); // $hasTaintFlow
}
{
List<String> taintedList = new ArrayList<>();
taintedList.add(taint());
StrBuilder sb40 = new StrBuilder(); sb40.appendWithSeparators(taintedList, ", "); sink(sb40.toString()); // $hasTaintFlow=y
StrBuilder sb41 = new StrBuilder(); sb41.appendWithSeparators(taintedList.iterator(), ", "); sink(sb41.toString()); // $hasTaintFlow=y
StrBuilder sb40 = new StrBuilder(); sb40.appendWithSeparators(taintedList, ", "); sink(sb40.toString()); // $hasTaintFlow
StrBuilder sb41 = new StrBuilder(); sb41.appendWithSeparators(taintedList.iterator(), ", "); sink(sb41.toString()); // $hasTaintFlow
List<String> untaintedList = new ArrayList<>();
StrBuilder sb42 = new StrBuilder(); sb42.appendWithSeparators(untaintedList, taint()); sink(sb42.toString()); // $hasTaintFlow=y
StrBuilder sb43 = new StrBuilder(); sb43.appendWithSeparators(untaintedList.iterator(), taint()); sink(sb43.toString()); // $hasTaintFlow=y
StrBuilder sb42 = new StrBuilder(); sb42.appendWithSeparators(untaintedList, taint()); sink(sb42.toString()); // $hasTaintFlow
StrBuilder sb43 = new StrBuilder(); sb43.appendWithSeparators(untaintedList.iterator(), taint()); sink(sb43.toString()); // $hasTaintFlow
String[] taintedArray = new String[] { taint() };
String[] untaintedArray = new String[] {};
StrBuilder sb44 = new StrBuilder(); sb44.appendWithSeparators(taintedArray, ", "); sink(sb44.toString()); // $hasTaintFlow=y
StrBuilder sb45 = new StrBuilder(); sb45.appendWithSeparators(untaintedArray, taint()); sink(sb45.toString()); // $hasTaintFlow=y
StrBuilder sb44 = new StrBuilder(); sb44.appendWithSeparators(taintedArray, ", "); sink(sb44.toString()); // $hasTaintFlow
StrBuilder sb45 = new StrBuilder(); sb45.appendWithSeparators(untaintedArray, taint()); sink(sb45.toString()); // $hasTaintFlow
}
{
StrBuilder sb46 = new StrBuilder(); sb46.append(taint());
char[] target = new char[100];
sb46.asReader().read(target);
sink(target); // $hasTaintFlow=y
sink(target); // $hasTaintFlow
}
StrBuilder sb47 = new StrBuilder(); sb47.append(taint()); sink(sb47.asTokenizer().next()); // $hasTaintFlow=y
StrBuilder sb48 = new StrBuilder(); sb48.append(taint()); sink(sb48.build()); // $hasTaintFlow=y
StrBuilder sb49 = new StrBuilder(); sb49.append(taint()); sink(sb49.getChars(null)); // $hasTaintFlow=y
StrBuilder sb47 = new StrBuilder(); sb47.append(taint()); sink(sb47.asTokenizer().next()); // $hasTaintFlow
StrBuilder sb48 = new StrBuilder(); sb48.append(taint()); sink(sb48.build()); // $hasTaintFlow
StrBuilder sb49 = new StrBuilder(); sb49.append(taint()); sink(sb49.getChars(null)); // $hasTaintFlow
{
StrBuilder sb50 = new StrBuilder(); sb50.append(taint());
char[] target = new char[100];
sb50.getChars(target);
sink(target); // $hasTaintFlow=y
sink(target); // $hasTaintFlow
}
{
StrBuilder sb51 = new StrBuilder(); sb51.append(taint());
char[] target = new char[100];
sb51.getChars(0, 0, target, 0);
sink(target); // $hasTaintFlow=y
sink(target); // $hasTaintFlow
}
StrBuilder sb52 = new StrBuilder(); sb52.insert(0, taint().toCharArray()); sink(sb52.toString()); // $hasTaintFlow=y
StrBuilder sb53 = new StrBuilder(); sb53.insert(0, taint().toCharArray(), 0, 0); sink(sb53.toString()); // $hasTaintFlow=y
StrBuilder sb54 = new StrBuilder(); sb54.insert(0, taint()); sink(sb54.toString()); // $hasTaintFlow=y
StrBuilder sb55 = new StrBuilder(); sb55.insert(0, (Object)taint()); sink(sb55.toString()); // $hasTaintFlow=y
StrBuilder sb56 = new StrBuilder(); sb56.append(taint()); sink(sb56.leftString(0)); // $hasTaintFlow=y
StrBuilder sb57 = new StrBuilder(); sb57.append(taint()); sink(sb57.midString(0, 0)); // $hasTaintFlow=y
StrBuilder sb52 = new StrBuilder(); sb52.insert(0, taint().toCharArray()); sink(sb52.toString()); // $hasTaintFlow
StrBuilder sb53 = new StrBuilder(); sb53.insert(0, taint().toCharArray(), 0, 0); sink(sb53.toString()); // $hasTaintFlow
StrBuilder sb54 = new StrBuilder(); sb54.insert(0, taint()); sink(sb54.toString()); // $hasTaintFlow
StrBuilder sb55 = new StrBuilder(); sb55.insert(0, (Object)taint()); sink(sb55.toString()); // $hasTaintFlow
StrBuilder sb56 = new StrBuilder(); sb56.append(taint()); sink(sb56.leftString(0)); // $hasTaintFlow
StrBuilder sb57 = new StrBuilder(); sb57.append(taint()); sink(sb57.midString(0, 0)); // $hasTaintFlow
{
StringReader reader = new StringReader(taint());
StrBuilder sb58 = new StrBuilder(); sb58.readFrom(reader); sink(sb58.toString()); // $hasTaintFlow=y
StrBuilder sb58 = new StrBuilder(); sb58.readFrom(reader); sink(sb58.toString()); // $hasTaintFlow
}
StrBuilder sb59 = new StrBuilder(); sb59.replace(0, 0, taint()); sink(sb59.toString()); // $hasTaintFlow=y
StrBuilder sb60 = new StrBuilder(); sb60.replace(null, taint(), 0, 0, 0); sink(sb60.toString()); // $hasTaintFlow=y
StrBuilder sb61 = new StrBuilder(); sb61.replaceAll((StrMatcher)null, taint()); sink(sb61.toString()); // $hasTaintFlow=y
StrBuilder sb62 = new StrBuilder(); sb62.replaceAll("search", taint()); sink(sb62.toString()); // $hasTaintFlow=y
StrBuilder sb59 = new StrBuilder(); sb59.replace(0, 0, taint()); sink(sb59.toString()); // $hasTaintFlow
StrBuilder sb60 = new StrBuilder(); sb60.replace(null, taint(), 0, 0, 0); sink(sb60.toString()); // $hasTaintFlow
StrBuilder sb61 = new StrBuilder(); sb61.replaceAll((StrMatcher)null, taint()); sink(sb61.toString()); // $hasTaintFlow
StrBuilder sb62 = new StrBuilder(); sb62.replaceAll("search", taint()); sink(sb62.toString()); // $hasTaintFlow
StrBuilder sb63 = new StrBuilder(); sb63.replaceAll(taint(), "replace"); sink(sb63.toString()); // GOOD (search string doesn't convey taint)
StrBuilder sb64 = new StrBuilder(); sb64.replaceFirst((StrMatcher)null, taint()); sink(sb64.toString()); // $hasTaintFlow=y
StrBuilder sb65 = new StrBuilder(); sb65.replaceFirst("search", taint()); sink(sb65.toString()); // $hasTaintFlow=y
StrBuilder sb64 = new StrBuilder(); sb64.replaceFirst((StrMatcher)null, taint()); sink(sb64.toString()); // $hasTaintFlow
StrBuilder sb65 = new StrBuilder(); sb65.replaceFirst("search", taint()); sink(sb65.toString()); // $hasTaintFlow
StrBuilder sb66 = new StrBuilder(); sb66.replaceFirst(taint(), "replace"); sink(sb66.toString()); // GOOD (search string doesn't convey taint)
StrBuilder sb67 = new StrBuilder(); sb67.append(taint()); sink(sb67.rightString(0)); // $hasTaintFlow=y
StrBuilder sb68 = new StrBuilder(); sb68.append(taint()); sink(sb68.subSequence(0, 0)); // $hasTaintFlow=y
StrBuilder sb69 = new StrBuilder(); sb69.append(taint()); sink(sb69.substring(0)); // $hasTaintFlow=y
StrBuilder sb70 = new StrBuilder(); sb70.append(taint()); sink(sb70.substring(0, 0)); // $hasTaintFlow=y
StrBuilder sb71 = new StrBuilder(); sb71.append(taint()); sink(sb71.toCharArray()); // $hasTaintFlow=y
StrBuilder sb72 = new StrBuilder(); sb72.append(taint()); sink(sb72.toCharArray(0, 0)); // $hasTaintFlow=y
StrBuilder sb73 = new StrBuilder(); sb73.append(taint()); sink(sb73.toStringBuffer()); // $hasTaintFlow=y
StrBuilder sb74 = new StrBuilder(); sb74.append(taint()); sink(sb74.toStringBuilder()); // $hasTaintFlow=y
StrBuilder sb67 = new StrBuilder(); sb67.append(taint()); sink(sb67.rightString(0)); // $hasTaintFlow
StrBuilder sb68 = new StrBuilder(); sb68.append(taint()); sink(sb68.subSequence(0, 0)); // $hasTaintFlow
StrBuilder sb69 = new StrBuilder(); sb69.append(taint()); sink(sb69.substring(0)); // $hasTaintFlow
StrBuilder sb70 = new StrBuilder(); sb70.append(taint()); sink(sb70.substring(0, 0)); // $hasTaintFlow
StrBuilder sb71 = new StrBuilder(); sb71.append(taint()); sink(sb71.toCharArray()); // $hasTaintFlow
StrBuilder sb72 = new StrBuilder(); sb72.append(taint()); sink(sb72.toCharArray(0, 0)); // $hasTaintFlow
StrBuilder sb73 = new StrBuilder(); sb73.append(taint()); sink(sb73.toStringBuffer()); // $hasTaintFlow
StrBuilder sb74 = new StrBuilder(); sb74.append(taint()); sink(sb74.toStringBuilder()); // $hasTaintFlow
}
}

View File

@@ -14,120 +14,120 @@ class StrBuilderTextTest {
void test() throws Exception {
StrBuilder cons1 = new StrBuilder(taint()); sink(cons1.toString()); // $hasTaintFlow=y
StrBuilder cons1 = new StrBuilder(taint()); sink(cons1.toString()); // $hasTaintFlow
StrBuilder sb1 = new StrBuilder(); sb1.append(taint().toCharArray()); sink(sb1.toString()); // $hasTaintFlow=y
StrBuilder sb2 = new StrBuilder(); sb2.append(taint().toCharArray(), 0, 0); sink(sb2.toString()); // $hasTaintFlow=y
StrBuilder sb3 = new StrBuilder(); sb3.append(CharBuffer.wrap(taint().toCharArray())); sink(sb3.toString()); // $ MISSING: hasTaintFlow=y
StrBuilder sb4 = new StrBuilder(); sb4.append(CharBuffer.wrap(taint().toCharArray()), 0, 0); sink(sb4.toString()); // $ MISSING: hasTaintFlow=y
StrBuilder sb5 = new StrBuilder(); sb5.append((CharSequence)taint()); sink(sb5.toString()); // $hasTaintFlow=y
StrBuilder sb6 = new StrBuilder(); sb6.append((CharSequence)taint(), 0, 0); sink(sb6.toString()); // $hasTaintFlow=y
StrBuilder sb7 = new StrBuilder(); sb7.append((Object)taint()); sink(sb7.toString()); // $hasTaintFlow=y
StrBuilder sb1 = new StrBuilder(); sb1.append(taint().toCharArray()); sink(sb1.toString()); // $hasTaintFlow
StrBuilder sb2 = new StrBuilder(); sb2.append(taint().toCharArray(), 0, 0); sink(sb2.toString()); // $hasTaintFlow
StrBuilder sb3 = new StrBuilder(); sb3.append(CharBuffer.wrap(taint().toCharArray())); sink(sb3.toString()); // $ MISSING: hasTaintFlow
StrBuilder sb4 = new StrBuilder(); sb4.append(CharBuffer.wrap(taint().toCharArray()), 0, 0); sink(sb4.toString()); // $ MISSING: hasTaintFlow
StrBuilder sb5 = new StrBuilder(); sb5.append((CharSequence)taint()); sink(sb5.toString()); // $hasTaintFlow
StrBuilder sb6 = new StrBuilder(); sb6.append((CharSequence)taint(), 0, 0); sink(sb6.toString()); // $hasTaintFlow
StrBuilder sb7 = new StrBuilder(); sb7.append((Object)taint()); sink(sb7.toString()); // $hasTaintFlow
{
StrBuilder auxsb = new StrBuilder(); auxsb.append(taint());
StrBuilder sb8 = new StrBuilder(); sb8.append(auxsb); sink(sb8.toString()); // $hasTaintFlow=y
StrBuilder sb8 = new StrBuilder(); sb8.append(auxsb); sink(sb8.toString()); // $hasTaintFlow
}
StrBuilder sb9 = new StrBuilder(); sb9.append(new StringBuffer(taint())); sink(sb9.toString()); // $hasTaintFlow=y
StrBuilder sb10 = new StrBuilder(); sb10.append(new StringBuffer(taint()), 0, 0); sink(sb10.toString()); // $hasTaintFlow=y
StrBuilder sb11 = new StrBuilder(); sb11.append(new StringBuilder(taint())); sink(sb11.toString()); // $hasTaintFlow=y
StrBuilder sb12 = new StrBuilder(); sb12.append(new StringBuilder(taint()), 0, 0); sink(sb12.toString()); // $hasTaintFlow=y
StrBuilder sb13 = new StrBuilder(); sb13.append(taint()); sink(sb13.toString()); // $hasTaintFlow=y
StrBuilder sb14 = new StrBuilder(); sb14.append(taint(), 0, 0); sink(sb14.toString()); // $hasTaintFlow=y
StrBuilder sb15 = new StrBuilder(); sb15.append(taint(), "format", "args"); sink(sb15.toString()); // $hasTaintFlow=y
StrBuilder sb16 = new StrBuilder(); sb16.append("Format string", taint(), "args"); sink(sb16.toString()); // $hasTaintFlow=y
StrBuilder sb9 = new StrBuilder(); sb9.append(new StringBuffer(taint())); sink(sb9.toString()); // $hasTaintFlow
StrBuilder sb10 = new StrBuilder(); sb10.append(new StringBuffer(taint()), 0, 0); sink(sb10.toString()); // $hasTaintFlow
StrBuilder sb11 = new StrBuilder(); sb11.append(new StringBuilder(taint())); sink(sb11.toString()); // $hasTaintFlow
StrBuilder sb12 = new StrBuilder(); sb12.append(new StringBuilder(taint()), 0, 0); sink(sb12.toString()); // $hasTaintFlow
StrBuilder sb13 = new StrBuilder(); sb13.append(taint()); sink(sb13.toString()); // $hasTaintFlow
StrBuilder sb14 = new StrBuilder(); sb14.append(taint(), 0, 0); sink(sb14.toString()); // $hasTaintFlow
StrBuilder sb15 = new StrBuilder(); sb15.append(taint(), "format", "args"); sink(sb15.toString()); // $hasTaintFlow
StrBuilder sb16 = new StrBuilder(); sb16.append("Format string", taint(), "args"); sink(sb16.toString()); // $hasTaintFlow
{
List<String> taintedList = new ArrayList<>();
taintedList.add(taint());
StrBuilder sb17 = new StrBuilder(); sb17.appendAll(taintedList); sink(sb17.toString()); // $hasTaintFlow=y
StrBuilder sb18 = new StrBuilder(); sb18.appendAll(taintedList.iterator()); sink(sb18.toString()); // $hasTaintFlow=y
StrBuilder sb17 = new StrBuilder(); sb17.appendAll(taintedList); sink(sb17.toString()); // $hasTaintFlow
StrBuilder sb18 = new StrBuilder(); sb18.appendAll(taintedList.iterator()); sink(sb18.toString()); // $hasTaintFlow
}
StrBuilder sb19 = new StrBuilder(); sb19.appendAll("clean", taint()); sink(sb19.toString()); // $hasTaintFlow=y
StrBuilder sb20 = new StrBuilder(); sb20.appendAll(taint(), "clean"); sink(sb20.toString()); // $hasTaintFlow=y
StrBuilder sb21 = new StrBuilder(); sb21.appendFixedWidthPadLeft(taint(), 0, ' '); sink(sb21.toString()); // $hasTaintFlow=y
StrBuilder sb22 = new StrBuilder(); sb22.appendFixedWidthPadRight(taint(), 0, ' '); sink(sb22.toString()); // $hasTaintFlow=y
StrBuilder sb23 = new StrBuilder(); sb23.appendln(taint().toCharArray()); sink(sb23.toString()); // $hasTaintFlow=y
StrBuilder sb24 = new StrBuilder(); sb24.appendln(taint().toCharArray(), 0, 0); sink(sb24.toString()); // $hasTaintFlow=y
StrBuilder sb25 = new StrBuilder(); sb25.appendln((Object)taint()); sink(sb25.toString()); // $hasTaintFlow=y
StrBuilder sb19 = new StrBuilder(); sb19.appendAll("clean", taint()); sink(sb19.toString()); // $hasTaintFlow
StrBuilder sb20 = new StrBuilder(); sb20.appendAll(taint(), "clean"); sink(sb20.toString()); // $hasTaintFlow
StrBuilder sb21 = new StrBuilder(); sb21.appendFixedWidthPadLeft(taint(), 0, ' '); sink(sb21.toString()); // $hasTaintFlow
StrBuilder sb22 = new StrBuilder(); sb22.appendFixedWidthPadRight(taint(), 0, ' '); sink(sb22.toString()); // $hasTaintFlow
StrBuilder sb23 = new StrBuilder(); sb23.appendln(taint().toCharArray()); sink(sb23.toString()); // $hasTaintFlow
StrBuilder sb24 = new StrBuilder(); sb24.appendln(taint().toCharArray(), 0, 0); sink(sb24.toString()); // $hasTaintFlow
StrBuilder sb25 = new StrBuilder(); sb25.appendln((Object)taint()); sink(sb25.toString()); // $hasTaintFlow
{
StrBuilder auxsb = new StrBuilder(); auxsb.appendln(taint());
StrBuilder sb26 = new StrBuilder(); sb26.appendln(auxsb); sink(sb26.toString()); // $hasTaintFlow=y
StrBuilder sb26 = new StrBuilder(); sb26.appendln(auxsb); sink(sb26.toString()); // $hasTaintFlow
}
StrBuilder sb27 = new StrBuilder(); sb27.appendln(new StringBuffer(taint())); sink(sb27.toString()); // $hasTaintFlow=y
StrBuilder sb28 = new StrBuilder(); sb28.appendln(new StringBuffer(taint()), 0, 0); sink(sb28.toString()); // $hasTaintFlow=y
StrBuilder sb29 = new StrBuilder(); sb29.appendln(new StringBuilder(taint())); sink(sb29.toString()); // $hasTaintFlow=y
StrBuilder sb30 = new StrBuilder(); sb30.appendln(new StringBuilder(taint()), 0, 0); sink(sb30.toString()); // $hasTaintFlow=y
StrBuilder sb31 = new StrBuilder(); sb31.appendln(taint()); sink(sb31.toString()); // $hasTaintFlow=y
StrBuilder sb32 = new StrBuilder(); sb32.appendln(taint(), 0, 0); sink(sb32.toString()); // $hasTaintFlow=y
StrBuilder sb33 = new StrBuilder(); sb33.appendln(taint(), "format", "args"); sink(sb33.toString()); // $hasTaintFlow=y
StrBuilder sb34 = new StrBuilder(); sb34.appendln("Format string", taint(), "args"); sink(sb34.toString()); // $hasTaintFlow=y
StrBuilder sb35 = new StrBuilder(); sb35.appendSeparator(taint()); sink(sb35.toString()); // $hasTaintFlow=y
StrBuilder sb36 = new StrBuilder(); sb36.appendSeparator(taint(), 0); sink(sb36.toString()); // $hasTaintFlow=y
StrBuilder sb37 = new StrBuilder(); sb37.appendSeparator(taint(), "default"); sink(sb37.toString()); // $hasTaintFlow=y
StrBuilder sb38 = new StrBuilder(); sb38.appendSeparator("", taint()); sink(sb38.toString()); // $hasTaintFlow=y
StrBuilder sb27 = new StrBuilder(); sb27.appendln(new StringBuffer(taint())); sink(sb27.toString()); // $hasTaintFlow
StrBuilder sb28 = new StrBuilder(); sb28.appendln(new StringBuffer(taint()), 0, 0); sink(sb28.toString()); // $hasTaintFlow
StrBuilder sb29 = new StrBuilder(); sb29.appendln(new StringBuilder(taint())); sink(sb29.toString()); // $hasTaintFlow
StrBuilder sb30 = new StrBuilder(); sb30.appendln(new StringBuilder(taint()), 0, 0); sink(sb30.toString()); // $hasTaintFlow
StrBuilder sb31 = new StrBuilder(); sb31.appendln(taint()); sink(sb31.toString()); // $hasTaintFlow
StrBuilder sb32 = new StrBuilder(); sb32.appendln(taint(), 0, 0); sink(sb32.toString()); // $hasTaintFlow
StrBuilder sb33 = new StrBuilder(); sb33.appendln(taint(), "format", "args"); sink(sb33.toString()); // $hasTaintFlow
StrBuilder sb34 = new StrBuilder(); sb34.appendln("Format string", taint(), "args"); sink(sb34.toString()); // $hasTaintFlow
StrBuilder sb35 = new StrBuilder(); sb35.appendSeparator(taint()); sink(sb35.toString()); // $hasTaintFlow
StrBuilder sb36 = new StrBuilder(); sb36.appendSeparator(taint(), 0); sink(sb36.toString()); // $hasTaintFlow
StrBuilder sb37 = new StrBuilder(); sb37.appendSeparator(taint(), "default"); sink(sb37.toString()); // $hasTaintFlow
StrBuilder sb38 = new StrBuilder(); sb38.appendSeparator("", taint()); sink(sb38.toString()); // $hasTaintFlow
{
StrBuilder auxsb = new StrBuilder(); auxsb.appendln(taint());
StrBuilder sb39 = new StrBuilder(); auxsb.appendTo(sb39); sink(sb39.toString()); // $hasTaintFlow=y
StrBuilder sb39 = new StrBuilder(); auxsb.appendTo(sb39); sink(sb39.toString()); // $hasTaintFlow
}
{
List<String> taintedList = new ArrayList<>();
taintedList.add(taint());
StrBuilder sb40 = new StrBuilder(); sb40.appendWithSeparators(taintedList, ", "); sink(sb40.toString()); // $hasTaintFlow=y
StrBuilder sb41 = new StrBuilder(); sb41.appendWithSeparators(taintedList.iterator(), ", "); sink(sb41.toString()); // $hasTaintFlow=y
StrBuilder sb40 = new StrBuilder(); sb40.appendWithSeparators(taintedList, ", "); sink(sb40.toString()); // $hasTaintFlow
StrBuilder sb41 = new StrBuilder(); sb41.appendWithSeparators(taintedList.iterator(), ", "); sink(sb41.toString()); // $hasTaintFlow
List<String> untaintedList = new ArrayList<>();
StrBuilder sb42 = new StrBuilder(); sb42.appendWithSeparators(untaintedList, taint()); sink(sb42.toString()); // $hasTaintFlow=y
StrBuilder sb43 = new StrBuilder(); sb43.appendWithSeparators(untaintedList.iterator(), taint()); sink(sb43.toString()); // $hasTaintFlow=y
StrBuilder sb42 = new StrBuilder(); sb42.appendWithSeparators(untaintedList, taint()); sink(sb42.toString()); // $hasTaintFlow
StrBuilder sb43 = new StrBuilder(); sb43.appendWithSeparators(untaintedList.iterator(), taint()); sink(sb43.toString()); // $hasTaintFlow
String[] taintedArray = new String[] { taint() };
String[] untaintedArray = new String[] {};
StrBuilder sb44 = new StrBuilder(); sb44.appendWithSeparators(taintedArray, ", "); sink(sb44.toString()); // $hasTaintFlow=y
StrBuilder sb45 = new StrBuilder(); sb45.appendWithSeparators(untaintedArray, taint()); sink(sb45.toString()); // $hasTaintFlow=y
StrBuilder sb44 = new StrBuilder(); sb44.appendWithSeparators(taintedArray, ", "); sink(sb44.toString()); // $hasTaintFlow
StrBuilder sb45 = new StrBuilder(); sb45.appendWithSeparators(untaintedArray, taint()); sink(sb45.toString()); // $hasTaintFlow
}
{
StrBuilder sb46 = new StrBuilder(); sb46.append(taint());
char[] target = new char[100];
sb46.asReader().read(target);
sink(target); // $hasTaintFlow=y
sink(target); // $hasTaintFlow
}
StrBuilder sb47 = new StrBuilder(); sb47.append(taint()); sink(sb47.asTokenizer().next()); // $hasTaintFlow=y
StrBuilder sb48 = new StrBuilder(); sb48.append(taint()); sink(sb48.build()); // $hasTaintFlow=y
StrBuilder sb49 = new StrBuilder(); sb49.append(taint()); sink(sb49.getChars(null)); // $hasTaintFlow=y
StrBuilder sb47 = new StrBuilder(); sb47.append(taint()); sink(sb47.asTokenizer().next()); // $hasTaintFlow
StrBuilder sb48 = new StrBuilder(); sb48.append(taint()); sink(sb48.build()); // $hasTaintFlow
StrBuilder sb49 = new StrBuilder(); sb49.append(taint()); sink(sb49.getChars(null)); // $hasTaintFlow
{
StrBuilder sb50 = new StrBuilder(); sb50.append(taint());
char[] target = new char[100];
sb50.getChars(target);
sink(target); // $hasTaintFlow=y
sink(target); // $hasTaintFlow
}
{
StrBuilder sb51 = new StrBuilder(); sb51.append(taint());
char[] target = new char[100];
sb51.getChars(0, 0, target, 0);
sink(target); // $hasTaintFlow=y
sink(target); // $hasTaintFlow
}
StrBuilder sb52 = new StrBuilder(); sb52.insert(0, taint().toCharArray()); sink(sb52.toString()); // $hasTaintFlow=y
StrBuilder sb53 = new StrBuilder(); sb53.insert(0, taint().toCharArray(), 0, 0); sink(sb53.toString()); // $hasTaintFlow=y
StrBuilder sb54 = new StrBuilder(); sb54.insert(0, taint()); sink(sb54.toString()); // $hasTaintFlow=y
StrBuilder sb55 = new StrBuilder(); sb55.insert(0, (Object)taint()); sink(sb55.toString()); // $hasTaintFlow=y
StrBuilder sb56 = new StrBuilder(); sb56.append(taint()); sink(sb56.leftString(0)); // $hasTaintFlow=y
StrBuilder sb57 = new StrBuilder(); sb57.append(taint()); sink(sb57.midString(0, 0)); // $hasTaintFlow=y
StrBuilder sb52 = new StrBuilder(); sb52.insert(0, taint().toCharArray()); sink(sb52.toString()); // $hasTaintFlow
StrBuilder sb53 = new StrBuilder(); sb53.insert(0, taint().toCharArray(), 0, 0); sink(sb53.toString()); // $hasTaintFlow
StrBuilder sb54 = new StrBuilder(); sb54.insert(0, taint()); sink(sb54.toString()); // $hasTaintFlow
StrBuilder sb55 = new StrBuilder(); sb55.insert(0, (Object)taint()); sink(sb55.toString()); // $hasTaintFlow
StrBuilder sb56 = new StrBuilder(); sb56.append(taint()); sink(sb56.leftString(0)); // $hasTaintFlow
StrBuilder sb57 = new StrBuilder(); sb57.append(taint()); sink(sb57.midString(0, 0)); // $hasTaintFlow
{
StringReader reader = new StringReader(taint());
StrBuilder sb58 = new StrBuilder(); sb58.readFrom(reader); sink(sb58.toString()); // $hasTaintFlow=y
StrBuilder sb58 = new StrBuilder(); sb58.readFrom(reader); sink(sb58.toString()); // $hasTaintFlow
}
StrBuilder sb59 = new StrBuilder(); sb59.replace(0, 0, taint()); sink(sb59.toString()); // $hasTaintFlow=y
StrBuilder sb60 = new StrBuilder(); sb60.replace(null, taint(), 0, 0, 0); sink(sb60.toString()); // $hasTaintFlow=y
StrBuilder sb61 = new StrBuilder(); sb61.replaceAll((StrMatcher)null, taint()); sink(sb61.toString()); // $hasTaintFlow=y
StrBuilder sb62 = new StrBuilder(); sb62.replaceAll("search", taint()); sink(sb62.toString()); // $hasTaintFlow=y
StrBuilder sb59 = new StrBuilder(); sb59.replace(0, 0, taint()); sink(sb59.toString()); // $hasTaintFlow
StrBuilder sb60 = new StrBuilder(); sb60.replace(null, taint(), 0, 0, 0); sink(sb60.toString()); // $hasTaintFlow
StrBuilder sb61 = new StrBuilder(); sb61.replaceAll((StrMatcher)null, taint()); sink(sb61.toString()); // $hasTaintFlow
StrBuilder sb62 = new StrBuilder(); sb62.replaceAll("search", taint()); sink(sb62.toString()); // $hasTaintFlow
StrBuilder sb63 = new StrBuilder(); sb63.replaceAll(taint(), "replace"); sink(sb63.toString()); // GOOD (search string doesn't convey taint)
StrBuilder sb64 = new StrBuilder(); sb64.replaceFirst((StrMatcher)null, taint()); sink(sb64.toString()); // $hasTaintFlow=y
StrBuilder sb65 = new StrBuilder(); sb65.replaceFirst("search", taint()); sink(sb65.toString()); // $hasTaintFlow=y
StrBuilder sb64 = new StrBuilder(); sb64.replaceFirst((StrMatcher)null, taint()); sink(sb64.toString()); // $hasTaintFlow
StrBuilder sb65 = new StrBuilder(); sb65.replaceFirst("search", taint()); sink(sb65.toString()); // $hasTaintFlow
StrBuilder sb66 = new StrBuilder(); sb66.replaceFirst(taint(), "replace"); sink(sb66.toString()); // GOOD (search string doesn't convey taint)
StrBuilder sb67 = new StrBuilder(); sb67.append(taint()); sink(sb67.rightString(0)); // $hasTaintFlow=y
StrBuilder sb68 = new StrBuilder(); sb68.append(taint()); sink(sb68.subSequence(0, 0)); // $hasTaintFlow=y
StrBuilder sb69 = new StrBuilder(); sb69.append(taint()); sink(sb69.substring(0)); // $hasTaintFlow=y
StrBuilder sb70 = new StrBuilder(); sb70.append(taint()); sink(sb70.substring(0, 0)); // $hasTaintFlow=y
StrBuilder sb71 = new StrBuilder(); sb71.append(taint()); sink(sb71.toCharArray()); // $hasTaintFlow=y
StrBuilder sb72 = new StrBuilder(); sb72.append(taint()); sink(sb72.toCharArray(0, 0)); // $hasTaintFlow=y
StrBuilder sb73 = new StrBuilder(); sb73.append(taint()); sink(sb73.toStringBuffer()); // $hasTaintFlow=y
StrBuilder sb74 = new StrBuilder(); sb74.append(taint()); sink(sb74.toStringBuilder()); // $hasTaintFlow=y
StrBuilder sb67 = new StrBuilder(); sb67.append(taint()); sink(sb67.rightString(0)); // $hasTaintFlow
StrBuilder sb68 = new StrBuilder(); sb68.append(taint()); sink(sb68.subSequence(0, 0)); // $hasTaintFlow
StrBuilder sb69 = new StrBuilder(); sb69.append(taint()); sink(sb69.substring(0)); // $hasTaintFlow
StrBuilder sb70 = new StrBuilder(); sb70.append(taint()); sink(sb70.substring(0, 0)); // $hasTaintFlow
StrBuilder sb71 = new StrBuilder(); sb71.append(taint()); sink(sb71.toCharArray()); // $hasTaintFlow
StrBuilder sb72 = new StrBuilder(); sb72.append(taint()); sink(sb72.toCharArray(0, 0)); // $hasTaintFlow
StrBuilder sb73 = new StrBuilder(); sb73.append(taint()); sink(sb73.toStringBuffer()); // $hasTaintFlow
StrBuilder sb74 = new StrBuilder(); sb74.append(taint()); sink(sb74.toStringBuilder()); // $hasTaintFlow
}
}

View File

@@ -0,0 +1,17 @@
import org.apache.commons.lang3.text.StrLookup;
import java.util.HashMap;
import java.util.Map;
class StrLookupTest {
String taint() { return "tainted"; }
void sink(Object o) {}
void test() throws Exception {
Map<String, String> map = new HashMap<String, String>();
map.put("key", taint());
StrLookup<String> lookup = StrLookup.mapLookup(map);
sink(lookup.lookup("key")); // $hasTaintFlow
}
}

View File

@@ -0,0 +1,82 @@
import org.apache.commons.lang3.text.StrSubstitutor;
import org.apache.commons.lang3.text.StrLookup;
import org.apache.commons.lang3.text.StrMatcher;
import org.apache.commons.lang3.text.StrBuilder;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
class StrSubstitutorTest {
String taint() { return "tainted"; }
void sink(Object o) {}
void test() throws Exception {
Map<String, String> taintedMap = new HashMap<String, String>();
taintedMap.put("key", taint());
StrLookup<String> taintedLookup = StrLookup.mapLookup(taintedMap);
// Test constructors:
StrSubstitutor ss1 = new StrSubstitutor(); ss1.setVariableResolver(taintedLookup); sink(ss1.replace("input")); // $hasTaintFlow
StrSubstitutor ss2 = new StrSubstitutor(taintedMap); sink(ss2.replace("input")); // $hasTaintFlow
StrSubstitutor ss3 = new StrSubstitutor(taintedMap, "{", "}"); sink(ss3.replace("input")); // $hasTaintFlow
StrSubstitutor ss4 = new StrSubstitutor(taintedMap, "{", "}", ' '); sink(ss4.replace("input")); // $hasTaintFlow
StrSubstitutor ss5 = new StrSubstitutor(taintedMap, "{", "}", ' ', ","); sink(ss5.replace("input")); // $hasTaintFlow
StrSubstitutor ss6 = new StrSubstitutor(taintedLookup); sink(ss6.replace("input")); // $hasTaintFlow
StrSubstitutor ss7 = new StrSubstitutor(taintedLookup, "{", "}", ' '); sink(ss7.replace("input")); // $hasTaintFlow
StrSubstitutor ss8 = new StrSubstitutor(taintedLookup, "{", "}", ' ', ","); sink(ss8.replace("input")); // $hasTaintFlow
StrSubstitutor ss9 = new StrSubstitutor(taintedLookup, (StrMatcher)null, null, ' '); sink(ss9.replace("input")); // $hasTaintFlow
StrSubstitutor ss10 = new StrSubstitutor(taintedLookup, (StrMatcher)null, null, ' ', null); sink(ss10.replace("input")); // $hasTaintFlow
// Test replace overloads (tainted substitution map):
StrSubstitutor taintedSubst = ss2;
sink(taintedSubst.replace((Object)"input")); // $hasTaintFlow
sink(taintedSubst.replace("input")); // $hasTaintFlow
sink(taintedSubst.replace("input", 0, 0)); // $hasTaintFlow
sink(taintedSubst.replace("input".toCharArray())); // $hasTaintFlow
sink(taintedSubst.replace("input".toCharArray(), 0, 0)); // $hasTaintFlow
sink(taintedSubst.replace((CharSequence)"input")); // $hasTaintFlow
sink(taintedSubst.replace((CharSequence)"input", 0, 0)); // $hasTaintFlow
sink(taintedSubst.replace(new StrBuilder("input"))); // $hasTaintFlow
sink(taintedSubst.replace(new StrBuilder("input"), 0, 0)); // $hasTaintFlow
sink(taintedSubst.replace(new StringBuilder("input"))); // $hasTaintFlow
sink(taintedSubst.replace(new StringBuilder("input"), 0, 0)); // $hasTaintFlow
sink(taintedSubst.replace(new StringBuffer("input"))); // $hasTaintFlow
sink(taintedSubst.replace(new StringBuffer("input"), 0, 0)); // $hasTaintFlow
// Test replace overloads (tainted input):
StrSubstitutor untaintedSubst = ss1;
sink(untaintedSubst.replace((Object)taint())); // $hasTaintFlow
sink(untaintedSubst.replace(taint())); // $hasTaintFlow
sink(untaintedSubst.replace(taint(), 0, 0)); // $hasTaintFlow
sink(untaintedSubst.replace(taint().toCharArray())); // $hasTaintFlow
sink(untaintedSubst.replace(taint().toCharArray(), 0, 0)); // $hasTaintFlow
sink(untaintedSubst.replace((CharSequence)taint())); // $hasTaintFlow
sink(untaintedSubst.replace((CharSequence)taint(), 0, 0)); // $hasTaintFlow
sink(untaintedSubst.replace(new StrBuilder(taint()))); // $hasTaintFlow
sink(untaintedSubst.replace(new StrBuilder(taint()), 0, 0)); // $hasTaintFlow
sink(untaintedSubst.replace(new StringBuilder(taint()))); // $hasTaintFlow
sink(untaintedSubst.replace(new StringBuilder(taint()), 0, 0)); // $hasTaintFlow
sink(untaintedSubst.replace(new StringBuffer(taint()))); // $hasTaintFlow
sink(untaintedSubst.replace(new StringBuffer(taint()), 0, 0)); // $hasTaintFlow
// Test static replace methods:
sink(StrSubstitutor.replace(taint(), new HashMap<String, String>())); // $hasTaintFlow
sink(StrSubstitutor.replace(taint(), new HashMap<String, String>(), "{", "}")); // $hasTaintFlow
sink(StrSubstitutor.replace("input", taintedMap)); // $hasTaintFlow
sink(StrSubstitutor.replace("input", taintedMap, "{", "}")); // $hasTaintFlow
Properties taintedProps = new Properties();
taintedProps.put("key", taint());
sink(StrSubstitutor.replace(taint(), new Properties())); // $hasTaintFlow
sink(StrSubstitutor.replace("input", taintedProps)); // $hasTaintFlow
// Test replaceIn methods:
StrBuilder strBuilder1 = new StrBuilder(); taintedSubst.replaceIn(strBuilder1); sink(strBuilder1.toString()); // $hasTaintFlow
StrBuilder strBuilder2 = new StrBuilder(); taintedSubst.replaceIn(strBuilder2, 0, 0); sink(strBuilder2.toString()); // $hasTaintFlow
StringBuilder stringBuilder1 = new StringBuilder(); taintedSubst.replaceIn(stringBuilder1); sink(stringBuilder1.toString()); // $hasTaintFlow
StringBuilder stringBuilder2 = new StringBuilder(); taintedSubst.replaceIn(stringBuilder2, 0, 0); sink(stringBuilder2.toString()); // $hasTaintFlow
StringBuffer stringBuffer1 = new StringBuffer(); taintedSubst.replaceIn(stringBuffer1); sink(stringBuffer1.toString()); // $hasTaintFlow
StringBuffer stringBuffer2 = new StringBuffer(); taintedSubst.replaceIn(stringBuffer2, 0, 0); sink(stringBuffer2.toString()); // $hasTaintFlow
}
}

View File

@@ -0,0 +1,46 @@
import org.apache.commons.lang3.text.StrTokenizer;
import org.apache.commons.lang3.text.StrMatcher;
public class StrTokenizerTest {
String taint() { return "tainted"; }
void sink(Object o) {}
void test() throws Exception {
// Test constructors:
sink((new StrTokenizer(taint().toCharArray())).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint().toCharArray(), ',')).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint().toCharArray(), ',', '"')).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint().toCharArray(), ",")).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint().toCharArray(), (StrMatcher)null)).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint().toCharArray(), (StrMatcher)null, (StrMatcher)null)).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint())).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint(), ',')).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint(), ',', '"')).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint(), ",")).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint(), (StrMatcher)null)).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint(), (StrMatcher)null, (StrMatcher)null)).toString()); // $hasTaintFlow
// Test constructing static methods:
sink(StrTokenizer.getCSVInstance(taint().toCharArray()).toString()); // $hasTaintFlow
sink(StrTokenizer.getCSVInstance(taint()).toString()); // $hasTaintFlow
sink(StrTokenizer.getTSVInstance(taint().toCharArray()).toString()); // $hasTaintFlow
sink(StrTokenizer.getTSVInstance(taint()).toString()); // $hasTaintFlow
// Test accessors:
sink((new StrTokenizer(taint())).clone()); // $hasTaintFlow
sink((new StrTokenizer(taint())).getContent()); // $hasTaintFlow
sink((new StrTokenizer(taint())).getTokenArray()); // $hasTaintFlow
sink((new StrTokenizer(taint())).getTokenList()); // $hasTaintFlow
sink((new StrTokenizer(taint())).next()); // $hasTaintFlow
sink((new StrTokenizer(taint())).nextToken()); // $hasTaintFlow
sink((new StrTokenizer(taint())).previous()); // $hasTaintFlow
sink((new StrTokenizer(taint())).previousToken()); // $hasTaintFlow
// Test mutators:
sink((new StrTokenizer()).reset(taint().toCharArray()).toString()); // $hasTaintFlow
sink((new StrTokenizer()).reset(taint()).toString()); // $hasTaintFlow
}
}

View File

@@ -0,0 +1,46 @@
import org.apache.commons.text.StrTokenizer;
import org.apache.commons.text.StrMatcher;
public class StrTokenizerTextTest {
String taint() { return "tainted"; }
void sink(Object o) {}
void test() throws Exception {
// Test constructors:
sink((new StrTokenizer(taint().toCharArray())).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint().toCharArray(), ',')).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint().toCharArray(), ',', '"')).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint().toCharArray(), ",")).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint().toCharArray(), (StrMatcher)null)).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint().toCharArray(), (StrMatcher)null, (StrMatcher)null)).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint())).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint(), ',')).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint(), ',', '"')).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint(), ",")).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint(), (StrMatcher)null)).toString()); // $hasTaintFlow
sink((new StrTokenizer(taint(), (StrMatcher)null, (StrMatcher)null)).toString()); // $hasTaintFlow
// Test constructing static methods:
sink(StrTokenizer.getCSVInstance(taint().toCharArray()).toString()); // $hasTaintFlow
sink(StrTokenizer.getCSVInstance(taint()).toString()); // $hasTaintFlow
sink(StrTokenizer.getTSVInstance(taint().toCharArray()).toString()); // $hasTaintFlow
sink(StrTokenizer.getTSVInstance(taint()).toString()); // $hasTaintFlow
// Test accessors:
sink((new StrTokenizer(taint())).clone()); // $hasTaintFlow
sink((new StrTokenizer(taint())).getContent()); // $hasTaintFlow
sink((new StrTokenizer(taint())).getTokenArray()); // $hasTaintFlow
sink((new StrTokenizer(taint())).getTokenList()); // $hasTaintFlow
sink((new StrTokenizer(taint())).next()); // $hasTaintFlow
sink((new StrTokenizer(taint())).nextToken()); // $hasTaintFlow
sink((new StrTokenizer(taint())).previous()); // $hasTaintFlow
sink((new StrTokenizer(taint())).previousToken()); // $hasTaintFlow
// Test mutators:
sink((new StrTokenizer()).reset(taint().toCharArray()).toString()); // $hasTaintFlow
sink((new StrTokenizer()).reset(taint()).toString()); // $hasTaintFlow
}
}

View File

@@ -0,0 +1,18 @@
import org.apache.commons.text.lookup.StringLookup;
import org.apache.commons.text.lookup.StringLookupFactory;
import java.util.HashMap;
import java.util.Map;
class StringLookupTextTest {
String taint() { return "tainted"; }
void sink(Object o) {}
void test() throws Exception {
Map<String, String> map = new HashMap<String, String>();
map.put("key", taint());
StringLookup lookup = StringLookupFactory.INSTANCE.mapStringLookup(map);
sink(lookup.lookup("key")); // $hasTaintFlow
}
}

View File

@@ -0,0 +1,83 @@
import org.apache.commons.text.StringSubstitutor;
import org.apache.commons.text.lookup.StringLookup;
import org.apache.commons.text.lookup.StringLookupFactory;
import org.apache.commons.text.matcher.StringMatcher;
import org.apache.commons.text.TextStringBuilder;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
class StringSubstitutorTextTest {
String taint() { return "tainted"; }
void sink(Object o) {}
void test() throws Exception {
Map<String, String> taintedMap = new HashMap<String, String>();
taintedMap.put("key", taint());
StringLookup taintedLookup = StringLookupFactory.INSTANCE.mapStringLookup(taintedMap);
// Test constructors:
StringSubstitutor ss1 = new StringSubstitutor(); ss1.setVariableResolver(taintedLookup); sink(ss1.replace("input")); // $hasTaintFlow
StringSubstitutor ss2 = new StringSubstitutor(taintedMap); sink(ss2.replace("input")); // $hasTaintFlow
StringSubstitutor ss3 = new StringSubstitutor(taintedMap, "{", "}"); sink(ss3.replace("input")); // $hasTaintFlow
StringSubstitutor ss4 = new StringSubstitutor(taintedMap, "{", "}", ' '); sink(ss4.replace("input")); // $hasTaintFlow
StringSubstitutor ss5 = new StringSubstitutor(taintedMap, "{", "}", ' ', ","); sink(ss5.replace("input")); // $hasTaintFlow
StringSubstitutor ss6 = new StringSubstitutor(taintedLookup); sink(ss6.replace("input")); // $hasTaintFlow
StringSubstitutor ss7 = new StringSubstitutor(taintedLookup, "{", "}", ' '); sink(ss7.replace("input")); // $hasTaintFlow
StringSubstitutor ss8 = new StringSubstitutor(taintedLookup, "{", "}", ' ', ","); sink(ss8.replace("input")); // $hasTaintFlow
StringSubstitutor ss9 = new StringSubstitutor(taintedLookup, (StringMatcher)null, null, ' '); sink(ss9.replace("input")); // $hasTaintFlow
StringSubstitutor ss10 = new StringSubstitutor(taintedLookup, (StringMatcher)null, null, ' ', null); sink(ss10.replace("input")); // $hasTaintFlow
// Test replace overloads (tainted substitution map):
StringSubstitutor taintedSubst = ss2;
sink(taintedSubst.replace((Object)"input")); // $hasTaintFlow
sink(taintedSubst.replace("input")); // $hasTaintFlow
sink(taintedSubst.replace("input", 0, 0)); // $hasTaintFlow
sink(taintedSubst.replace("input".toCharArray())); // $hasTaintFlow
sink(taintedSubst.replace("input".toCharArray(), 0, 0)); // $hasTaintFlow
sink(taintedSubst.replace((CharSequence)"input")); // $hasTaintFlow
sink(taintedSubst.replace((CharSequence)"input", 0, 0)); // $hasTaintFlow
sink(taintedSubst.replace(new TextStringBuilder("input"))); // $hasTaintFlow
sink(taintedSubst.replace(new TextStringBuilder("input"), 0, 0)); // $hasTaintFlow
sink(taintedSubst.replace(new StringBuilder("input"))); // $hasTaintFlow
sink(taintedSubst.replace(new StringBuilder("input"), 0, 0)); // $hasTaintFlow
sink(taintedSubst.replace(new StringBuffer("input"))); // $hasTaintFlow
sink(taintedSubst.replace(new StringBuffer("input"), 0, 0)); // $hasTaintFlow
// Test replace overloads (tainted input):
StringSubstitutor untaintedSubst = ss1;
sink(untaintedSubst.replace((Object)taint())); // $hasTaintFlow
sink(untaintedSubst.replace(taint())); // $hasTaintFlow
sink(untaintedSubst.replace(taint(), 0, 0)); // $hasTaintFlow
sink(untaintedSubst.replace(taint().toCharArray())); // $hasTaintFlow
sink(untaintedSubst.replace(taint().toCharArray(), 0, 0)); // $hasTaintFlow
sink(untaintedSubst.replace((CharSequence)taint())); // $hasTaintFlow
sink(untaintedSubst.replace((CharSequence)taint(), 0, 0)); // $hasTaintFlow
sink(untaintedSubst.replace(new TextStringBuilder(taint()))); // $hasTaintFlow
sink(untaintedSubst.replace(new TextStringBuilder(taint()), 0, 0)); // $hasTaintFlow
sink(untaintedSubst.replace(new StringBuilder(taint()))); // $hasTaintFlow
sink(untaintedSubst.replace(new StringBuilder(taint()), 0, 0)); // $hasTaintFlow
sink(untaintedSubst.replace(new StringBuffer(taint()))); // $hasTaintFlow
sink(untaintedSubst.replace(new StringBuffer(taint()), 0, 0)); // $hasTaintFlow
// Test static replace methods:
sink(StringSubstitutor.replace(taint(), new HashMap<String, String>())); // $hasTaintFlow
sink(StringSubstitutor.replace(taint(), new HashMap<String, String>(), "{", "}")); // $hasTaintFlow
sink(StringSubstitutor.replace("input", taintedMap)); // $hasTaintFlow
sink(StringSubstitutor.replace("input", taintedMap, "{", "}")); // $hasTaintFlow
Properties taintedProps = new Properties();
taintedProps.put("key", taint());
sink(StringSubstitutor.replace(taint(), new Properties())); // $hasTaintFlow
sink(StringSubstitutor.replace("input", taintedProps)); // $hasTaintFlow
// Test replaceIn methods:
TextStringBuilder strBuilder1 = new TextStringBuilder(); taintedSubst.replaceIn(strBuilder1); sink(strBuilder1.toString()); // $hasTaintFlow
TextStringBuilder strBuilder2 = new TextStringBuilder(); taintedSubst.replaceIn(strBuilder2, 0, 0); sink(strBuilder2.toString()); // $hasTaintFlow
StringBuilder stringBuilder1 = new StringBuilder(); taintedSubst.replaceIn(stringBuilder1); sink(stringBuilder1.toString()); // $hasTaintFlow
StringBuilder stringBuilder2 = new StringBuilder(); taintedSubst.replaceIn(stringBuilder2, 0, 0); sink(stringBuilder2.toString()); // $hasTaintFlow
StringBuffer stringBuffer1 = new StringBuffer(); taintedSubst.replaceIn(stringBuffer1); sink(stringBuffer1.toString()); // $hasTaintFlow
StringBuffer stringBuffer2 = new StringBuffer(); taintedSubst.replaceIn(stringBuffer2, 0, 0); sink(stringBuffer2.toString()); // $hasTaintFlow
}
}

View File

@@ -0,0 +1,46 @@
import org.apache.commons.text.StringTokenizer;
import org.apache.commons.text.matcher.StringMatcher;
public class StringTokenizerTest {
String taint() { return "tainted"; }
void sink(Object o) {}
void test() throws Exception {
// Test constructors:
sink((new StringTokenizer(taint().toCharArray())).toString()); // $hasTaintFlow
sink((new StringTokenizer(taint().toCharArray(), ',')).toString()); // $hasTaintFlow
sink((new StringTokenizer(taint().toCharArray(), ',', '"')).toString()); // $hasTaintFlow
sink((new StringTokenizer(taint().toCharArray(), ",")).toString()); // $hasTaintFlow
sink((new StringTokenizer(taint().toCharArray(), (StringMatcher)null)).toString()); // $hasTaintFlow
sink((new StringTokenizer(taint().toCharArray(), (StringMatcher)null, (StringMatcher)null)).toString()); // $hasTaintFlow
sink((new StringTokenizer(taint())).toString()); // $hasTaintFlow
sink((new StringTokenizer(taint(), ',')).toString()); // $hasTaintFlow
sink((new StringTokenizer(taint(), ',', '"')).toString()); // $hasTaintFlow
sink((new StringTokenizer(taint(), ",")).toString()); // $hasTaintFlow
sink((new StringTokenizer(taint(), (StringMatcher)null)).toString()); // $hasTaintFlow
sink((new StringTokenizer(taint(), (StringMatcher)null, (StringMatcher)null)).toString()); // $hasTaintFlow
// Test constructing static methods:
sink(StringTokenizer.getCSVInstance(taint().toCharArray()).toString()); // $hasTaintFlow
sink(StringTokenizer.getCSVInstance(taint()).toString()); // $hasTaintFlow
sink(StringTokenizer.getTSVInstance(taint().toCharArray()).toString()); // $hasTaintFlow
sink(StringTokenizer.getTSVInstance(taint()).toString()); // $hasTaintFlow
// Test accessors:
sink((new StringTokenizer(taint())).clone()); // $hasTaintFlow
sink((new StringTokenizer(taint())).getContent()); // $hasTaintFlow
sink((new StringTokenizer(taint())).getTokenArray()); // $hasTaintFlow
sink((new StringTokenizer(taint())).getTokenList()); // $hasTaintFlow
sink((new StringTokenizer(taint())).next()); // $hasTaintFlow
sink((new StringTokenizer(taint())).nextToken()); // $hasTaintFlow
sink((new StringTokenizer(taint())).previous()); // $hasTaintFlow
sink((new StringTokenizer(taint())).previousToken()); // $hasTaintFlow
// Test mutators:
sink((new StringTokenizer()).reset(taint().toCharArray()).toString()); // $hasTaintFlow
sink((new StringTokenizer()).reset(taint()).toString()); // $hasTaintFlow
}
}

View File

@@ -12,57 +12,57 @@ class Test {
void test() throws Exception {
// All these calls should convey taint to `sink` except as noted.
sink(StringUtils.abbreviate(taint(), 0)); // $hasTaintFlow=y
sink(StringUtils.abbreviate(taint(), 0, 0)); // $hasTaintFlow=y
sink(StringUtils.abbreviate(taint(), "...", 0)); // $hasTaintFlow=y
sink(StringUtils.abbreviate("Untainted", taint(), 0)); // $hasTaintFlow=y
sink(StringUtils.abbreviate(taint(), "...", 0, 0)); // $hasTaintFlow=y
sink(StringUtils.abbreviate("Untainted", taint(), 0, 0)); // $hasTaintFlow=y
sink(StringUtils.abbreviateMiddle(taint(), "...", 0)); // $hasTaintFlow=y
sink(StringUtils.abbreviateMiddle("Untainted", taint(), 0)); // $hasTaintFlow=y
sink(StringUtils.appendIfMissing(taint(), "suffix", "candsuffix1", "candsuffix2")); // $hasTaintFlow=y
sink(StringUtils.appendIfMissing("prefix", taint(), "candsuffix1", "candsuffix2")); // $hasTaintFlow=y
sink(StringUtils.abbreviate(taint(), 0)); // $hasTaintFlow
sink(StringUtils.abbreviate(taint(), 0, 0)); // $hasTaintFlow
sink(StringUtils.abbreviate(taint(), "...", 0)); // $hasTaintFlow
sink(StringUtils.abbreviate("Untainted", taint(), 0)); // $hasTaintFlow
sink(StringUtils.abbreviate(taint(), "...", 0, 0)); // $hasTaintFlow
sink(StringUtils.abbreviate("Untainted", taint(), 0, 0)); // $hasTaintFlow
sink(StringUtils.abbreviateMiddle(taint(), "...", 0)); // $hasTaintFlow
sink(StringUtils.abbreviateMiddle("Untainted", taint(), 0)); // $hasTaintFlow
sink(StringUtils.appendIfMissing(taint(), "suffix", "candsuffix1", "candsuffix2")); // $hasTaintFlow
sink(StringUtils.appendIfMissing("prefix", taint(), "candsuffix1", "candsuffix2")); // $hasTaintFlow
// (next 2 calls) GOOD: candidate suffixes do not flow to the return value.
sink(StringUtils.appendIfMissing("prefix", "suffix", taint(), "candsuffix2"));
sink(StringUtils.appendIfMissing("prefix", "suffix", "candsuffix1", taint()));
sink(StringUtils.appendIfMissingIgnoreCase(taint(), "suffix", "candsuffix1", "candsuffix2")); // $hasTaintFlow=y
sink(StringUtils.appendIfMissingIgnoreCase("prefix", taint(), "candsuffix1", "candsuffix2")); // $hasTaintFlow=y
sink(StringUtils.appendIfMissingIgnoreCase(taint(), "suffix", "candsuffix1", "candsuffix2")); // $hasTaintFlow
sink(StringUtils.appendIfMissingIgnoreCase("prefix", taint(), "candsuffix1", "candsuffix2")); // $hasTaintFlow
// (next 2 calls) GOOD: candidate suffixes do not flow to the return value.
sink(StringUtils.appendIfMissingIgnoreCase("prefix", "suffix", taint(), "candsuffix2"));
sink(StringUtils.appendIfMissingIgnoreCase("prefix", "suffix", "candsuffix1", taint()));
sink(StringUtils.capitalize(taint())); // $hasTaintFlow=y
sink(StringUtils.center(taint(), 0)); // $hasTaintFlow=y
sink(StringUtils.center(taint(), 0, 'x')); // $hasTaintFlow=y
sink(StringUtils.center(taint(), 0, "padding string")); // $hasTaintFlow=y
sink(StringUtils.center("Center me", 0, taint())); // $hasTaintFlow=y
sink(StringUtils.chomp(taint())); // $hasTaintFlow=y
sink(StringUtils.chomp(taint(), "separator")); // $hasTaintFlow=y
sink(StringUtils.capitalize(taint())); // $hasTaintFlow
sink(StringUtils.center(taint(), 0)); // $hasTaintFlow
sink(StringUtils.center(taint(), 0, 'x')); // $hasTaintFlow
sink(StringUtils.center(taint(), 0, "padding string")); // $hasTaintFlow
sink(StringUtils.center("Center me", 0, taint())); // $hasTaintFlow
sink(StringUtils.chomp(taint())); // $hasTaintFlow
sink(StringUtils.chomp(taint(), "separator")); // $hasTaintFlow
// GOOD: separator does not flow to the return value.
sink(StringUtils.chomp("Chomp me", taint()));
sink(StringUtils.chop(taint())); // $hasTaintFlow=y
sink(StringUtils.defaultIfBlank(taint(), "default")); // $hasTaintFlow=y
sink(StringUtils.defaultIfBlank("Perhaps blank", taint())); // $hasTaintFlow=y
sink(StringUtils.defaultIfEmpty(taint(), "default")); // $hasTaintFlow=y
sink(StringUtils.defaultIfEmpty("Perhaps empty", taint())); // $hasTaintFlow=y
sink(StringUtils.defaultString(taint())); // $hasTaintFlow=y
sink(StringUtils.defaultString(taint(), "default string")); // $hasTaintFlow=y
sink(StringUtils.defaultString("perhaps null", taint())); // $hasTaintFlow=y
sink(StringUtils.deleteWhitespace(taint())); // $hasTaintFlow=y
sink(StringUtils.difference(taint(), "rhs")); // $hasTaintFlow=y
sink(StringUtils.difference("lhs", taint())); // $hasTaintFlow=y
sink(StringUtils.firstNonBlank(taint(), "second string")); // $hasTaintFlow=y
sink(StringUtils.firstNonBlank("first string", taint())); // $hasTaintFlow=y
sink(StringUtils.firstNonEmpty(taint(), "second string")); // $hasTaintFlow=y
sink(StringUtils.firstNonEmpty("first string", taint())); // $hasTaintFlow=y
sink(StringUtils.getBytes(taint(), (Charset)null)); // $hasTaintFlow=y
sink(StringUtils.getBytes(taint(), "some charset")); // $hasTaintFlow=y
sink(StringUtils.chop(taint())); // $hasTaintFlow
sink(StringUtils.defaultIfBlank(taint(), "default")); // $hasTaintFlow
sink(StringUtils.defaultIfBlank("Perhaps blank", taint())); // $hasTaintFlow
sink(StringUtils.defaultIfEmpty(taint(), "default")); // $hasTaintFlow
sink(StringUtils.defaultIfEmpty("Perhaps empty", taint())); // $hasTaintFlow
sink(StringUtils.defaultString(taint())); // $hasTaintFlow
sink(StringUtils.defaultString(taint(), "default string")); // $hasTaintFlow
sink(StringUtils.defaultString("perhaps null", taint())); // $hasTaintFlow
sink(StringUtils.deleteWhitespace(taint())); // $hasTaintFlow
sink(StringUtils.difference(taint(), "rhs")); // $hasTaintFlow
sink(StringUtils.difference("lhs", taint())); // $hasTaintFlow
sink(StringUtils.firstNonBlank(taint(), "second string")); // $hasTaintFlow
sink(StringUtils.firstNonBlank("first string", taint())); // $hasTaintFlow
sink(StringUtils.firstNonEmpty(taint(), "second string")); // $hasTaintFlow
sink(StringUtils.firstNonEmpty("first string", taint())); // $hasTaintFlow
sink(StringUtils.getBytes(taint(), (Charset)null)); // $hasTaintFlow
sink(StringUtils.getBytes(taint(), "some charset")); // $hasTaintFlow
// GOOD: charset names are not a source of taint
sink(StringUtils.getBytes("some string", taint()));
sink(StringUtils.getCommonPrefix(taint(), "second string")); // $hasTaintFlow=y
sink(StringUtils.getCommonPrefix("first string", taint())); // $hasTaintFlow=y
sink(StringUtils.getDigits(taint())); // $hasTaintFlow=y
sink(StringUtils.getIfBlank(taint(), () -> "default")); // $hasTaintFlow=y
sink(StringUtils.getIfEmpty(taint(), () -> "default")); // $hasTaintFlow=y
sink(StringUtils.getCommonPrefix(taint(), "second string")); // $hasTaintFlow
sink(StringUtils.getCommonPrefix("first string", taint())); // $hasTaintFlow
sink(StringUtils.getDigits(taint())); // $hasTaintFlow
sink(StringUtils.getIfBlank(taint(), () -> "default")); // $hasTaintFlow
sink(StringUtils.getIfEmpty(taint(), () -> "default")); // $hasTaintFlow
// BAD (but not detected yet): latent taint in lambdas
sink(StringUtils.getIfBlank("maybe blank", () -> taint()));
sink(StringUtils.getIfEmpty("maybe blank", () -> taint()));
@@ -70,70 +70,70 @@ class Test {
// of tainted data.
sink(StringUtils.join(StringUtils.getBytes(taint(), "UTF-8"), ' '));
sink(StringUtils.join(StringUtils.getBytes(taint(), "UTF-8"), ' ', 0, 0));
sink(StringUtils.join(taint().toCharArray(), ' ')); // $hasTaintFlow=y
sink(StringUtils.join(taint().toCharArray(), ' ', 0, 0)); // $hasTaintFlow=y
sink(StringUtils.join(taint().toCharArray(), ' ')); // $hasTaintFlow
sink(StringUtils.join(taint().toCharArray(), ' ', 0, 0)); // $hasTaintFlow
// Testing the Iterable<?> overloads of `join`
List<String> taintedList = new ArrayList<>();
taintedList.add(taint());
sink(StringUtils.join(taintedList, ' ')); // $hasTaintFlow=y
sink(StringUtils.join(taintedList, "sep")); // $hasTaintFlow=y
sink(StringUtils.join(taintedList, ' ')); // $hasTaintFlow
sink(StringUtils.join(taintedList, "sep")); // $hasTaintFlow
List<String> untaintedList = new ArrayList<>();
sink(StringUtils.join(untaintedList, taint())); // $hasTaintFlow=y
sink(StringUtils.join(untaintedList, taint())); // $hasTaintFlow
// Testing the Iterator<?> overloads of `join`
sink(StringUtils.join(taintedList.iterator(), ' ')); // $hasTaintFlow=y
sink(StringUtils.join(taintedList.iterator(), "sep")); // $hasTaintFlow=y
sink(StringUtils.join(untaintedList.iterator(), taint())); // $hasTaintFlow=y
sink(StringUtils.join(taintedList.iterator(), ' ')); // $hasTaintFlow
sink(StringUtils.join(taintedList.iterator(), "sep")); // $hasTaintFlow
sink(StringUtils.join(untaintedList.iterator(), taint())); // $hasTaintFlow
// Testing the List<?> overloads of `join`, which have start/end indices
sink(StringUtils.join(taintedList, ' ', 0, 0)); // $hasTaintFlow=y
sink(StringUtils.join(taintedList, "sep", 0, 0)); // $hasTaintFlow=y
sink(StringUtils.join(untaintedList, taint(), 0, 0)); // $hasTaintFlow=y
sink(StringUtils.join(taintedList, ' ', 0, 0)); // $hasTaintFlow
sink(StringUtils.join(taintedList, "sep", 0, 0)); // $hasTaintFlow
sink(StringUtils.join(untaintedList, taint(), 0, 0)); // $hasTaintFlow
// Testing the Object[] overloads of `join`, which may have start/end indices
Object[] taintedArray = new Object[] { taint() };
sink(StringUtils.join(taintedArray, ' ')); // $hasTaintFlow=y
sink(StringUtils.join(taintedArray, "sep")); // $hasTaintFlow=y
sink(StringUtils.join(taintedArray, ' ', 0, 0)); // $hasTaintFlow=y
sink(StringUtils.join(taintedArray, "sep", 0, 0)); // $hasTaintFlow=y
sink(StringUtils.join(taintedArray, ' ')); // $hasTaintFlow
sink(StringUtils.join(taintedArray, "sep")); // $hasTaintFlow
sink(StringUtils.join(taintedArray, ' ', 0, 0)); // $hasTaintFlow
sink(StringUtils.join(taintedArray, "sep", 0, 0)); // $hasTaintFlow
Object[] untaintedArray = new Object[] { "safe" };
sink(StringUtils.join(untaintedArray, taint())); // $hasTaintFlow=y
sink(StringUtils.join(untaintedArray, taint(), 0, 0)); // $hasTaintFlow=y
sink(StringUtils.join(untaintedArray, taint())); // $hasTaintFlow
sink(StringUtils.join(untaintedArray, taint(), 0, 0)); // $hasTaintFlow
// Testing the variadic overload of `join` and `joinWith`
sink(StringUtils.join(taint(), "other string")); // $hasTaintFlow=y
sink(StringUtils.join("other string before", taint())); // $hasTaintFlow=y
sink(StringUtils.joinWith("separator", taint(), "other string")); // $hasTaintFlow=y
sink(StringUtils.joinWith("separator", "other string before", taint())); // $hasTaintFlow=y
sink(StringUtils.joinWith(taint(), "other string before", "other string after")); // $hasTaintFlow=y
sink(StringUtils.join(taint(), "other string")); // $hasTaintFlow
sink(StringUtils.join("other string before", taint())); // $hasTaintFlow
sink(StringUtils.joinWith("separator", taint(), "other string")); // $hasTaintFlow
sink(StringUtils.joinWith("separator", "other string before", taint())); // $hasTaintFlow
sink(StringUtils.joinWith(taint(), "other string before", "other string after")); // $hasTaintFlow
// End of `join` tests
sink(StringUtils.left(taint(), 0)); // $hasTaintFlow=y
sink(StringUtils.leftPad(taint(), 0)); // $hasTaintFlow=y
sink(StringUtils.leftPad(taint(), 0, ' ')); // $hasTaintFlow=y
sink(StringUtils.leftPad(taint(), 0, "padding")); // $hasTaintFlow=y
sink(StringUtils.leftPad("to pad", 0, taint())); // $hasTaintFlow=y
sink(StringUtils.lowerCase(taint())); // $hasTaintFlow=y
sink(StringUtils.lowerCase(taint(), Locale.UK)); // $hasTaintFlow=y
sink(StringUtils.mid(taint(), 0, 0)); // $hasTaintFlow=y
sink(StringUtils.normalizeSpace(taint())); // $hasTaintFlow=y
sink(StringUtils.overlay(taint(), "overlay", 0, 0)); // $hasTaintFlow=y
sink(StringUtils.overlay("underlay", taint(), 0, 0)); // $hasTaintFlow=y
sink(StringUtils.prependIfMissing(taint(), "append prefix", "check prefix 1", "check prefix 2")); // $hasTaintFlow=y
sink(StringUtils.prependIfMissing("original string", taint(), "check prefix 1", "check prefix 2")); // $hasTaintFlow=y
sink(StringUtils.left(taint(), 0)); // $hasTaintFlow
sink(StringUtils.leftPad(taint(), 0)); // $hasTaintFlow
sink(StringUtils.leftPad(taint(), 0, ' ')); // $hasTaintFlow
sink(StringUtils.leftPad(taint(), 0, "padding")); // $hasTaintFlow
sink(StringUtils.leftPad("to pad", 0, taint())); // $hasTaintFlow
sink(StringUtils.lowerCase(taint())); // $hasTaintFlow
sink(StringUtils.lowerCase(taint(), Locale.UK)); // $hasTaintFlow
sink(StringUtils.mid(taint(), 0, 0)); // $hasTaintFlow
sink(StringUtils.normalizeSpace(taint())); // $hasTaintFlow
sink(StringUtils.overlay(taint(), "overlay", 0, 0)); // $hasTaintFlow
sink(StringUtils.overlay("underlay", taint(), 0, 0)); // $hasTaintFlow
sink(StringUtils.prependIfMissing(taint(), "append prefix", "check prefix 1", "check prefix 2")); // $hasTaintFlow
sink(StringUtils.prependIfMissing("original string", taint(), "check prefix 1", "check prefix 2")); // $hasTaintFlow
// (next 2 calls) GOOD: args 3+ are checked against but do not propagate to the return value
sink(StringUtils.prependIfMissing("original string", "append prefix", taint(), "check prefix 2"));
sink(StringUtils.prependIfMissing("original string", "append prefix", "check prefix 1", taint()));
sink(StringUtils.prependIfMissingIgnoreCase(taint(), "append prefix", "check prefix 1", "check prefix 2")); // $hasTaintFlow=y
sink(StringUtils.prependIfMissingIgnoreCase("original string", taint(), "check prefix 1", "check prefix 2")); // $hasTaintFlow=y
sink(StringUtils.prependIfMissingIgnoreCase(taint(), "append prefix", "check prefix 1", "check prefix 2")); // $hasTaintFlow
sink(StringUtils.prependIfMissingIgnoreCase("original string", taint(), "check prefix 1", "check prefix 2")); // $hasTaintFlow
// (next 2 calls) GOOD: args 3+ are checked against but do not propagate to the return value
sink(StringUtils.prependIfMissingIgnoreCase("original string", "append prefix", taint(), "check prefix 2"));
sink(StringUtils.prependIfMissingIgnoreCase("original string", "append prefix", "check prefix 1", taint()));
sink(StringUtils.remove(taint(), ' ')); // $hasTaintFlow=y
sink(StringUtils.remove(taint(), "delete me")); // $hasTaintFlow=y
sink(StringUtils.removeAll(taint(), "delete me")); // $hasTaintFlow=y
sink(StringUtils.removeEnd(taint(), "delete me")); // $hasTaintFlow=y
sink(StringUtils.removeEndIgnoreCase(taint(), "delete me")); // $hasTaintFlow=y
sink(StringUtils.removeFirst(taint(), "delete me")); // $hasTaintFlow=y
sink(StringUtils.removeIgnoreCase(taint(), "delete me")); // $hasTaintFlow=y
sink(StringUtils.removePattern(taint(), "delete me")); // $hasTaintFlow=y
sink(StringUtils.removeStart(taint(), "delete me")); // $hasTaintFlow=y
sink(StringUtils.removeStartIgnoreCase(taint(), "delete me")); // $hasTaintFlow=y
sink(StringUtils.remove(taint(), ' ')); // $hasTaintFlow
sink(StringUtils.remove(taint(), "delete me")); // $hasTaintFlow
sink(StringUtils.removeAll(taint(), "delete me")); // $hasTaintFlow
sink(StringUtils.removeEnd(taint(), "delete me")); // $hasTaintFlow
sink(StringUtils.removeEndIgnoreCase(taint(), "delete me")); // $hasTaintFlow
sink(StringUtils.removeFirst(taint(), "delete me")); // $hasTaintFlow
sink(StringUtils.removeIgnoreCase(taint(), "delete me")); // $hasTaintFlow
sink(StringUtils.removePattern(taint(), "delete me")); // $hasTaintFlow
sink(StringUtils.removeStart(taint(), "delete me")); // $hasTaintFlow
sink(StringUtils.removeStartIgnoreCase(taint(), "delete me")); // $hasTaintFlow
// GOOD (next 9 calls): the removed string doesn't propagate to the return value
sink(StringUtils.remove("remove from", taint()));
sink(StringUtils.removeAll("remove from", taint()));
@@ -144,32 +144,32 @@ class Test {
sink(StringUtils.removePattern("remove from", taint()));
sink(StringUtils.removeStart("remove from", taint()));
sink(StringUtils.removeStartIgnoreCase("remove from", taint()));
sink(StringUtils.repeat(taint(), 1)); // $hasTaintFlow=y
sink(StringUtils.repeat(taint(), "separator", 1)); // $hasTaintFlow=y
sink(StringUtils.repeat("repeat me", taint(), 1)); // $hasTaintFlow=y
sink(StringUtils.replace(taint(), "search", "replacement")); // $hasTaintFlow=y
sink(StringUtils.replace("haystack", "search", taint())); // $hasTaintFlow=y
sink(StringUtils.replace(taint(), "search", "replacement", 0)); // $hasTaintFlow=y
sink(StringUtils.replace("haystack", "search", taint(), 0)); // $hasTaintFlow=y
sink(StringUtils.replaceAll(taint(), "search", "replacement")); // $hasTaintFlow=y
sink(StringUtils.replaceAll("haystack", "search", taint())); // $hasTaintFlow=y
sink(StringUtils.replaceChars(taint(), 'a', 'b')); // $hasTaintFlow=y
sink(StringUtils.replaceChars(taint(), "abc", "xyz")); // $hasTaintFlow=y
sink(StringUtils.replaceChars("haystack", "abc", taint())); // $hasTaintFlow=y
sink(StringUtils.replaceEach(taint(), new String[] { "search" }, new String[] { "replacement" })); // $hasTaintFlow=y
sink(StringUtils.replaceEach("haystack", new String[] { "search" }, new String[] { taint() })); // $hasTaintFlow=y
sink(StringUtils.replaceEachRepeatedly(taint(), new String[] { "search" }, new String[] { "replacement" })); // $hasTaintFlow=y
sink(StringUtils.replaceEachRepeatedly("haystack", new String[] { "search" }, new String[] { taint() })); // $hasTaintFlow=y
sink(StringUtils.replaceFirst(taint(), "search", "replacement")); // $hasTaintFlow=y
sink(StringUtils.replaceFirst("haystack", "search", taint())); // $hasTaintFlow=y
sink(StringUtils.replaceIgnoreCase(taint(), "search", "replacement")); // $hasTaintFlow=y
sink(StringUtils.replaceIgnoreCase("haystack", "search", taint())); // $hasTaintFlow=y
sink(StringUtils.replaceOnce(taint(), "search", "replacement")); // $hasTaintFlow=y
sink(StringUtils.replaceOnce("haystack", "search", taint())); // $hasTaintFlow=y
sink(StringUtils.replaceOnceIgnoreCase(taint(), "search", "replacement")); // $hasTaintFlow=y
sink(StringUtils.replaceOnceIgnoreCase("haystack", "search", taint())); // $hasTaintFlow=y
sink(StringUtils.replacePattern(taint(), "search", "replacement")); // $hasTaintFlow=y
sink(StringUtils.replacePattern("haystack", "search", taint())); // $hasTaintFlow=y
sink(StringUtils.repeat(taint(), 1)); // $hasTaintFlow
sink(StringUtils.repeat(taint(), "separator", 1)); // $hasTaintFlow
sink(StringUtils.repeat("repeat me", taint(), 1)); // $hasTaintFlow
sink(StringUtils.replace(taint(), "search", "replacement")); // $hasTaintFlow
sink(StringUtils.replace("haystack", "search", taint())); // $hasTaintFlow
sink(StringUtils.replace(taint(), "search", "replacement", 0)); // $hasTaintFlow
sink(StringUtils.replace("haystack", "search", taint(), 0)); // $hasTaintFlow
sink(StringUtils.replaceAll(taint(), "search", "replacement")); // $hasTaintFlow
sink(StringUtils.replaceAll("haystack", "search", taint())); // $hasTaintFlow
sink(StringUtils.replaceChars(taint(), 'a', 'b')); // $hasTaintFlow
sink(StringUtils.replaceChars(taint(), "abc", "xyz")); // $hasTaintFlow
sink(StringUtils.replaceChars("haystack", "abc", taint())); // $hasTaintFlow
sink(StringUtils.replaceEach(taint(), new String[] { "search" }, new String[] { "replacement" })); // $hasTaintFlow
sink(StringUtils.replaceEach("haystack", new String[] { "search" }, new String[] { taint() })); // $hasTaintFlow
sink(StringUtils.replaceEachRepeatedly(taint(), new String[] { "search" }, new String[] { "replacement" })); // $hasTaintFlow
sink(StringUtils.replaceEachRepeatedly("haystack", new String[] { "search" }, new String[] { taint() })); // $hasTaintFlow
sink(StringUtils.replaceFirst(taint(), "search", "replacement")); // $hasTaintFlow
sink(StringUtils.replaceFirst("haystack", "search", taint())); // $hasTaintFlow
sink(StringUtils.replaceIgnoreCase(taint(), "search", "replacement")); // $hasTaintFlow
sink(StringUtils.replaceIgnoreCase("haystack", "search", taint())); // $hasTaintFlow
sink(StringUtils.replaceOnce(taint(), "search", "replacement")); // $hasTaintFlow
sink(StringUtils.replaceOnce("haystack", "search", taint())); // $hasTaintFlow
sink(StringUtils.replaceOnceIgnoreCase(taint(), "search", "replacement")); // $hasTaintFlow
sink(StringUtils.replaceOnceIgnoreCase("haystack", "search", taint())); // $hasTaintFlow
sink(StringUtils.replacePattern(taint(), "search", "replacement")); // $hasTaintFlow
sink(StringUtils.replacePattern("haystack", "search", taint())); // $hasTaintFlow
// GOOD (next 11 calls): searched string in replace methods does not flow to the return value.
sink(StringUtils.replace("haystack", taint(), "replacement"));
sink(StringUtils.replace("haystack", taint(), "replacement", 0));
@@ -182,28 +182,28 @@ class Test {
sink(StringUtils.replaceOnce("haystack", taint(), "replacement"));
sink(StringUtils.replaceOnceIgnoreCase("haystack", taint(), "replacement"));
sink(StringUtils.replacePattern("haystack", taint(), "replacement"));
sink(StringUtils.reverse(taint())); // $hasTaintFlow=y
sink(StringUtils.reverseDelimited(taint(), ',')); // $hasTaintFlow=y
sink(StringUtils.right(taint(), 0)); // $hasTaintFlow=y
sink(StringUtils.rightPad(taint(), 0)); // $hasTaintFlow=y
sink(StringUtils.rightPad(taint(), 0, ' ')); // $hasTaintFlow=y
sink(StringUtils.rightPad(taint(), 0, "padding")); // $hasTaintFlow=y
sink(StringUtils.rightPad("to pad", 0, taint())); // $hasTaintFlow=y
sink(StringUtils.rotate(taint(), 0)); // $hasTaintFlow=y
sink(StringUtils.split(taint())); // $hasTaintFlow=y
sink(StringUtils.split(taint(), ' ')); // $hasTaintFlow=y
sink(StringUtils.split(taint(), " ,; // $hasTaintFlow=y")); // $hasTaintFlow=y
sink(StringUtils.split(taint(), " ,; // $hasTaintFlow=y", 0)); // $hasTaintFlow=y
sink(StringUtils.splitByCharacterType(taint())); // $hasTaintFlow=y
sink(StringUtils.splitByCharacterTypeCamelCase(taint())); // $hasTaintFlow=y
sink(StringUtils.splitByWholeSeparator(taint(), "separator")); // $hasTaintFlow=y
sink(StringUtils.splitByWholeSeparator(taint(), "separator", 0)); // $hasTaintFlow=y
sink(StringUtils.splitByWholeSeparatorPreserveAllTokens(taint(), "separator")); // $hasTaintFlow=y
sink(StringUtils.splitByWholeSeparatorPreserveAllTokens(taint(), "separator", 0)); // $hasTaintFlow=y
sink(StringUtils.splitPreserveAllTokens(taint())); // $hasTaintFlow=y
sink(StringUtils.splitPreserveAllTokens(taint(), ' ')); // $hasTaintFlow=y
sink(StringUtils.splitPreserveAllTokens(taint(), " ,;")); // $hasTaintFlow=y
sink(StringUtils.splitPreserveAllTokens(taint(), " ,;", 0)); // $hasTaintFlow=y
sink(StringUtils.reverse(taint())); // $hasTaintFlow
sink(StringUtils.reverseDelimited(taint(), ',')); // $hasTaintFlow
sink(StringUtils.right(taint(), 0)); // $hasTaintFlow
sink(StringUtils.rightPad(taint(), 0)); // $hasTaintFlow
sink(StringUtils.rightPad(taint(), 0, ' ')); // $hasTaintFlow
sink(StringUtils.rightPad(taint(), 0, "padding")); // $hasTaintFlow
sink(StringUtils.rightPad("to pad", 0, taint())); // $hasTaintFlow
sink(StringUtils.rotate(taint(), 0)); // $hasTaintFlow
sink(StringUtils.split(taint())); // $hasTaintFlow
sink(StringUtils.split(taint(), ' ')); // $hasTaintFlow
sink(StringUtils.split(taint(), " ,; // $hasTaintFlow")); // $hasTaintFlow
sink(StringUtils.split(taint(), " ,; // $hasTaintFlow", 0)); // $hasTaintFlow
sink(StringUtils.splitByCharacterType(taint())); // $hasTaintFlow
sink(StringUtils.splitByCharacterTypeCamelCase(taint())); // $hasTaintFlow
sink(StringUtils.splitByWholeSeparator(taint(), "separator")); // $hasTaintFlow
sink(StringUtils.splitByWholeSeparator(taint(), "separator", 0)); // $hasTaintFlow
sink(StringUtils.splitByWholeSeparatorPreserveAllTokens(taint(), "separator")); // $hasTaintFlow
sink(StringUtils.splitByWholeSeparatorPreserveAllTokens(taint(), "separator", 0)); // $hasTaintFlow
sink(StringUtils.splitPreserveAllTokens(taint())); // $hasTaintFlow
sink(StringUtils.splitPreserveAllTokens(taint(), ' ')); // $hasTaintFlow
sink(StringUtils.splitPreserveAllTokens(taint(), " ,;")); // $hasTaintFlow
sink(StringUtils.splitPreserveAllTokens(taint(), " ,;", 0)); // $hasTaintFlow
// GOOD (next 8 calls): separators don't propagate to the return value
sink(StringUtils.split("to split", taint()));
sink(StringUtils.split("to split", taint(), 0));
@@ -213,30 +213,30 @@ class Test {
sink(StringUtils.splitByWholeSeparatorPreserveAllTokens("to split", taint()));
sink(StringUtils.splitByWholeSeparatorPreserveAllTokens("to split", taint(), 0));
sink(StringUtils.splitPreserveAllTokens("to split", taint()));
sink(StringUtils.strip(taint())); // $hasTaintFlow=y
sink(StringUtils.strip(taint(), "charstoremove")); // $hasTaintFlow=y
sink(StringUtils.stripAccents(taint())); // $hasTaintFlow=y
sink(StringUtils.stripAll(new String[] { taint() }, "charstoremove")); // $hasTaintFlow=y
sink(StringUtils.stripEnd(taint(), "charstoremove")); // $hasTaintFlow=y
sink(StringUtils.stripStart(taint(), "charstoremove")); // $hasTaintFlow=y
sink(StringUtils.strip(taint())); // $hasTaintFlow
sink(StringUtils.strip(taint(), "charstoremove")); // $hasTaintFlow
sink(StringUtils.stripAccents(taint())); // $hasTaintFlow
sink(StringUtils.stripAll(new String[] { taint() }, "charstoremove")); // $hasTaintFlow
sink(StringUtils.stripEnd(taint(), "charstoremove")); // $hasTaintFlow
sink(StringUtils.stripStart(taint(), "charstoremove")); // $hasTaintFlow
// GOOD (next 4 calls): stripped chars do not flow to the return value.
sink(StringUtils.strip("original text", taint()));
sink(StringUtils.stripAll(new String[] { "original text" }, taint()));
sink(StringUtils.stripEnd("original text", taint()));
sink(StringUtils.stripStart("original text", taint()));
sink(StringUtils.stripToEmpty(taint())); // $hasTaintFlow=y
sink(StringUtils.stripToNull(taint())); // $hasTaintFlow=y
sink(StringUtils.substring(taint(), 0)); // $hasTaintFlow=y
sink(StringUtils.substring(taint(), 0, 0)); // $hasTaintFlow=y
sink(StringUtils.substringAfter(taint(), 0)); // $hasTaintFlow=y
sink(StringUtils.substringAfter(taint(), "separator")); // $hasTaintFlow=y
sink(StringUtils.substringAfterLast(taint(), 0)); // $hasTaintFlow=y
sink(StringUtils.substringAfterLast(taint(), "separator")); // $hasTaintFlow=y
sink(StringUtils.substringBefore(taint(), "separator")); // $hasTaintFlow=y
sink(StringUtils.substringBeforeLast(taint(), "separator")); // $hasTaintFlow=y
sink(StringUtils.substringBetween(taint(), "separator")); // $hasTaintFlow=y
sink(StringUtils.substringBetween(taint(), "start-tag", "end-tag")); // $hasTaintFlow=y
sink(StringUtils.substringsBetween(taint(), "start-tag", "end-tag")[0]); // $hasTaintFlow=y
sink(StringUtils.stripToEmpty(taint())); // $hasTaintFlow
sink(StringUtils.stripToNull(taint())); // $hasTaintFlow
sink(StringUtils.substring(taint(), 0)); // $hasTaintFlow
sink(StringUtils.substring(taint(), 0, 0)); // $hasTaintFlow
sink(StringUtils.substringAfter(taint(), 0)); // $hasTaintFlow
sink(StringUtils.substringAfter(taint(), "separator")); // $hasTaintFlow
sink(StringUtils.substringAfterLast(taint(), 0)); // $hasTaintFlow
sink(StringUtils.substringAfterLast(taint(), "separator")); // $hasTaintFlow
sink(StringUtils.substringBefore(taint(), "separator")); // $hasTaintFlow
sink(StringUtils.substringBeforeLast(taint(), "separator")); // $hasTaintFlow
sink(StringUtils.substringBetween(taint(), "separator")); // $hasTaintFlow
sink(StringUtils.substringBetween(taint(), "start-tag", "end-tag")); // $hasTaintFlow
sink(StringUtils.substringsBetween(taint(), "start-tag", "end-tag")[0]); // $hasTaintFlow
// GOOD (next 9 calls): separators and bounding tags do not flow to the return value.
sink(StringUtils.substringAfter("original text", taint()));
sink(StringUtils.substringAfterLast("original text", taint()));
@@ -247,31 +247,31 @@ class Test {
sink(StringUtils.substringBetween("original text", "start-tag", taint()));
sink(StringUtils.substringsBetween("original text", taint(), "end-tag")[0]);
sink(StringUtils.substringsBetween("original text", "start-tag", taint())[0]);
sink(StringUtils.swapCase(taint())); // $hasTaintFlow=y
sink(StringUtils.toCodePoints(taint())); // $hasTaintFlow=y
sink(StringUtils.toEncodedString(StringUtils.getBytes(taint(), "charset"), null)); // $hasTaintFlow=y
sink(StringUtils.toRootLowerCase(taint())); // $hasTaintFlow=y
sink(StringUtils.toRootUpperCase(taint())); // $hasTaintFlow=y
sink(StringUtils.toString(StringUtils.getBytes(taint(), "charset"), "charset")); // $hasTaintFlow=y
sink(StringUtils.trim(taint())); // $hasTaintFlow=y
sink(StringUtils.trimToEmpty(taint())); // $hasTaintFlow=y
sink(StringUtils.trimToNull(taint())); // $hasTaintFlow=y
sink(StringUtils.truncate(taint(), 0)); // $hasTaintFlow=y
sink(StringUtils.truncate(taint(), 0, 0)); // $hasTaintFlow=y
sink(StringUtils.uncapitalize(taint())); // $hasTaintFlow=y
sink(StringUtils.unwrap(taint(), '"')); // $hasTaintFlow=y
sink(StringUtils.unwrap(taint(), "separator")); // $hasTaintFlow=y
sink(StringUtils.swapCase(taint())); // $hasTaintFlow
sink(StringUtils.toCodePoints(taint())); // $hasTaintFlow
sink(StringUtils.toEncodedString(StringUtils.getBytes(taint(), "charset"), null)); // $hasTaintFlow
sink(StringUtils.toRootLowerCase(taint())); // $hasTaintFlow
sink(StringUtils.toRootUpperCase(taint())); // $hasTaintFlow
sink(StringUtils.toString(StringUtils.getBytes(taint(), "charset"), "charset")); // $hasTaintFlow
sink(StringUtils.trim(taint())); // $hasTaintFlow
sink(StringUtils.trimToEmpty(taint())); // $hasTaintFlow
sink(StringUtils.trimToNull(taint())); // $hasTaintFlow
sink(StringUtils.truncate(taint(), 0)); // $hasTaintFlow
sink(StringUtils.truncate(taint(), 0, 0)); // $hasTaintFlow
sink(StringUtils.uncapitalize(taint())); // $hasTaintFlow
sink(StringUtils.unwrap(taint(), '"')); // $hasTaintFlow
sink(StringUtils.unwrap(taint(), "separator")); // $hasTaintFlow
// GOOD: the wrapper string does not flow to the return value.
sink(StringUtils.unwrap("original string", taint()));
sink(StringUtils.upperCase(taint())); // $hasTaintFlow=y
sink(StringUtils.upperCase(taint(), null)); // $hasTaintFlow=y
sink(StringUtils.valueOf(taint().toCharArray())); // $hasTaintFlow=y
sink(StringUtils.wrap(taint(), '"')); // $hasTaintFlow=y
sink(StringUtils.wrap(taint(), "wrapper token")); // $hasTaintFlow=y
sink(StringUtils.wrap("wrap me", taint())); // $hasTaintFlow=y
sink(StringUtils.wrapIfMissing(taint(), '"')); // $hasTaintFlow=y
sink(StringUtils.wrapIfMissing(taint(), "wrapper token")); // $hasTaintFlow=y
sink(StringUtils.wrapIfMissing("wrap me", taint())); // $hasTaintFlow=y
sink(StringUtils.upperCase(taint())); // $hasTaintFlow
sink(StringUtils.upperCase(taint(), null)); // $hasTaintFlow
sink(StringUtils.valueOf(taint().toCharArray())); // $hasTaintFlow
sink(StringUtils.wrap(taint(), '"')); // $hasTaintFlow
sink(StringUtils.wrap(taint(), "wrapper token")); // $hasTaintFlow
sink(StringUtils.wrap("wrap me", taint())); // $hasTaintFlow
sink(StringUtils.wrapIfMissing(taint(), '"')); // $hasTaintFlow
sink(StringUtils.wrapIfMissing(taint(), "wrapper token")); // $hasTaintFlow
sink(StringUtils.wrapIfMissing("wrap me", taint())); // $hasTaintFlow
}

View File

@@ -14,121 +14,121 @@ class TextStringBuilderTest {
void test() throws Exception {
TextStringBuilder cons1 = new TextStringBuilder(taint()); sink(cons1.toString()); // $hasTaintFlow=y
TextStringBuilder cons2 = new TextStringBuilder((CharSequence)taint()); sink(cons2.toString()); // $hasTaintFlow=y
TextStringBuilder cons1 = new TextStringBuilder(taint()); sink(cons1.toString()); // $hasTaintFlow
TextStringBuilder cons2 = new TextStringBuilder((CharSequence)taint()); sink(cons2.toString()); // $hasTaintFlow
TextStringBuilder sb1 = new TextStringBuilder(); sb1.append(taint().toCharArray()); sink(sb1.toString()); // $hasTaintFlow=y
TextStringBuilder sb2 = new TextStringBuilder(); sb2.append(taint().toCharArray(), 0, 0); sink(sb2.toString()); // $hasTaintFlow=y
TextStringBuilder sb3 = new TextStringBuilder(); sb3.append(CharBuffer.wrap(taint().toCharArray())); sink(sb3.toString()); // $ MISSING: hasTaintFlow=y
TextStringBuilder sb4 = new TextStringBuilder(); sb4.append(CharBuffer.wrap(taint().toCharArray()), 0, 0); sink(sb4.toString()); // $ MISSING: hasTaintFlow=y
TextStringBuilder sb5 = new TextStringBuilder(); sb5.append((CharSequence)taint()); sink(sb5.toString()); // $hasTaintFlow=y
TextStringBuilder sb6 = new TextStringBuilder(); sb6.append((CharSequence)taint(), 0, 0); sink(sb6.toString()); // $hasTaintFlow=y
TextStringBuilder sb7 = new TextStringBuilder(); sb7.append((Object)taint()); sink(sb7.toString()); // $hasTaintFlow=y
TextStringBuilder sb1 = new TextStringBuilder(); sb1.append(taint().toCharArray()); sink(sb1.toString()); // $hasTaintFlow
TextStringBuilder sb2 = new TextStringBuilder(); sb2.append(taint().toCharArray(), 0, 0); sink(sb2.toString()); // $hasTaintFlow
TextStringBuilder sb3 = new TextStringBuilder(); sb3.append(CharBuffer.wrap(taint().toCharArray())); sink(sb3.toString()); // $ MISSING: hasTaintFlow
TextStringBuilder sb4 = new TextStringBuilder(); sb4.append(CharBuffer.wrap(taint().toCharArray()), 0, 0); sink(sb4.toString()); // $ MISSING: hasTaintFlow
TextStringBuilder sb5 = new TextStringBuilder(); sb5.append((CharSequence)taint()); sink(sb5.toString()); // $hasTaintFlow
TextStringBuilder sb6 = new TextStringBuilder(); sb6.append((CharSequence)taint(), 0, 0); sink(sb6.toString()); // $hasTaintFlow
TextStringBuilder sb7 = new TextStringBuilder(); sb7.append((Object)taint()); sink(sb7.toString()); // $hasTaintFlow
{
TextStringBuilder auxsb = new TextStringBuilder(); auxsb.append(taint());
TextStringBuilder sb8 = new TextStringBuilder(); sb8.append(auxsb); sink(sb8.toString()); // $hasTaintFlow=y
TextStringBuilder sb8 = new TextStringBuilder(); sb8.append(auxsb); sink(sb8.toString()); // $hasTaintFlow
}
TextStringBuilder sb9 = new TextStringBuilder(); sb9.append(new StringBuffer(taint())); sink(sb9.toString()); // $hasTaintFlow=y
TextStringBuilder sb10 = new TextStringBuilder(); sb10.append(new StringBuffer(taint()), 0, 0); sink(sb10.toString()); // $hasTaintFlow=y
TextStringBuilder sb11 = new TextStringBuilder(); sb11.append(new StringBuilder(taint())); sink(sb11.toString()); // $hasTaintFlow=y
TextStringBuilder sb12 = new TextStringBuilder(); sb12.append(new StringBuilder(taint()), 0, 0); sink(sb12.toString()); // $hasTaintFlow=y
TextStringBuilder sb13 = new TextStringBuilder(); sb13.append(taint()); sink(sb13.toString()); // $hasTaintFlow=y
TextStringBuilder sb14 = new TextStringBuilder(); sb14.append(taint(), 0, 0); sink(sb14.toString()); // $hasTaintFlow=y
TextStringBuilder sb15 = new TextStringBuilder(); sb15.append(taint(), "format", "args"); sink(sb15.toString()); // $hasTaintFlow=y
TextStringBuilder sb16 = new TextStringBuilder(); sb16.append("Format string", taint(), "args"); sink(sb16.toString()); // $hasTaintFlow=y
TextStringBuilder sb9 = new TextStringBuilder(); sb9.append(new StringBuffer(taint())); sink(sb9.toString()); // $hasTaintFlow
TextStringBuilder sb10 = new TextStringBuilder(); sb10.append(new StringBuffer(taint()), 0, 0); sink(sb10.toString()); // $hasTaintFlow
TextStringBuilder sb11 = new TextStringBuilder(); sb11.append(new StringBuilder(taint())); sink(sb11.toString()); // $hasTaintFlow
TextStringBuilder sb12 = new TextStringBuilder(); sb12.append(new StringBuilder(taint()), 0, 0); sink(sb12.toString()); // $hasTaintFlow
TextStringBuilder sb13 = new TextStringBuilder(); sb13.append(taint()); sink(sb13.toString()); // $hasTaintFlow
TextStringBuilder sb14 = new TextStringBuilder(); sb14.append(taint(), 0, 0); sink(sb14.toString()); // $hasTaintFlow
TextStringBuilder sb15 = new TextStringBuilder(); sb15.append(taint(), "format", "args"); sink(sb15.toString()); // $hasTaintFlow
TextStringBuilder sb16 = new TextStringBuilder(); sb16.append("Format string", taint(), "args"); sink(sb16.toString()); // $hasTaintFlow
{
List<String> taintedList = new ArrayList<>();
taintedList.add(taint());
TextStringBuilder sb17 = new TextStringBuilder(); sb17.appendAll(taintedList); sink(sb17.toString()); // $hasTaintFlow=y
TextStringBuilder sb18 = new TextStringBuilder(); sb18.appendAll(taintedList.iterator()); sink(sb18.toString()); // $hasTaintFlow=y
TextStringBuilder sb17 = new TextStringBuilder(); sb17.appendAll(taintedList); sink(sb17.toString()); // $hasTaintFlow
TextStringBuilder sb18 = new TextStringBuilder(); sb18.appendAll(taintedList.iterator()); sink(sb18.toString()); // $hasTaintFlow
}
TextStringBuilder sb19 = new TextStringBuilder(); sb19.appendAll("clean", taint()); sink(sb19.toString()); // $hasTaintFlow=y
TextStringBuilder sb20 = new TextStringBuilder(); sb20.appendAll(taint(), "clean"); sink(sb20.toString()); // $hasTaintFlow=y
TextStringBuilder sb21 = new TextStringBuilder(); sb21.appendFixedWidthPadLeft(taint(), 0, ' '); sink(sb21.toString()); // $hasTaintFlow=y
TextStringBuilder sb22 = new TextStringBuilder(); sb22.appendFixedWidthPadRight(taint(), 0, ' '); sink(sb22.toString()); // $hasTaintFlow=y
TextStringBuilder sb23 = new TextStringBuilder(); sb23.appendln(taint().toCharArray()); sink(sb23.toString()); // $hasTaintFlow=y
TextStringBuilder sb24 = new TextStringBuilder(); sb24.appendln(taint().toCharArray(), 0, 0); sink(sb24.toString()); // $hasTaintFlow=y
TextStringBuilder sb25 = new TextStringBuilder(); sb25.appendln((Object)taint()); sink(sb25.toString()); // $hasTaintFlow=y
TextStringBuilder sb19 = new TextStringBuilder(); sb19.appendAll("clean", taint()); sink(sb19.toString()); // $hasTaintFlow
TextStringBuilder sb20 = new TextStringBuilder(); sb20.appendAll(taint(), "clean"); sink(sb20.toString()); // $hasTaintFlow
TextStringBuilder sb21 = new TextStringBuilder(); sb21.appendFixedWidthPadLeft(taint(), 0, ' '); sink(sb21.toString()); // $hasTaintFlow
TextStringBuilder sb22 = new TextStringBuilder(); sb22.appendFixedWidthPadRight(taint(), 0, ' '); sink(sb22.toString()); // $hasTaintFlow
TextStringBuilder sb23 = new TextStringBuilder(); sb23.appendln(taint().toCharArray()); sink(sb23.toString()); // $hasTaintFlow
TextStringBuilder sb24 = new TextStringBuilder(); sb24.appendln(taint().toCharArray(), 0, 0); sink(sb24.toString()); // $hasTaintFlow
TextStringBuilder sb25 = new TextStringBuilder(); sb25.appendln((Object)taint()); sink(sb25.toString()); // $hasTaintFlow
{
TextStringBuilder auxsb = new TextStringBuilder(); auxsb.appendln(taint());
TextStringBuilder sb26 = new TextStringBuilder(); sb26.appendln(auxsb); sink(sb26.toString()); // $hasTaintFlow=y
TextStringBuilder sb26 = new TextStringBuilder(); sb26.appendln(auxsb); sink(sb26.toString()); // $hasTaintFlow
}
TextStringBuilder sb27 = new TextStringBuilder(); sb27.appendln(new StringBuffer(taint())); sink(sb27.toString()); // $hasTaintFlow=y
TextStringBuilder sb28 = new TextStringBuilder(); sb28.appendln(new StringBuffer(taint()), 0, 0); sink(sb28.toString()); // $hasTaintFlow=y
TextStringBuilder sb29 = new TextStringBuilder(); sb29.appendln(new StringBuilder(taint())); sink(sb29.toString()); // $hasTaintFlow=y
TextStringBuilder sb30 = new TextStringBuilder(); sb30.appendln(new StringBuilder(taint()), 0, 0); sink(sb30.toString()); // $hasTaintFlow=y
TextStringBuilder sb31 = new TextStringBuilder(); sb31.appendln(taint()); sink(sb31.toString()); // $hasTaintFlow=y
TextStringBuilder sb32 = new TextStringBuilder(); sb32.appendln(taint(), 0, 0); sink(sb32.toString()); // $hasTaintFlow=y
TextStringBuilder sb33 = new TextStringBuilder(); sb33.appendln(taint(), "format", "args"); sink(sb33.toString()); // $hasTaintFlow=y
TextStringBuilder sb34 = new TextStringBuilder(); sb34.appendln("Format string", taint(), "args"); sink(sb34.toString()); // $hasTaintFlow=y
TextStringBuilder sb35 = new TextStringBuilder(); sb35.appendSeparator(taint()); sink(sb35.toString()); // $hasTaintFlow=y
TextStringBuilder sb36 = new TextStringBuilder(); sb36.appendSeparator(taint(), 0); sink(sb36.toString()); // $hasTaintFlow=y
TextStringBuilder sb37 = new TextStringBuilder(); sb37.appendSeparator(taint(), "default"); sink(sb37.toString()); // $hasTaintFlow=y
TextStringBuilder sb38 = new TextStringBuilder(); sb38.appendSeparator("", taint()); sink(sb38.toString()); // $hasTaintFlow=y
TextStringBuilder sb27 = new TextStringBuilder(); sb27.appendln(new StringBuffer(taint())); sink(sb27.toString()); // $hasTaintFlow
TextStringBuilder sb28 = new TextStringBuilder(); sb28.appendln(new StringBuffer(taint()), 0, 0); sink(sb28.toString()); // $hasTaintFlow
TextStringBuilder sb29 = new TextStringBuilder(); sb29.appendln(new StringBuilder(taint())); sink(sb29.toString()); // $hasTaintFlow
TextStringBuilder sb30 = new TextStringBuilder(); sb30.appendln(new StringBuilder(taint()), 0, 0); sink(sb30.toString()); // $hasTaintFlow
TextStringBuilder sb31 = new TextStringBuilder(); sb31.appendln(taint()); sink(sb31.toString()); // $hasTaintFlow
TextStringBuilder sb32 = new TextStringBuilder(); sb32.appendln(taint(), 0, 0); sink(sb32.toString()); // $hasTaintFlow
TextStringBuilder sb33 = new TextStringBuilder(); sb33.appendln(taint(), "format", "args"); sink(sb33.toString()); // $hasTaintFlow
TextStringBuilder sb34 = new TextStringBuilder(); sb34.appendln("Format string", taint(), "args"); sink(sb34.toString()); // $hasTaintFlow
TextStringBuilder sb35 = new TextStringBuilder(); sb35.appendSeparator(taint()); sink(sb35.toString()); // $hasTaintFlow
TextStringBuilder sb36 = new TextStringBuilder(); sb36.appendSeparator(taint(), 0); sink(sb36.toString()); // $hasTaintFlow
TextStringBuilder sb37 = new TextStringBuilder(); sb37.appendSeparator(taint(), "default"); sink(sb37.toString()); // $hasTaintFlow
TextStringBuilder sb38 = new TextStringBuilder(); sb38.appendSeparator("", taint()); sink(sb38.toString()); // $hasTaintFlow
{
TextStringBuilder auxsb = new TextStringBuilder(); auxsb.appendln(taint());
TextStringBuilder sb39 = new TextStringBuilder(); auxsb.appendTo(sb39); sink(sb39.toString()); // $hasTaintFlow=y
TextStringBuilder sb39 = new TextStringBuilder(); auxsb.appendTo(sb39); sink(sb39.toString()); // $hasTaintFlow
}
{
List<String> taintedList = new ArrayList<>();
taintedList.add(taint());
TextStringBuilder sb40 = new TextStringBuilder(); sb40.appendWithSeparators(taintedList, ", "); sink(sb40.toString()); // $hasTaintFlow=y
TextStringBuilder sb41 = new TextStringBuilder(); sb41.appendWithSeparators(taintedList.iterator(), ", "); sink(sb41.toString()); // $hasTaintFlow=y
TextStringBuilder sb40 = new TextStringBuilder(); sb40.appendWithSeparators(taintedList, ", "); sink(sb40.toString()); // $hasTaintFlow
TextStringBuilder sb41 = new TextStringBuilder(); sb41.appendWithSeparators(taintedList.iterator(), ", "); sink(sb41.toString()); // $hasTaintFlow
List<String> untaintedList = new ArrayList<>();
TextStringBuilder sb42 = new TextStringBuilder(); sb42.appendWithSeparators(untaintedList, taint()); sink(sb42.toString()); // $hasTaintFlow=y
TextStringBuilder sb43 = new TextStringBuilder(); sb43.appendWithSeparators(untaintedList.iterator(), taint()); sink(sb43.toString()); // $hasTaintFlow=y
TextStringBuilder sb42 = new TextStringBuilder(); sb42.appendWithSeparators(untaintedList, taint()); sink(sb42.toString()); // $hasTaintFlow
TextStringBuilder sb43 = new TextStringBuilder(); sb43.appendWithSeparators(untaintedList.iterator(), taint()); sink(sb43.toString()); // $hasTaintFlow
String[] taintedArray = new String[] { taint() };
String[] untaintedArray = new String[] {};
TextStringBuilder sb44 = new TextStringBuilder(); sb44.appendWithSeparators(taintedArray, ", "); sink(sb44.toString()); // $hasTaintFlow=y
TextStringBuilder sb45 = new TextStringBuilder(); sb45.appendWithSeparators(untaintedArray, taint()); sink(sb45.toString()); // $hasTaintFlow=y
TextStringBuilder sb44 = new TextStringBuilder(); sb44.appendWithSeparators(taintedArray, ", "); sink(sb44.toString()); // $hasTaintFlow
TextStringBuilder sb45 = new TextStringBuilder(); sb45.appendWithSeparators(untaintedArray, taint()); sink(sb45.toString()); // $hasTaintFlow
}
{
TextStringBuilder sb46 = new TextStringBuilder(); sb46.append(taint());
char[] target = new char[100];
sb46.asReader().read(target);
sink(target); // $hasTaintFlow=y
sink(target); // $hasTaintFlow
}
TextStringBuilder sb47 = new TextStringBuilder(); sb47.append(taint()); sink(sb47.asTokenizer().next()); // $hasTaintFlow=y
TextStringBuilder sb48 = new TextStringBuilder(); sb48.append(taint()); sink(sb48.build()); // $hasTaintFlow=y
TextStringBuilder sb49 = new TextStringBuilder(); sb49.append(taint()); sink(sb49.getChars(null)); // $hasTaintFlow=y
TextStringBuilder sb47 = new TextStringBuilder(); sb47.append(taint()); sink(sb47.asTokenizer().next()); // $hasTaintFlow
TextStringBuilder sb48 = new TextStringBuilder(); sb48.append(taint()); sink(sb48.build()); // $hasTaintFlow
TextStringBuilder sb49 = new TextStringBuilder(); sb49.append(taint()); sink(sb49.getChars(null)); // $hasTaintFlow
{
TextStringBuilder sb50 = new TextStringBuilder(); sb50.append(taint());
char[] target = new char[100];
sb50.getChars(target);
sink(target); // $hasTaintFlow=y
sink(target); // $hasTaintFlow
}
{
TextStringBuilder sb51 = new TextStringBuilder(); sb51.append(taint());
char[] target = new char[100];
sb51.getChars(0, 0, target, 0);
sink(target); // $hasTaintFlow=y
sink(target); // $hasTaintFlow
}
TextStringBuilder sb52 = new TextStringBuilder(); sb52.insert(0, taint().toCharArray()); sink(sb52.toString()); // $hasTaintFlow=y
TextStringBuilder sb53 = new TextStringBuilder(); sb53.insert(0, taint().toCharArray(), 0, 0); sink(sb53.toString()); // $hasTaintFlow=y
TextStringBuilder sb54 = new TextStringBuilder(); sb54.insert(0, taint()); sink(sb54.toString()); // $hasTaintFlow=y
TextStringBuilder sb55 = new TextStringBuilder(); sb55.insert(0, (Object)taint()); sink(sb55.toString()); // $hasTaintFlow=y
TextStringBuilder sb56 = new TextStringBuilder(); sb56.append(taint()); sink(sb56.leftString(0)); // $hasTaintFlow=y
TextStringBuilder sb57 = new TextStringBuilder(); sb57.append(taint()); sink(sb57.midString(0, 0)); // $hasTaintFlow=y
TextStringBuilder sb52 = new TextStringBuilder(); sb52.insert(0, taint().toCharArray()); sink(sb52.toString()); // $hasTaintFlow
TextStringBuilder sb53 = new TextStringBuilder(); sb53.insert(0, taint().toCharArray(), 0, 0); sink(sb53.toString()); // $hasTaintFlow
TextStringBuilder sb54 = new TextStringBuilder(); sb54.insert(0, taint()); sink(sb54.toString()); // $hasTaintFlow
TextStringBuilder sb55 = new TextStringBuilder(); sb55.insert(0, (Object)taint()); sink(sb55.toString()); // $hasTaintFlow
TextStringBuilder sb56 = new TextStringBuilder(); sb56.append(taint()); sink(sb56.leftString(0)); // $hasTaintFlow
TextStringBuilder sb57 = new TextStringBuilder(); sb57.append(taint()); sink(sb57.midString(0, 0)); // $hasTaintFlow
{
StringReader reader = new StringReader(taint());
TextStringBuilder sb58 = new TextStringBuilder(); sb58.readFrom(reader); sink(sb58.toString()); // $hasTaintFlow=y
TextStringBuilder sb58 = new TextStringBuilder(); sb58.readFrom(reader); sink(sb58.toString()); // $hasTaintFlow
}
TextStringBuilder sb59 = new TextStringBuilder(); sb59.replace(0, 0, taint()); sink(sb59.toString()); // $hasTaintFlow=y
TextStringBuilder sb60 = new TextStringBuilder(); sb60.replace(null, taint(), 0, 0, 0); sink(sb60.toString()); // $hasTaintFlow=y
TextStringBuilder sb61 = new TextStringBuilder(); sb61.replaceAll((StringMatcher)null, taint()); sink(sb61.toString()); // $hasTaintFlow=y
TextStringBuilder sb62 = new TextStringBuilder(); sb62.replaceAll("search", taint()); sink(sb62.toString()); // $hasTaintFlow=y
TextStringBuilder sb59 = new TextStringBuilder(); sb59.replace(0, 0, taint()); sink(sb59.toString()); // $hasTaintFlow
TextStringBuilder sb60 = new TextStringBuilder(); sb60.replace(null, taint(), 0, 0, 0); sink(sb60.toString()); // $hasTaintFlow
TextStringBuilder sb61 = new TextStringBuilder(); sb61.replaceAll((StringMatcher)null, taint()); sink(sb61.toString()); // $hasTaintFlow
TextStringBuilder sb62 = new TextStringBuilder(); sb62.replaceAll("search", taint()); sink(sb62.toString()); // $hasTaintFlow
TextStringBuilder sb63 = new TextStringBuilder(); sb63.replaceAll(taint(), "replace"); sink(sb63.toString()); // GOOD (search string doesn't convey taint)
TextStringBuilder sb64 = new TextStringBuilder(); sb64.replaceFirst((StringMatcher)null, taint()); sink(sb64.toString()); // $hasTaintFlow=y
TextStringBuilder sb65 = new TextStringBuilder(); sb65.replaceFirst("search", taint()); sink(sb65.toString()); // $hasTaintFlow=y
TextStringBuilder sb64 = new TextStringBuilder(); sb64.replaceFirst((StringMatcher)null, taint()); sink(sb64.toString()); // $hasTaintFlow
TextStringBuilder sb65 = new TextStringBuilder(); sb65.replaceFirst("search", taint()); sink(sb65.toString()); // $hasTaintFlow
TextStringBuilder sb66 = new TextStringBuilder(); sb66.replaceFirst(taint(), "replace"); sink(sb66.toString()); // GOOD (search string doesn't convey taint)
TextStringBuilder sb67 = new TextStringBuilder(); sb67.append(taint()); sink(sb67.rightString(0)); // $hasTaintFlow=y
TextStringBuilder sb68 = new TextStringBuilder(); sb68.append(taint()); sink(sb68.subSequence(0, 0)); // $hasTaintFlow=y
TextStringBuilder sb69 = new TextStringBuilder(); sb69.append(taint()); sink(sb69.substring(0)); // $hasTaintFlow=y
TextStringBuilder sb70 = new TextStringBuilder(); sb70.append(taint()); sink(sb70.substring(0, 0)); // $hasTaintFlow=y
TextStringBuilder sb71 = new TextStringBuilder(); sb71.append(taint()); sink(sb71.toCharArray()); // $hasTaintFlow=y
TextStringBuilder sb72 = new TextStringBuilder(); sb72.append(taint()); sink(sb72.toCharArray(0, 0)); // $hasTaintFlow=y
TextStringBuilder sb73 = new TextStringBuilder(); sb73.append(taint()); sink(sb73.toStringBuffer()); // $hasTaintFlow=y
TextStringBuilder sb74 = new TextStringBuilder(); sb74.append(taint()); sink(sb74.toStringBuilder()); // $hasTaintFlow=y
TextStringBuilder sb67 = new TextStringBuilder(); sb67.append(taint()); sink(sb67.rightString(0)); // $hasTaintFlow
TextStringBuilder sb68 = new TextStringBuilder(); sb68.append(taint()); sink(sb68.subSequence(0, 0)); // $hasTaintFlow
TextStringBuilder sb69 = new TextStringBuilder(); sb69.append(taint()); sink(sb69.substring(0)); // $hasTaintFlow
TextStringBuilder sb70 = new TextStringBuilder(); sb70.append(taint()); sink(sb70.substring(0, 0)); // $hasTaintFlow
TextStringBuilder sb71 = new TextStringBuilder(); sb71.append(taint()); sink(sb71.toCharArray()); // $hasTaintFlow
TextStringBuilder sb72 = new TextStringBuilder(); sb72.append(taint()); sink(sb72.toCharArray(0, 0)); // $hasTaintFlow
TextStringBuilder sb73 = new TextStringBuilder(); sb73.append(taint()); sink(sb73.toStringBuffer()); // $hasTaintFlow
TextStringBuilder sb74 = new TextStringBuilder(); sb74.append(taint()); sink(sb74.toStringBuilder()); // $hasTaintFlow
}
}

View File

@@ -0,0 +1,26 @@
import org.apache.commons.lang3.text.WordUtils;
public class WordUtilsTest {
String taint() { return "tainted"; }
void sink(Object o) {}
void test() throws Exception {
sink(WordUtils.capitalize(taint())); // $hasTaintFlow
sink(WordUtils.capitalize(taint(), ' ', ',')); // $hasTaintFlow
sink(WordUtils.capitalizeFully(taint())); // $hasTaintFlow
sink(WordUtils.capitalizeFully(taint(), ' ', ',')); // $hasTaintFlow
sink(WordUtils.initials(taint())); // $hasTaintFlow
sink(WordUtils.initials(taint(), ' ', ',')); // $hasTaintFlow
sink(WordUtils.swapCase(taint())); // $hasTaintFlow
sink(WordUtils.uncapitalize(taint())); // $hasTaintFlow
sink(WordUtils.uncapitalize(taint(), ' ', ',')); // $hasTaintFlow
sink(WordUtils.wrap(taint(), 0)); // $hasTaintFlow
sink(WordUtils.wrap(taint(), 0, "\n", false)); // $hasTaintFlow
sink(WordUtils.wrap("wrap me", 0, taint(), false)); // $hasTaintFlow
sink(WordUtils.wrap(taint(), 0, "\n", false, "\n")); // $hasTaintFlow
sink(WordUtils.wrap("wrap me", 0, taint(), false, "\n")); // $hasTaintFlow
// GOOD: the wrap-on line terminator does not propagate to the return value
sink(WordUtils.wrap("wrap me", 0, "\n", false, taint()));
}
}

View File

@@ -0,0 +1,28 @@
import org.apache.commons.text.WordUtils;
public class WordUtilsTextTest {
String taint() { return "tainted"; }
void sink(Object o) {}
void test() throws Exception {
sink(WordUtils.abbreviate(taint(), 0, 0, "append me")); // $hasTaintFlow
sink(WordUtils.abbreviate("abbreviate me", 0, 0, taint())); // $hasTaintFlow
sink(WordUtils.capitalize(taint())); // $hasTaintFlow
sink(WordUtils.capitalize(taint(), ' ', ',')); // $hasTaintFlow
sink(WordUtils.capitalizeFully(taint())); // $hasTaintFlow
sink(WordUtils.capitalizeFully(taint(), ' ', ',')); // $hasTaintFlow
sink(WordUtils.initials(taint())); // $hasTaintFlow
sink(WordUtils.initials(taint(), ' ', ',')); // $hasTaintFlow
sink(WordUtils.swapCase(taint())); // $hasTaintFlow
sink(WordUtils.uncapitalize(taint())); // $hasTaintFlow
sink(WordUtils.uncapitalize(taint(), ' ', ',')); // $hasTaintFlow
sink(WordUtils.wrap(taint(), 0)); // $hasTaintFlow
sink(WordUtils.wrap(taint(), 0, "\n", false)); // $hasTaintFlow
sink(WordUtils.wrap("wrap me", 0, taint(), false)); // $hasTaintFlow
sink(WordUtils.wrap(taint(), 0, "\n", false, "\n")); // $hasTaintFlow
sink(WordUtils.wrap("wrap me", 0, taint(), false, "\n")); // $hasTaintFlow
// GOOD: the wrap-on line terminator does not propagate to the return value
sink(WordUtils.wrap("wrap me", 0, "\n", false, taint()));
}
}

View File

@@ -2,8 +2,20 @@ import java
import semmle.code.java.dataflow.TaintTracking
import TestUtilities.InlineExpectationsTest
class Conf extends TaintTracking::Configuration {
Conf() { this = "qltest:frameworks:apache-commons-lang3" }
class TaintFlowConf extends TaintTracking::Configuration {
TaintFlowConf() { this = "qltest:frameworks:apache-commons-lang3-taint-flow" }
override predicate isSource(DataFlow::Node n) {
n.asExpr().(MethodAccess).getMethod().hasName("taint")
}
override predicate isSink(DataFlow::Node n) {
exists(MethodAccess ma | ma.getMethod().hasName("sink") | n.asExpr() = ma.getAnArgument())
}
}
class ValueFlowConf extends DataFlow::Configuration {
ValueFlowConf() { this = "qltest:frameworks:apache-commons-lang3-value-flow" }
override predicate isSource(DataFlow::Node n) {
n.asExpr().(MethodAccess).getMethod().hasName("taint")
@@ -17,14 +29,22 @@ class Conf extends TaintTracking::Configuration {
class HasFlowTest extends InlineExpectationsTest {
HasFlowTest() { this = "HasFlowTest" }
override string getARelevantTag() { result = "hasTaintFlow" }
override string getARelevantTag() { result = ["hasTaintFlow", "hasValueFlow"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "hasTaintFlow" and
exists(DataFlow::Node src, DataFlow::Node sink, Conf conf | conf.hasFlow(src, sink) |
exists(DataFlow::Node src, DataFlow::Node sink, TaintFlowConf conf | conf.hasFlow(src, sink) |
not any(ValueFlowConf vconf).hasFlow(src, sink) and
sink.getLocation() = location and
element = sink.toString() and
value = "y"
value = ""
)
or
tag = "hasValueFlow" and
exists(DataFlow::Node src, DataFlow::Node sink, ValueFlowConf conf | conf.hasFlow(src, sink) |
sink.getLocation() = location and
element = sink.toString() and
value = ""
)
}
}

View File

@@ -0,0 +1,65 @@
import org.apache.http.*;
import org.apache.http.protocol.*;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.*;
import org.apache.http.entity.*;
import java.io.IOException;
class A {
static Object taint() { return null; }
static void sink(Object o) { }
class Test1 implements HttpRequestHandler {
public void handle(HttpRequest req, HttpResponse res, HttpContext ctx) throws IOException {
A.sink(req.getRequestLine()); //$hasTaintFlow
A.sink(req.getRequestLine().getUri()); //$hasTaintFlow
A.sink(req.getRequestLine().getMethod()); //$hasTaintFlow
A.sink(req.getAllHeaders()); //$hasTaintFlow
HeaderIterator it = req.headerIterator();
A.sink(it.next()); //$hasTaintFlow
A.sink(it.nextHeader()); //$hasTaintFlow
Header h = req.getHeaders("abc")[3];
A.sink(h.getName()); //$hasTaintFlow
A.sink(h.getValue()); //$hasTaintFlow
HeaderElement el = h.getElements()[0];
A.sink(el.getName()); //$hasTaintFlow
A.sink(el.getValue()); //$hasTaintFlow
A.sink(el.getParameters()); //$hasTaintFlow
A.sink(el.getParameterByName("abc").getValue()); //$hasTaintFlow
A.sink(el.getParameter(0).getName()); //$hasTaintFlow
HttpEntity ent = ((HttpEntityEnclosingRequest)req).getEntity();
A.sink(ent.getContent()); //$hasTaintFlow
A.sink(ent.getContentEncoding()); //$hasTaintFlow
A.sink(ent.getContentType()); //$hasTaintFlow
A.sink(EntityUtils.toString(ent)); //$hasTaintFlow
A.sink(EntityUtils.toByteArray(ent)); //$hasTaintFlow
A.sink(EntityUtils.getContentCharSet(ent)); //$hasTaintFlow
A.sink(EntityUtils.getContentMimeType(ent)); //$hasTaintFlow
res.setEntity(new StringEntity("<a href='" + req.getRequestLine().getUri() + "'>a</a>")); //$hasTaintFlow
EntityUtils.updateEntity(res, new ByteArrayEntity(EntityUtils.toByteArray(ent))); //$hasTaintFlow
res.setHeader("Location", req.getRequestLine().getUri()); //$hasTaintFlow
res.setHeader(new BasicHeader("Location", req.getRequestLine().getUri())); //$hasTaintFlow
}
}
void test2() {
ByteArrayBuffer bbuf = new ByteArrayBuffer(42);
bbuf.append((byte[]) taint(), 0, 3);
sink(bbuf.buffer()); //$hasTaintFlow
sink(bbuf.toByteArray()); //$hasTaintFlow
CharArrayBuffer cbuf = new CharArrayBuffer(42);
cbuf.append(bbuf.toByteArray(), 0, 3);
sink(cbuf.toCharArray()); //$hasTaintFlow
sink(cbuf.toString()); //$hasTaintFlow
sink(cbuf.subSequence(0, 3)); //$hasTaintFlow
sink(cbuf.substring(0, 3)); //$hasTaintFlow
sink(cbuf.substringTrimmed(0, 3)); //$hasTaintFlow
sink(Args.notNull(taint(), "x")); //$hasTaintFlow
sink(Args.notEmpty((String) taint(), "x")); //$hasTaintFlow
sink(Args.notBlank((String) taint(), "x")); //$hasTaintFlow
sink(Args.notNull("x", (String) taint())); // Good
}
}

View File

@@ -0,0 +1,76 @@
import org.apache.hc.core5.http.*;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.http.io.HttpRequestHandler;
import org.apache.hc.core5.http.io.HttpServerRequestHandler;
import org.apache.hc.core5.http.message.*;
import org.apache.hc.core5.http.io.entity.*;
import org.apache.hc.core5.util.*;
import java.io.IOException;
class B {
static Object taint() { return null; }
static void sink(Object o) { }
class Test1 implements HttpRequestHandler {
public void handle(ClassicHttpRequest req, ClassicHttpResponse res, HttpContext ctx) throws IOException, ParseException {
B.sink(req.getAuthority().getHostName()); //$hasTaintFlow
B.sink(req.getAuthority().toString()); //$hasTaintFlow
B.sink(req.getMethod()); //$hasTaintFlow
B.sink(req.getPath()); //$hasTaintFlow
B.sink(req.getScheme());
B.sink(req.getRequestUri()); //$hasTaintFlow
RequestLine line = new RequestLine(req);
B.sink(line.getUri()); //$hasTaintFlow
B.sink(line.getMethod()); //$hasTaintFlow
B.sink(req.getHeaders()); //$hasTaintFlow
B.sink(req.headerIterator()); //$hasTaintFlow
Header h = req.getHeaders("abc")[3];
B.sink(h.getName()); //$hasTaintFlow
B.sink(h.getValue()); //$hasTaintFlow
B.sink(req.getFirstHeader("abc")); //$hasTaintFlow
B.sink(req.getLastHeader("abc")); //$hasTaintFlow
HttpEntity ent = req.getEntity();
B.sink(ent.getContent()); //$hasTaintFlow
B.sink(ent.getContentEncoding()); //$hasTaintFlow
B.sink(ent.getContentType()); //$hasTaintFlow
B.sink(ent.getTrailerNames()); //$hasTaintFlow
B.sink(ent.getTrailers().get()); //$hasTaintFlow
B.sink(EntityUtils.toString(ent)); //$hasTaintFlow
B.sink(EntityUtils.toByteArray(ent)); //$hasTaintFlow
B.sink(EntityUtils.parse(ent)); //$hasTaintFlow
res.setEntity(new StringEntity("<a href='" + req.getRequestUri() + "'>a</a>")); //$hasTaintFlow
res.setEntity(new ByteArrayEntity(EntityUtils.toByteArray(ent), ContentType.TEXT_HTML)); //$hasTaintFlow
res.setEntity(HttpEntities.create("<a href='" + req.getRequestUri() + "'>a</a>")); //$hasTaintFlow
res.setHeader("Location", req.getRequestUri()); //$hasTaintFlow
res.setHeader(new BasicHeader("Location", req.getRequestUri())); //$hasTaintFlow
}
}
void test2() {
ByteArrayBuffer bbuf = new ByteArrayBuffer(42);
bbuf.append((byte[]) taint(), 0, 3);
sink(bbuf.array()); //$hasTaintFlow
sink(bbuf.toByteArray()); //$hasTaintFlow
sink(bbuf.toString());
CharArrayBuffer cbuf = new CharArrayBuffer(42);
cbuf.append(bbuf.toByteArray(), 0, 3);
sink(cbuf.toCharArray()); //$hasTaintFlow
sink(cbuf.toString()); //$hasTaintFlow
sink(cbuf.subSequence(0, 3)); //$hasTaintFlow
sink(cbuf.substring(0, 3)); //$hasTaintFlow
sink(cbuf.substringTrimmed(0, 3)); //$hasTaintFlow
sink(Args.notNull(taint(), "x")); //$hasTaintFlow
sink(Args.notEmpty((String) taint(), "x")); //$hasTaintFlow
sink(Args.notBlank((String) taint(), "x")); //$hasTaintFlow
sink(Args.notNull("x", (String) taint()));
}
class Test3 implements HttpServerRequestHandler {
public void handle(ClassicHttpRequest req, HttpServerRequestHandler.ResponseTrigger restr, HttpContext ctx) throws HttpException, IOException {
B.sink(req.getEntity()); //$hasTaintFlow
}
}
}

View File

@@ -0,0 +1,39 @@
import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.XSS
import semmle.code.java.security.UrlRedirect
import TestUtilities.InlineExpectationsTest
class Conf extends TaintTracking::Configuration {
Conf() { this = "qltest:frameworks:apache-http" }
override predicate isSource(DataFlow::Node n) {
n.asExpr().(MethodAccess).getMethod().hasName("taint")
or
n instanceof RemoteFlowSource
}
override predicate isSink(DataFlow::Node n) {
exists(MethodAccess ma | ma.getMethod().hasName("sink") | n.asExpr() = ma.getAnArgument())
or
n instanceof XssSink
or
n instanceof UrlRedirectSink
}
}
class HasFlowTest extends InlineExpectationsTest {
HasFlowTest() { this = "HasFlowTest" }
override string getARelevantTag() { result = "hasTaintFlow" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "hasTaintFlow" and
exists(DataFlow::Node src, DataFlow::Node sink, Conf conf | conf.hasFlow(src, sink) |
sink.getLocation() = location and
element = sink.toString() and
value = ""
)
}
}

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/apache-http-4.4.13:${testdir}/../../../stubs/apache-http-5

View File

@@ -0,0 +1,63 @@
package com.google.common.base;
import java.util.Map;
import java.util.HashMap;
class TestBase {
String taint() { return "tainted"; }
void sink(Object o) {}
void test1() {
String x = taint();
sink(Strings.padStart(x, 10, ' ')); // $numTaintFlow=1
sink(Strings.padEnd(x, 10, ' ')); // $numTaintFlow=1
sink(Strings.repeat(x, 3)); // $numTaintFlow=1
sink(Strings.emptyToNull(Strings.nullToEmpty(x))); // $numTaintFlow=1
sink(Strings.lenientFormat(x, 3)); // $numTaintFlow=1
sink(Strings.commonPrefix(x, "abc"));
sink(Strings.commonSuffix(x, "cde"));
sink(Strings.lenientFormat("%s = %s", x, 3)); // $numTaintFlow=1
}
void test2() {
String x = taint();
Splitter s = Splitter.on(x).omitEmptyStrings();
sink(s.split("x y z"));
sink(s.split(x)); // $numTaintFlow=1
sink(s.splitToList(x)); // $numTaintFlow=1
sink(s.withKeyValueSeparator("=").split("a=b"));
sink(s.withKeyValueSeparator("=").split(x)); // $numTaintFlow=1
}
void test3() {
String x = taint();
Joiner taintedJoiner = Joiner.on(x);
Joiner safeJoiner = Joiner.on(", ");
StringBuilder sb = new StringBuilder();
sink(safeJoiner.appendTo(sb, "a", "b", "c"));
sink(sb.toString());
sink(taintedJoiner.appendTo(sb, "a", "b", "c")); // $numTaintFlow=1
sink(sb.toString()); // $numTaintFlow=1
sink(safeJoiner.appendTo(sb, "a", "b", "c")); // $numTaintFlow=1
sink(sb.toString()); // $numTaintFlow=1
sb = new StringBuilder();
sink(safeJoiner.appendTo(sb, x, x)); // $numTaintFlow=1
Map<String, String> m = new HashMap<String, String>();
m.put("k", "v");
sink(safeJoiner.withKeyValueSeparator("=").join(m));
sink(safeJoiner.withKeyValueSeparator(x).join(m)); // $numTaintFlow=1
sink(taintedJoiner.useForNull("(null)").withKeyValueSeparator("=").join(m)); // $numTaintFlow=1
m.put("k2", x);
sink(safeJoiner.withKeyValueSeparator("=").join(m)); // $numTaintFlow=1
}
void test4() {
sink(Preconditions.checkNotNull(taint())); // $numTaintFlow=1
}
}

View File

@@ -14,20 +14,20 @@ class TestCollect {
String x = taint();
ImmutableSet<String> xs = ImmutableSet.of(x, "y", "z");
sink(xs.asList());
sink(xs.asList()); // $numTaintFlow=1
ImmutableSet<String> ys = ImmutableSet.of("a", "b", "c");
sink(Sets.filter(Sets.union(xs, ys), y -> true));
sink(Sets.filter(Sets.union(xs, ys), y -> true)); // $numTaintFlow=1
sink(Sets.newHashSet("a", "b", "c", "d", x));
sink(Sets.newHashSet("a", "b", "c", "d", x)); // $numTaintFlow=1
}
void test2() {
sink(ImmutableList.of(taint(), taint(), taint(), taint())); // expect 4 alerts
sink(ImmutableMap.of(taint(), taint(), taint(), taint())); // expect 2 alerts
sink(ImmutableMultimap.of(taint(), taint(), taint(), taint())); // expect 2 alerts
sink(ImmutableTable.of(taint(),taint(), taint())); // expect 1 alert
sink(ImmutableList.of(taint(), taint(), taint(), taint())); // $numTaintFlow=4
sink(ImmutableMap.of(taint(), taint(), taint(), taint())); // $numTaintFlow=2
sink(ImmutableMultimap.of(taint(), taint(), taint(), taint())); // $numTaintFlow=2
sink(ImmutableTable.of(taint(),taint(), taint())); // $numTaintFlow=1
}
void test3() {
@@ -38,20 +38,20 @@ class TestCollect {
b.add("a");
sink(b);
b.add(x);
sink(b.build());
sink(b.build()); // $numTaintFlow=1
b = ImmutableList.builder();
b.add("a").add(x);
sink(b.build());
sink(b.build()); // $numTaintFlow=1
sink(ImmutableList.builder().add("a").add(x).build());
sink(ImmutableList.builder().add("a").add(x).build()); // $numTaintFlow=1
ImmutableMap.Builder<String, String> b2 = ImmutableMap.builder();
b2.put(x,"v");
sink(b2);
b2.put("k",x);
sink(b2.build());
sink(b2.build()); // $numTaintFlow=1
}
void test4(Table<String, String, String> t1, Table<String, String, String> t2, Table<String, String, String> t3) {
@@ -61,62 +61,62 @@ class TestCollect {
t1.put("r", x, "v");
sink(t1);
t1.put("r", "c", x);
sink(t1);
sink(t1.row("r"));
sink(t1); // $numTaintFlow=1
sink(t1.row("r")); // $numTaintFlow=1
t2.putAll(t1);
for (Table.Cell<String,String,String> c : t2.cellSet()) {
sink(c.getValue());
sink(c.getValue()); // $numTaintFlow=1
}
sink(t1.remove("r", "c"));
sink(t1.remove("r", "c")); // $numTaintFlow=1
t3.row("r").put("c", x);
sink(t3); // Not detected
sink(t3); // $ MISSING:numTaintFlow=1
}
void test4(Multimap<String, String> m1, Multimap<String, String> m2, Multimap<String, String> m3,
Multimap<String, String> m4, Multimap<String, String> m5){
String x = taint();
m1.put("k", x);
sink(m1);
sink(m1.get("k"));
sink(m1); // $numTaintFlow=1
sink(m1.get("k")); // $numTaintFlow=1
m2.putAll("k", ImmutableList.of("a", x, "b"));
sink(m2);
sink(m2); // $numTaintFlow=1
m3.putAll(m1);
sink(m3);
sink(m3); // $numTaintFlow=1
m4.replaceValues("k", m1.replaceValues("k", ImmutableList.of("a")));
for (Map.Entry<String, String> e : m4.entries()) {
sink(e.getValue());
sink(e.getValue()); // $numTaintFlow=1
}
m5.asMap().get("k").add(x);
sink(m5); // Not detected
sink(m5); // $ MISSING:numTaintFlow=1
}
void test5(Comparator<String> comp, SortedSet<String> sorS, SortedMap<String, String> sorM) {
ImmutableSortedSet<String> s = ImmutableSortedSet.of(taint());
sink(s);
sink(ImmutableSortedSet.copyOf(s));
sink(ImmutableSortedSet.copyOf(comp, s));
sink(s); // $numTaintFlow=1
sink(ImmutableSortedSet.copyOf(s)); // $numTaintFlow=1
sink(ImmutableSortedSet.copyOf(comp, s)); // $numTaintFlow=1
sorS.add(taint());
sink(ImmutableSortedSet.copyOfSorted(sorS));
sink(ImmutableSortedSet.copyOfSorted(sorS)); // $numTaintFlow=1
sink(ImmutableList.sortedCopyOf(s));
sink(ImmutableList.sortedCopyOf(comp, s));
sink(ImmutableList.sortedCopyOf(s)); // $numTaintFlow=1
sink(ImmutableList.sortedCopyOf(comp, s)); // $numTaintFlow=1
ImmutableSortedMap<String, String> m = ImmutableSortedMap.of("k", taint());
sink(m);
sink(ImmutableSortedMap.copyOf(m));
sink(ImmutableSortedMap.copyOf(m, comp));
sink(m); // $numTaintFlow=1
sink(ImmutableSortedMap.copyOf(m)); // $numTaintFlow=1
sink(ImmutableSortedMap.copyOf(m, comp)); // $numTaintFlow=1
sorM.put("k", taint());
sink(ImmutableSortedMap.copyOfSorted(sorM));
sink(ImmutableSortedMap.copyOfSorted(sorM)); // $numTaintFlow=1
}
}

View File

@@ -0,0 +1,126 @@
package com.google.common.io;
import com.google.common.collect.ImmutableList;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.StringBuffer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.Closeable;
import java.nio.file.Path;
import java.io.IOException;
class TestIO {
Object taint() { return null; }
String staint(){ return (String) taint(); }
byte[] btaint() { return (byte[]) taint(); }
InputStream itaint() { return (InputStream) taint(); }
Reader rtaint() { return new InputStreamReader(itaint()); }
Path ptaint() { return (Path) taint(); }
void sink(Object o) {}
void test1() {
BaseEncoding enc = BaseEncoding.base64();
sink(enc.decode(staint())); // $numTaintFlow=1
sink(enc.encode(btaint())); // $numTaintFlow=1
sink(enc.encode(btaint(), 0, 42)); // $numTaintFlow=1
sink(enc.decodingStream(rtaint())); // $numTaintFlow=1
sink(enc.decodingSource(CharSource.wrap(staint()))); // $numTaintFlow=1
sink(enc.withSeparator(staint(), 10).omitPadding().lowerCase().decode("abc")); // $numTaintFlow=1
}
void test2() throws IOException {
ByteSource b = ByteSource.wrap(btaint());
sink(b.openStream()); // $numTaintFlow=1
sink(b.openBufferedStream()); // $numTaintFlow=1
sink(b.asCharSource(null)); // $numTaintFlow=1
sink(b.slice(42,1337)); // $numTaintFlow=1
sink(b.read()); // $numTaintFlow=1
sink(ByteSource.concat(ByteSource.empty(), ByteSource.empty(), b)); // $numTaintFlow=1
sink(ByteSource.concat(ImmutableList.of(ByteSource.empty(), ByteSource.empty(), b))); // $numTaintFlow=1
sink(b.read(new MyByteProcessor())); // $ MISSING:numTaintFlow=1
ByteArrayOutputStream out = new ByteArrayOutputStream();
b.copyTo(out);
sink(out.toByteArray()); // $numTaintFlow=1
CharSource c = CharSource.wrap(staint());
sink(c.openStream()); // $numTaintFlow=1
sink(c.openBufferedStream()); // $numTaintFlow=1
sink(c.asByteSource(null)); // $numTaintFlow=1
sink(c.readFirstLine()); // $numTaintFlow=1
sink(c.readLines()); // $numTaintFlow=1
sink(c.read()); // $numTaintFlow=1
sink(c.lines()); // $numTaintFlow=1
sink(CharSource.concat(CharSource.empty(), CharSource.empty(), c)); // $numTaintFlow=1
sink(CharSource.concat(ImmutableList.of(CharSource.empty(), CharSource.empty(), c))); // $numTaintFlow=1
sink(c.readLines(new MyLineProcessor())); // $ MISSING:numTaintFlow=1
c.forEachLine(l -> sink(l)); // $ MISSING:numTaintFlow=1
StringBuffer buf = new StringBuffer();
c.copyTo(buf);
sink(buf); // $numTaintFlow=1
}
class MyByteProcessor implements ByteProcessor<Object> {
byte[] buf;
public Object getResult() { return buf; }
public boolean processBytes(byte[] b, int off, int len) { this.buf = b; return false; }
}
class MyLineProcessor implements LineProcessor<String> {
String s = "";
public String getResult() { return s; }
public boolean processLine(String l) { this.s += l; return true; }
}
void test3() throws IOException {
sink(ByteStreams.limit(itaint(), 1337)); // $numTaintFlow=1
sink(ByteStreams.newDataInput(btaint())); // $numTaintFlow=1
sink(ByteStreams.newDataInput(btaint(), 0)); // $numTaintFlow=1
sink(ByteStreams.newDataInput(btaint())); // $numTaintFlow=1
sink(ByteStreams.newDataInput(btaint()).readLine()); // $ MISSING:numTaintFlow=1
sink(ByteStreams.newDataInput(new ByteArrayInputStream(btaint()))); // $numTaintFlow=1
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(btaint());
sink(ByteStreams.newDataOutput(out)); // $numTaintFlow=1
byte[] b1 = null, b2 = null, b3 = null;
ByteStreams.read(itaint(), b1, 0, 42);
sink(b1); // $numTaintFlow=1
ByteStreams.readFully(itaint(), b2);
sink(b2); // $numTaintFlow=1
ByteStreams.readFully(itaint(), b3, 0, 42);
sink(b3); // $numTaintFlow=1
sink(ByteStreams.readBytes(itaint(), new MyByteProcessor())); // $ MISSING:numTaintFlow=1
sink(ByteStreams.toByteArray(itaint())); // $numTaintFlow=1
ByteArrayDataOutput out2 = ByteStreams.newDataOutput();
out2.writeUTF(staint());
sink(out2.toByteArray()); // $numTaintFlow=1
StringBuffer buf = new StringBuffer();
CharStreams.copy(rtaint(), buf);
sink(buf); // $numTaintFlow=1
sink(CharStreams.readLines(rtaint())); // $numTaintFlow=1
sink(CharStreams.readLines(rtaint(), new MyLineProcessor())); // $ MISSING:numTaintFlow=1
sink(CharStreams.toString(rtaint())); // $numTaintFlow=1
}
void test4() throws IOException {
sink(Closer.create().register((Closeable) taint())); // $numTaintFlow=1
sink(new LineReader(rtaint()).readLine()); // $numTaintFlow=1
sink(Files.simplifyPath(staint())); // $numTaintFlow=1
sink(Files.getFileExtension(staint())); // $numTaintFlow=1
sink(Files.getNameWithoutExtension(staint())); // $numTaintFlow=1
sink(MoreFiles.getFileExtension(ptaint())); // $numTaintFlow=1
sink(MoreFiles.getNameWithoutExtension(ptaint())); // $numTaintFlow=1
}
void test6() throws IOException {
sink(new CountingInputStream(itaint())); // $numTaintFlow=1
byte[] buf = null;
new CountingInputStream(itaint()).read(buf, 0, 42);
sink(buf); // $numTaintFlow=1
sink(new LittleEndianDataInputStream(itaint())); // $numTaintFlow=1
sink(new LittleEndianDataInputStream(itaint()).readUTF()); // $ MISSING:numTaintFlow=1
}
}

View File

@@ -1,62 +0,0 @@
import com.google.common.base.Strings;
import com.google.common.base.Splitter;
import com.google.common.base.Joiner;
import java.util.Map;
import java.util.HashMap;
class TestStrings {
String taint() { return "tainted"; }
void sink(Object o) {}
void test1() {
String x = taint();
sink(Strings.padStart(x, 10, ' '));
sink(Strings.padEnd(x, 10, ' '));
sink(Strings.repeat(x, 3));
sink(Strings.emptyToNull(Strings.nullToEmpty(x)));
sink(Strings.lenientFormat(x, 3));
sink(Strings.commonPrefix(x, "abc"));
sink(Strings.commonSuffix(x, "cde"));
sink(Strings.lenientFormat("%s = %s", x, 3));
}
void test2() {
String x = taint();
Splitter s = Splitter.on(x).omitEmptyStrings();
sink(s.split("x y z"));
sink(s.split(x));
sink(s.splitToList(x));
sink(s.withKeyValueSeparator("=").split("a=b"));
sink(s.withKeyValueSeparator("=").split(x));
}
void test3() {
String x = taint();
Joiner taintedJoiner = Joiner.on(x);
Joiner safeJoiner = Joiner.on(", ");
StringBuilder sb = new StringBuilder();
sink(safeJoiner.appendTo(sb, "a", "b", "c"));
sink(sb.toString());
sink(taintedJoiner.appendTo(sb, "a", "b", "c"));
sink(sb.toString());
sink(safeJoiner.appendTo(sb, "a", "b", "c"));
sink(sb.toString());
sb = new StringBuilder();
sink(safeJoiner.appendTo(sb, x, x));
Map<String, String> m = new HashMap<String, String>();
m.put("k", "v");
sink(safeJoiner.withKeyValueSeparator("=").join(m));
sink(safeJoiner.withKeyValueSeparator(x).join(m));
sink(taintedJoiner.useForNull("(null)").withKeyValueSeparator("=").join(m));
m.put("k2", x);
sink(safeJoiner.withKeyValueSeparator("=").join(m));
}
}

View File

@@ -1,52 +0,0 @@
| TestCollect.java:14:20:14:26 | taint(...) | TestCollect.java:17:14:17:24 | asList(...) |
| TestCollect.java:14:20:14:26 | taint(...) | TestCollect.java:21:14:21:55 | filter(...) |
| TestCollect.java:14:20:14:26 | taint(...) | TestCollect.java:23:14:23:51 | newHashSet(...) |
| TestCollect.java:27:31:27:37 | taint(...) | TestCollect.java:27:14:27:65 | of(...) |
| TestCollect.java:27:40:27:46 | taint(...) | TestCollect.java:27:14:27:65 | of(...) |
| TestCollect.java:27:49:27:55 | taint(...) | TestCollect.java:27:14:27:65 | of(...) |
| TestCollect.java:27:58:27:64 | taint(...) | TestCollect.java:27:14:27:65 | of(...) |
| TestCollect.java:28:39:28:45 | taint(...) | TestCollect.java:28:14:28:64 | of(...) |
| TestCollect.java:28:57:28:63 | taint(...) | TestCollect.java:28:14:28:64 | of(...) |
| TestCollect.java:29:44:29:50 | taint(...) | TestCollect.java:29:14:29:69 | of(...) |
| TestCollect.java:29:62:29:68 | taint(...) | TestCollect.java:29:14:29:69 | of(...) |
| TestCollect.java:30:49:30:55 | taint(...) | TestCollect.java:30:14:30:56 | of(...) |
| TestCollect.java:34:20:34:26 | taint(...) | TestCollect.java:41:14:41:22 | build(...) |
| TestCollect.java:34:20:34:26 | taint(...) | TestCollect.java:46:14:46:22 | build(...) |
| TestCollect.java:34:20:34:26 | taint(...) | TestCollect.java:48:14:48:60 | build(...) |
| TestCollect.java:34:20:34:26 | taint(...) | TestCollect.java:54:14:54:23 | build(...) |
| TestCollect.java:58:20:58:26 | taint(...) | TestCollect.java:64:14:64:15 | t1 |
| TestCollect.java:58:20:58:26 | taint(...) | TestCollect.java:65:14:65:24 | row(...) |
| TestCollect.java:58:20:58:26 | taint(...) | TestCollect.java:69:18:69:29 | getValue(...) |
| TestCollect.java:58:20:58:26 | taint(...) | TestCollect.java:72:14:72:32 | remove(...) |
| TestCollect.java:80:20:80:26 | taint(...) | TestCollect.java:82:14:82:15 | m1 |
| TestCollect.java:80:20:80:26 | taint(...) | TestCollect.java:83:14:83:24 | get(...) |
| TestCollect.java:80:20:80:26 | taint(...) | TestCollect.java:86:14:86:15 | m2 |
| TestCollect.java:80:20:80:26 | taint(...) | TestCollect.java:89:14:89:15 | m3 |
| TestCollect.java:80:20:80:26 | taint(...) | TestCollect.java:93:18:93:29 | getValue(...) |
| TestCollect.java:101:62:101:68 | taint(...) | TestCollect.java:103:14:103:14 | s |
| TestCollect.java:101:62:101:68 | taint(...) | TestCollect.java:104:14:104:41 | copyOf(...) |
| TestCollect.java:101:62:101:68 | taint(...) | TestCollect.java:105:14:105:47 | copyOf(...) |
| TestCollect.java:101:62:101:68 | taint(...) | TestCollect.java:110:14:110:42 | sortedCopyOf(...) |
| TestCollect.java:101:62:101:68 | taint(...) | TestCollect.java:111:14:111:48 | sortedCopyOf(...) |
| TestCollect.java:107:18:107:24 | taint(...) | TestCollect.java:108:14:108:50 | copyOfSorted(...) |
| TestCollect.java:113:75:113:81 | taint(...) | TestCollect.java:115:14:115:14 | m |
| TestCollect.java:113:75:113:81 | taint(...) | TestCollect.java:116:14:116:41 | copyOf(...) |
| TestCollect.java:113:75:113:81 | taint(...) | TestCollect.java:117:14:117:47 | copyOf(...) |
| TestCollect.java:119:23:119:29 | taint(...) | TestCollect.java:120:14:120:50 | copyOfSorted(...) |
| TestStrings.java:15:20:15:26 | taint(...) | TestStrings.java:17:14:17:41 | padStart(...) |
| TestStrings.java:15:20:15:26 | taint(...) | TestStrings.java:18:14:18:39 | padEnd(...) |
| TestStrings.java:15:20:15:26 | taint(...) | TestStrings.java:19:14:19:33 | repeat(...) |
| TestStrings.java:15:20:15:26 | taint(...) | TestStrings.java:20:14:20:56 | emptyToNull(...) |
| TestStrings.java:15:20:15:26 | taint(...) | TestStrings.java:21:14:21:40 | lenientFormat(...) |
| TestStrings.java:15:20:15:26 | taint(...) | TestStrings.java:24:14:24:51 | lenientFormat(...) |
| TestStrings.java:28:20:28:26 | taint(...) | TestStrings.java:32:14:32:23 | split(...) |
| TestStrings.java:28:20:28:26 | taint(...) | TestStrings.java:33:14:33:29 | splitToList(...) |
| TestStrings.java:28:20:28:26 | taint(...) | TestStrings.java:35:14:35:50 | split(...) |
| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:46:14:46:54 | appendTo(...) |
| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:47:14:47:26 | toString(...) |
| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:48:14:48:51 | appendTo(...) |
| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:49:14:49:26 | toString(...) |
| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:52:14:52:42 | appendTo(...) |
| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:57:14:57:56 | join(...) |
| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:58:14:58:82 | join(...) |
| TestStrings.java:39:20:39:26 | taint(...) | TestStrings.java:60:14:60:58 | join(...) |

View File

@@ -1,5 +1,6 @@
import java
import semmle.code.java.dataflow.TaintTracking
import TestUtilities.InlineExpectationsTest
class Conf extends TaintTracking::Configuration {
Conf() { this = "qltest:frameworks:guava" }
@@ -13,6 +14,18 @@ class Conf extends TaintTracking::Configuration {
}
}
from DataFlow::Node src, DataFlow::Node sink, Conf conf
where conf.hasFlow(src, sink)
select src, sink
class HasFlowTest extends InlineExpectationsTest {
HasFlowTest() { this = "HasFlowTest" }
override string getARelevantTag() { result = "numTaintFlow" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "numTaintFlow" and
exists(DataFlow::Node src, DataFlow::Node sink, Conf conf, int num | conf.hasFlow(src, sink) |
value = num.toString() and
sink.getLocation() = location and
element = sink.toString() and
num = strictcount(DataFlow::Node src2 | conf.hasFlow(src2, sink))
)
}
}

View File

@@ -0,0 +1,3 @@
| resources/Resource.java:19:37:19:46 | uri |
| resources/Resource.java:24:42:24:53 | token |
| resources/Resource.java:28:56:28:65 | uri |

View File

@@ -0,0 +1,4 @@
import semmle.code.java.frameworks.play.Play
from PlayActionMethodQueryParameter p
select p

View File

@@ -0,0 +1 @@
| resources/Resource.java:12:3:12:15 | AddCSRFToken |

View File

@@ -0,0 +1,4 @@
import semmle.code.java.frameworks.play.Play
from PlayAddCsrfTokenAnnotation token
select token

View File

@@ -0,0 +1 @@
| play.mvc.BodyParser<>$Of |

View File

@@ -0,0 +1,4 @@
import semmle.code.java.frameworks.play.Play
from PlayBodyParserAnnotation parser
select parser.getType().getQualifiedName()

View File

@@ -0,0 +1,2 @@
| Resource |
| play.mvc.Controller |

View File

@@ -0,0 +1,4 @@
import semmle.code.java.frameworks.play.Play
from PlayController c
select c.getQualifiedName()

View File

@@ -0,0 +1,4 @@
| Resource.async_completionstage |
| Resource.async_promise |
| Resource.index |
| Resource.session_redirect_me |

View File

@@ -0,0 +1,4 @@
import semmle.code.java.frameworks.play.Play
from PlayControllerActionMethod m
select m.getQualifiedName()

View File

@@ -0,0 +1,27 @@
| play.mvc.Http$RequestHeader | RequestHeader.acceptLanguages |
| play.mvc.Http$RequestHeader | RequestHeader.accepts |
| play.mvc.Http$RequestHeader | RequestHeader.addAttr |
| play.mvc.Http$RequestHeader | RequestHeader.attrs |
| play.mvc.Http$RequestHeader | RequestHeader.charset |
| play.mvc.Http$RequestHeader | RequestHeader.clientCertificateChain |
| play.mvc.Http$RequestHeader | RequestHeader.contentType |
| play.mvc.Http$RequestHeader | RequestHeader.cookie |
| play.mvc.Http$RequestHeader | RequestHeader.cookies |
| play.mvc.Http$RequestHeader | RequestHeader.getHeader |
| play.mvc.Http$RequestHeader | RequestHeader.getHeaders |
| play.mvc.Http$RequestHeader | RequestHeader.getQueryString |
| play.mvc.Http$RequestHeader | RequestHeader.hasBody |
| play.mvc.Http$RequestHeader | RequestHeader.hasHeader |
| play.mvc.Http$RequestHeader | RequestHeader.header |
| play.mvc.Http$RequestHeader | RequestHeader.headers |
| play.mvc.Http$RequestHeader | RequestHeader.host |
| play.mvc.Http$RequestHeader | RequestHeader.method |
| play.mvc.Http$RequestHeader | RequestHeader.path |
| play.mvc.Http$RequestHeader | RequestHeader.queryString |
| play.mvc.Http$RequestHeader | RequestHeader.remoteAddress |
| play.mvc.Http$RequestHeader | RequestHeader.secure |
| play.mvc.Http$RequestHeader | RequestHeader.tags |
| play.mvc.Http$RequestHeader | RequestHeader.uri |
| play.mvc.Http$RequestHeader | RequestHeader.version |
| play.mvc.Http$RequestHeader | RequestHeader.withAttrs |
| play.mvc.Http$RequestHeader | RequestHeader.withBody |

View File

@@ -0,0 +1,4 @@
import semmle.code.java.frameworks.play.Play
from PlayMvcHttpRequestHeader c
select c.getQualifiedName(), c.getAMethod().getQualifiedName()

View File

@@ -0,0 +1 @@
| play.mvc.Result |

View File

@@ -0,0 +1,4 @@
import semmle.code.java.frameworks.play.Play
from PlayMvcResultClass m
select m.getQualifiedName()

View File

@@ -0,0 +1,19 @@
| play.mvc.Results | Results.<clinit> |
| play.mvc.Results | Results.badRequest |
| play.mvc.Results | Results.created |
| play.mvc.Results | Results.forbidden |
| play.mvc.Results | Results.found |
| play.mvc.Results | Results.internalServerError |
| play.mvc.Results | Results.movedPermanently |
| play.mvc.Results | Results.noContent |
| play.mvc.Results | Results.notAcceptable |
| play.mvc.Results | Results.notFound |
| play.mvc.Results | Results.ok |
| play.mvc.Results | Results.paymentRequired |
| play.mvc.Results | Results.permanentRedirect |
| play.mvc.Results | Results.redirect |
| play.mvc.Results | Results.seeOther |
| play.mvc.Results | Results.status |
| play.mvc.Results | Results.temporaryRedirect |
| play.mvc.Results | Results.unauthorized |
| play.mvc.Results | Results.unsupportedMediaType |

View File

@@ -0,0 +1,4 @@
import semmle.code.java.frameworks.play.Play
from PlayMvcResultsClass m
select m.getQualifiedName(), m.getAMethod().getQualifiedName()

View File

@@ -0,0 +1,3 @@
| resources/Resource.java:15:12:15:26 | ok(...) |
| resources/Resource.java:25:27:25:35 | ok(...) |
| resources/Resource.java:29:46:29:73 | ok(...) |

View File

@@ -0,0 +1,4 @@
import semmle.code.java.frameworks.play.Play
from PlayMvcResultsMethods m
select m.getAnOkAccess()

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/playframework-2.6.x:${testdir}/../../../stubs/jackson-databind-2.10:${testdir}/../../../stubs/akka-2.6.x

View File

@@ -0,0 +1,36 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import play.filters.csrf.AddCSRFToken;
import play.libs.F;
import play.mvc.BodyParser;
import play.mvc.Controller;
import play.mvc.Http.*;
import play.mvc.Result;
public class Resource extends Controller {
@AddCSRFToken
public Result index() {
response().setHeader("X-Play-QL", "1");
return ok("It works!");
}
@BodyParser.Of()
public Result session_redirect_me(String uri) {
String url = request().getQueryString("url");
return redirect(url);
}
public F.Promise<Result> async_promise(String token) {
return F.Promise.pure(ok(token));
}
public CompletionStage<Result> async_completionstage(String uri) {
return CompletableFuture.completedFuture(ok("Async completion Stage"));
}
public String not_playactionmethod(String no_action) {
String return_code = no_action;
return return_code;
}
}

View File

@@ -1 +1,3 @@
| literals/Literals.java:11:22:11:25 | true |
| literals/Literals.java:11:22:11:25 | true | true | true |
| literals/Literals.java:16:3:16:6 | true | true | true |
| literals/Literals.java:17:3:17:7 | false | false | false |

View File

@@ -2,4 +2,4 @@ import semmle.code.java.Expr
from BooleanLiteral lit
where lit.getCompilationUnit().fromSource()
select lit
select lit, lit.getValue(), lit.getBooleanValue()

View File

@@ -1 +1,10 @@
| literals/Literals.java:12:22:12:24 | 'x' |
| literals/Literals.java:12:22:12:24 | 'x' | x |
| literals/Literals.java:21:3:21:5 | 'a' | a |
| literals/Literals.java:22:3:22:10 | '\\u0061' | a |
| literals/Literals.java:23:3:23:10 | '\\u0000' | \u0000 |
| literals/Literals.java:24:3:24:6 | '\\0' | \u0000 |
| literals/Literals.java:25:3:25:6 | '\\n' | \n |
| literals/Literals.java:26:3:26:6 | '\\0' | \u0000 |
| literals/Literals.java:27:3:27:6 | '\\\\' | \\ |
| literals/Literals.java:28:3:28:6 | '\\'' | ' |
| literals/Literals.java:29:3:29:8 | '\\123' | S |

View File

@@ -1,4 +1,4 @@
import semmle.code.java.Expr
from CharacterLiteral lit
select lit
select lit, lit.getValue()

View File

@@ -1 +1,16 @@
| literals/Literals.java:10:22:10:27 | 456.0D |
| literals/Literals.java:10:22:10:27 | 456.0D | 456.0 | 456.0 |
| literals/Literals.java:33:3:33:5 | 0.0 | 0.0 | 0.0 |
| literals/Literals.java:34:3:34:4 | 0d | 0.0 | 0.0 |
| literals/Literals.java:35:3:35:5 | .0d | 0.0 | 0.0 |
| literals/Literals.java:36:3:36:4 | .0 | 0.0 | 0.0 |
| literals/Literals.java:37:4:37:6 | 0.d | 0.0 | 0.0 |
| literals/Literals.java:38:4:38:6 | 0.d | 0.0 | 0.0 |
| literals/Literals.java:39:3:39:22 | 1.234567890123456789 | 1.2345678901234567 | 1.2345678901234567 |
| literals/Literals.java:40:3:40:24 | 1.55555555555555555555 | 1.5555555555555556 | 1.5555555555555556 |
| literals/Literals.java:42:3:42:5 | 1e1 | 10.0 | 10.0 |
| literals/Literals.java:43:3:43:24 | 1.7976931348623157E308 | 1.7976931348623157E308 | 1.7976931348623157E308 |
| literals/Literals.java:44:4:44:25 | 1.7976931348623157E308 | 1.7976931348623157E308 | 1.7976931348623157E308 |
| literals/Literals.java:45:3:45:28 | 0x1.f_ffff_ffff_ffffP+1023 | 1.7976931348623157E308 | 1.7976931348623157E308 |
| literals/Literals.java:46:3:46:10 | 4.9e-324 | 4.9E-324 | 4.9E-324 |
| literals/Literals.java:47:3:47:28 | 0x0.0_0000_0000_0001P-1022 | 4.9E-324 | 4.9E-324 |
| literals/Literals.java:48:3:48:13 | 0x1.0P-1074 | 4.9E-324 | 4.9E-324 |

View File

@@ -1,4 +1,4 @@
import semmle.code.java.Expr
from DoubleLiteral lit
select lit
select lit, lit.getValue(), lit.getDoubleValue()

View File

@@ -1 +1,16 @@
| literals/Literals.java:9:22:9:27 | 123.0F |
| literals/Literals.java:9:22:9:27 | 123.0F | 123.0 | 123.0 |
| literals/Literals.java:52:3:52:6 | 0.0f | 0.0 | 0.0 |
| literals/Literals.java:53:3:53:4 | 0f | 0.0 | 0.0 |
| literals/Literals.java:54:3:54:5 | .0f | 0.0 | 0.0 |
| literals/Literals.java:55:4:55:6 | 0.f | 0.0 | 0.0 |
| literals/Literals.java:56:4:56:6 | 0.f | 0.0 | 0.0 |
| literals/Literals.java:57:3:57:10 | 1_0_0.0f | 100.0 | 100.0 |
| literals/Literals.java:58:3:58:23 | 1.234567890123456789f | 1.2345679 | 1.2345679 |
| literals/Literals.java:59:3:59:25 | 1.55555555555555555555f | 1.5555556 | 1.5555556 |
| literals/Literals.java:61:3:61:6 | 1e1f | 10.0 | 10.0 |
| literals/Literals.java:62:3:62:15 | 3.4028235e38f | 3.4028235E38 | 3.4028235E38 |
| literals/Literals.java:63:4:63:16 | 3.4028235e38f | 3.4028235E38 | 3.4028235E38 |
| literals/Literals.java:64:3:64:18 | 0x1.fffffeP+127f | 3.4028235E38 | 3.4028235E38 |
| literals/Literals.java:65:3:65:10 | 1.4e-45f | 1.4E-45 | 1.4E-45 |
| literals/Literals.java:66:3:66:18 | 0x0.000002P-126f | 1.4E-45 | 1.4E-45 |
| literals/Literals.java:67:3:67:13 | 0x1.0P-149f | 1.4E-45 | 1.4E-45 |

View File

@@ -1,4 +1,4 @@
import semmle.code.java.Expr
from FloatingPointLiteral lit
select lit
select lit, lit.getValue(), lit.getFloatValue()

View File

@@ -1,8 +1,20 @@
| literals/Literals.java:7:22:7:24 | 123 |
| literals/Literals.java:14:16:14:26 | -2147483648 |
| literals/Literals.java:16:21:16:30 | 2147483647 |
| literals/Literals.java:18:20:18:29 | 0x80000000 |
| literals/Literals.java:20:10:20:11 | 23 |
| literals/Literals.java:20:15:20:16 | 19 |
| literals/Literals.java:21:10:21:11 | 23 |
| literals/Literals.java:21:15:21:16 | 19 |
| literals/Literals.java:7:22:7:24 | 123 | 123 | 123 |
| literals/Literals.java:71:3:71:3 | 0 | 0 | 0 |
| literals/Literals.java:72:3:72:5 | 0_0 | 0 | 0 |
| literals/Literals.java:73:3:73:7 | 0___0 | 0 | 0 |
| literals/Literals.java:74:3:74:6 | 0_12 | 10 | 10 |
| literals/Literals.java:75:3:75:7 | 0X012 | 18 | 18 |
| literals/Literals.java:76:3:76:10 | 0xaBcDeF | 11259375 | 11259375 |
| literals/Literals.java:77:3:77:6 | 0B11 | 3 | 3 |
| literals/Literals.java:78:3:78:12 | 0x80000000 | -2147483648 | -2147483648 |
| literals/Literals.java:79:3:79:12 | 2147483647 | 2147483647 | 2147483647 |
| literals/Literals.java:80:3:80:13 | -2147483648 | -2147483648 | -2147483648 |
| literals/Literals.java:82:3:82:13 | 0x7fff_ffff | 2147483647 | 2147483647 |
| literals/Literals.java:83:3:83:16 | 0177_7777_7777 | 2147483647 | 2147483647 |
| literals/Literals.java:84:3:84:43 | 0b0111_1111_1111_1111_1111_1111_1111_1111 | 2147483647 | 2147483647 |
| literals/Literals.java:85:3:85:13 | 0x8000_0000 | -2147483648 | -2147483648 |
| literals/Literals.java:86:3:86:16 | 0200_0000_0000 | -2147483648 | -2147483648 |
| literals/Literals.java:87:3:87:43 | 0b1000_0000_0000_0000_0000_0000_0000_0000 | -2147483648 | -2147483648 |
| literals/Literals.java:88:3:88:13 | 0xffff_ffff | -1 | -1 |
| literals/Literals.java:89:3:89:16 | 0377_7777_7777 | -1 | -1 |
| literals/Literals.java:90:3:90:43 | 0b1111_1111_1111_1111_1111_1111_1111_1111 | -1 | -1 |

View File

@@ -1,4 +1,4 @@
import semmle.code.java.Expr
from IntegerLiteral lit
select lit
select lit, lit.getValue(), lit.getIntValue()

View File

@@ -1,4 +1,20 @@
| literals/Literals.java:8:22:8:25 | 456L |
| literals/Literals.java:15:18:15:38 | -9223372036854775808l |
| literals/Literals.java:17:23:17:42 | 9223372036854775807l |
| literals/Literals.java:19:22:19:40 | 0x8000000000000000L |
| literals/Literals.java:8:22:8:25 | 456L | 456 |
| literals/Literals.java:94:3:94:4 | 0l | 0 |
| literals/Literals.java:95:3:95:4 | 0L | 0 |
| literals/Literals.java:96:3:96:6 | 0_0L | 0 |
| literals/Literals.java:97:3:97:8 | 0___0L | 0 |
| literals/Literals.java:98:3:98:7 | 0_12L | 10 |
| literals/Literals.java:99:3:99:8 | 0X012L | 18 |
| literals/Literals.java:100:3:100:11 | 0xaBcDeFL | 11259375 |
| literals/Literals.java:101:3:101:7 | 0B11L | 3 |
| literals/Literals.java:102:3:102:22 | 9223372036854775807L | 9223372036854775807 |
| literals/Literals.java:103:3:103:23 | -9223372036854775808L | -9223372036854775808 |
| literals/Literals.java:105:3:105:24 | 0x7fff_ffff_ffff_ffffL | 9223372036854775807 |
| literals/Literals.java:106:3:106:30 | 07_7777_7777_7777_7777_7777L | 9223372036854775807 |
| literals/Literals.java:107:3:107:84 | 0b0111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L | 9223372036854775807 |
| literals/Literals.java:108:3:108:24 | 0x8000_0000_0000_0000L | -9223372036854775808 |
| literals/Literals.java:109:3:109:31 | 010_0000_0000_0000_0000_0000L | -9223372036854775808 |
| literals/Literals.java:110:3:110:84 | 0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000L | -9223372036854775808 |
| literals/Literals.java:111:3:111:24 | 0xffff_ffff_ffff_ffffL | -1 |
| literals/Literals.java:112:3:112:31 | 017_7777_7777_7777_7777_7777L | -1 |
| literals/Literals.java:113:3:113:84 | 0b1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L | -1 |

View File

@@ -1,4 +1,4 @@
import semmle.code.java.Expr
from LongLiteral lit
select lit
select lit, lit.getValue()

Some files were not shown because too many files have changed in this diff Show More