Merge branch 'main' into fixHiddenTypesTestGenerator

This commit is contained in:
Benjamin Muskalla
2021-09-28 17:42:39 +02:00
308 changed files with 10928 additions and 1350 deletions

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The query "Expression language injection (Spring)" (`java/spel-expression-injection`) has been promoted from experimental to the main query pack. Its results will now appear by default. This query was originally [submitted as an experimental query by @artem-smotrakov](https://github.com/github/codeql/pull/3291).

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The query "XSLT transformation with user-controlled stylesheet" (`java/xslt-injection`) has been promoted from experimental to the main query pack. Its results will now appear by default. This query was originally [submitted as an experimental query by @ggolawski](https://github.com/github/codeql/pull/3363).

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* Added models for the subpackages of Apache Commons Collections. This may lead to more results from any query using data-flow analysis where a relevant path uses one of these container types.

View File

@@ -1,89 +1,89 @@
package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:jexl,sink:jndi-injection,sink:ldap,sink:mvel,sink:ognl-injection,sink:open-url,sink:set-hostname-verifier,sink:sql,sink:url-open-stream,sink:url-redirect,sink:xpath,sink:xss,source:remote,summary:taint,summary:value
android.content,8,,4,,,,,,,,,,,,,8,,,,,,4,
android.database,59,,30,,,,,,,,,,,,,59,,,,,,30,
android.net,,,60,,,,,,,,,,,,,,,,,,,45,15
android.util,,16,,,,,,,,,,,,,,,,,,,16,,
android.webkit,3,2,,,,,,,,,,,,,,,,,,3,2,,
com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,1,
com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,1,
com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,1,
com.fasterxml.jackson.databind,,,5,,,,,,,,,,,,,,,,,,,5,
com.google.common.base,,,85,,,,,,,,,,,,,,,,,,,62,23
com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,17
com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,2,551
com.google.common.io,6,,73,,,,,,,,,,,,,,6,,,,,72,1
com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,3,,,,,,,,,,
com.unboundid.ldap.sdk,17,,,,,,,,,,17,,,,,,,,,,,,
flexjson,,,1,,,,,,,,,,,,,,,,,,,,1
groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,
groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,
jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,2,7,,
jakarta.json,,,123,,,,,,,,,,,,,,,,,,,100,23
jakarta.ws.rs.client,1,,,,,,,,,,,,,1,,,,,,,,,
jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,9,,
jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,2,,,,94,55
java.beans,,,1,,,,,,,,,,,,,,,,,,,1,
java.io,3,,27,,3,,,,,,,,,,,,,,,,,26,1
java.lang,,,47,,,,,,,,,,,,,,,,,,,41,6
java.net,10,3,7,,,,,,,,,,,10,,,,,,,3,7,
java.nio,10,,4,,10,,,,,,,,,,,,,,,,,4,
java.sql,7,,,,,,,,,,,,,,,7,,,,,,,
java.util,,,337,,,,,,,,,,,,,,,,,,,15,322
javax.faces.context,2,7,,,,,,,,,,,,,,,,,,2,7,,
javax.json,,,123,,,,,,,,,,,,,,,,,,,100,23
javax.management.remote,2,,,,,,,,,2,,,,,,,,,,,,,
javax.naming,7,,,,,,,,,6,1,,,,,,,,,,,,
javax.net.ssl,2,,,,,,,,,,,,,,2,,,,,,,,
javax.script,1,,,,,,,,,,,1,,,,,,,,,,,
javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,21,2,
javax.validation,1,1,,1,,,,,,,,,,,,,,,,,1,,
javax.ws.rs.client,1,,,,,,,,,,,,,1,,,,,,,,,
javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,9,,
javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,2,,,,94,55
javax.xml.transform.sax,,,4,,,,,,,,,,,,,,,,,,,4,
javax.xml.transform.stream,,,2,,,,,,,,,,,,,,,,,,,2,
javax.xml.xpath,3,,,,,,,,,,,,,,,,,,3,,,,
jodd.json,,,10,,,,,,,,,,,,,,,,,,,,10
ognl,6,,,,,,,,,,,,6,,,,,,,,,,
org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,6,
org.apache.commons.collections,,,394,,,,,,,,,,,,,,,,,,,9,385
org.apache.commons.collections4,,,394,,,,,,,,,,,,,,,,,,,9,385
org.apache.commons.io,,,22,,,,,,,,,,,,,,,,,,,22,
org.apache.commons.jexl2,15,,,,,,,,15,,,,,,,,,,,,,,
org.apache.commons.jexl3,15,,,,,,,,15,,,,,,,,,,,,,,
org.apache.commons.lang3,,,423,,,,,,,,,,,,,,,,,,,292,131
org.apache.commons.ognl,6,,,,,,,,,,,,6,,,,,,,,,,
org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,220,52
org.apache.directory.ldap.client.api,1,,,,,,,,,,1,,,,,,,,,,,,
org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,1,
org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,1,2,39,
org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,2,
org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,18,6
org.apache.http,27,3,70,,,,,,,,,,,25,,,,,,2,3,62,8
org.apache.ibatis.jdbc,6,,,,,,,,,,,,,,,6,,,,,,,
org.apache.shiro.jndi,1,,,,,,,,,1,,,,,,,,,,,,,
org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,
org.dom4j,20,,,,,,,,,,,,,,,,,,20,,,,
org.hibernate,7,,,,,,,,,,,,,,,7,,,,,,,
org.jooq,1,,,,,,,,,,,,,,,1,,,,,,,
org.json,,,236,,,,,,,,,,,,,,,,,,,198,38
org.mvel2,16,,,,,,,,,,,16,,,,,,,,,,,
org.springframework.beans,,,26,,,,,,,,,,,,,,,,,,,,26
org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,13
org.springframework.http,14,,70,,,,,,,,,,,14,,,,,,,,60,10
org.springframework.jdbc.core,10,,,,,,,,,,,,,,,10,,,,,,,
org.springframework.jdbc.object,9,,,,,,,,,,,,,,,9,,,,,,,
org.springframework.jndi,1,,,,,,,,,1,,,,,,,,,,,,,
org.springframework.ldap,42,,,,,,,,,28,14,,,,,,,,,,,,
org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,6,,
org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,32
org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,87,52
org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,13,
org.springframework.web.client,13,3,,,,,,,,,,,,13,,,,,,,3,,
org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,8,,
org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,12,13,
org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,2,,,,,,,,,
org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,138,25
org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,1,
org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,3,,
play.mvc,,4,,,,,,,,,,,,,,,,,,,4,,
package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:jexl,sink:jndi-injection,sink:ldap,sink:mvel,sink:ognl-injection,sink:open-url,sink:set-hostname-verifier,sink:sql,sink:url-open-stream,sink:url-redirect,sink:xpath,sink:xslt,sink:xss,source:remote,summary:taint,summary:value
android.content,8,,4,,,,,,,,,,,,,8,,,,,,,4,
android.database,59,,30,,,,,,,,,,,,,59,,,,,,,30,
android.net,,,60,,,,,,,,,,,,,,,,,,,,45,15
android.util,,16,,,,,,,,,,,,,,,,,,,,16,,
android.webkit,3,2,,,,,,,,,,,,,,,,,,,3,2,,
com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,1,
com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,1,
com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,1,
com.fasterxml.jackson.databind,,,5,,,,,,,,,,,,,,,,,,,,5,
com.google.common.base,,,85,,,,,,,,,,,,,,,,,,,,62,23
com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,17
com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,2,551
com.google.common.io,6,,73,,,,,,,,,,,,,,6,,,,,,72,1
com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,3,,,,,,,,,,,
com.unboundid.ldap.sdk,17,,,,,,,,,,17,,,,,,,,,,,,,
flexjson,,,1,,,,,,,,,,,,,,,,,,,,,1
groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,
groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,
jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,2,7,,
jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,100,23
jakarta.ws.rs.client,1,,,,,,,,,,,,,1,,,,,,,,,,
jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,9,,
jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,2,,,,,94,55
java.beans,,,1,,,,,,,,,,,,,,,,,,,,1,
java.io,3,,27,,3,,,,,,,,,,,,,,,,,,26,1
java.lang,,,47,,,,,,,,,,,,,,,,,,,,41,6
java.net,10,3,7,,,,,,,,,,,10,,,,,,,,3,7,
java.nio,10,,4,,10,,,,,,,,,,,,,,,,,,4,
java.sql,7,,,,,,,,,,,,,,,7,,,,,,,,
java.util,,,337,,,,,,,,,,,,,,,,,,,,15,322
javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,2,7,,
javax.json,,,123,,,,,,,,,,,,,,,,,,,,100,23
javax.management.remote,2,,,,,,,,,2,,,,,,,,,,,,,,
javax.naming,7,,,,,,,,,6,1,,,,,,,,,,,,,
javax.net.ssl,2,,,,,,,,,,,,,,2,,,,,,,,,
javax.script,1,,,,,,,,,,,1,,,,,,,,,,,,
javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,21,2,
javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,1,,
javax.ws.rs.client,1,,,,,,,,,,,,,1,,,,,,,,,,
javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,9,,
javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,2,,,,,94,55
javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,1,,,6,
javax.xml.xpath,3,,,,,,,,,,,,,,,,,,3,,,,,
jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,10
net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,5,,,,
ognl,6,,,,,,,,,,,,6,,,,,,,,,,,
org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,6,
org.apache.commons.collections,,,394,,,,,,,,,,,,,,,,,,,,9,385
org.apache.commons.collections4,,,394,,,,,,,,,,,,,,,,,,,,9,385
org.apache.commons.io,,,22,,,,,,,,,,,,,,,,,,,,22,
org.apache.commons.jexl2,15,,,,,,,,15,,,,,,,,,,,,,,,
org.apache.commons.jexl3,15,,,,,,,,15,,,,,,,,,,,,,,,
org.apache.commons.lang3,,,423,,,,,,,,,,,,,,,,,,,,292,131
org.apache.commons.ognl,6,,,,,,,,,,,,6,,,,,,,,,,,
org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,220,52
org.apache.directory.ldap.client.api,1,,,,,,,,,,1,,,,,,,,,,,,,
org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,1,
org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,1,2,39,
org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,2,
org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,18,6
org.apache.http,27,3,70,,,,,,,,,,,25,,,,,,,2,3,62,8
org.apache.ibatis.jdbc,6,,,,,,,,,,,,,,,6,,,,,,,,
org.apache.shiro.jndi,1,,,,,,,,,1,,,,,,,,,,,,,,
org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,
org.dom4j,20,,,,,,,,,,,,,,,,,,20,,,,,
org.hibernate,7,,,,,,,,,,,,,,,7,,,,,,,,
org.jooq,1,,,,,,,,,,,,,,,1,,,,,,,,
org.json,,,236,,,,,,,,,,,,,,,,,,,,198,38
org.mvel2,16,,,,,,,,,,,16,,,,,,,,,,,,
org.springframework.beans,,,26,,,,,,,,,,,,,,,,,,,,,26
org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,13
org.springframework.http,14,,70,,,,,,,,,,,14,,,,,,,,,60,10
org.springframework.jdbc.core,10,,,,,,,,,,,,,,,10,,,,,,,,
org.springframework.jdbc.object,9,,,,,,,,,,,,,,,9,,,,,,,,
org.springframework.jndi,1,,,,,,,,,1,,,,,,,,,,,,,,
org.springframework.ldap,42,,,,,,,,,28,14,,,,,,,,,,,,,
org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,6,,
org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,32
org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,87,52
org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,13,
org.springframework.web.client,13,3,,,,,,,,,,,,13,,,,,,,,3,,
org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,8,,
org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,12,13,
org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,2,,,,,,,,,,
org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,138,25
org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,1,
org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,3,,
play.mvc,,4,,,,,,,,,,,,,,,,,,,,4,,
1 package sink source summary sink:bean-validation sink:create-file sink:groovy sink:header-splitting sink:information-leak sink:jexl sink:jndi-injection sink:ldap sink:mvel sink:ognl-injection sink:open-url sink:set-hostname-verifier sink:sql sink:url-open-stream sink:url-redirect sink:xpath sink:xslt sink:xss source:remote summary:taint summary:value
2 android.content 8 4 8 4
3 android.database 59 30 59 30
4 android.net 60 45 15
5 android.util 16 16
6 android.webkit 3 2 3 2
7 com.esotericsoftware.kryo.io 1 1
8 com.esotericsoftware.kryo5.io 1 1
9 com.fasterxml.jackson.core 1 1
10 com.fasterxml.jackson.databind 5 5
11 com.google.common.base 85 62 23
12 com.google.common.cache 17 17
13 com.google.common.collect 553 2 551
14 com.google.common.io 6 73 6 72 1
15 com.opensymphony.xwork2.ognl 3 3
16 com.unboundid.ldap.sdk 17 17
17 flexjson 1 1
18 groovy.lang 26 26
19 groovy.util 5 5
20 jakarta.faces.context 2 7 2 7
21 jakarta.json 123 100 23
22 jakarta.ws.rs.client 1 1
23 jakarta.ws.rs.container 9 9
24 jakarta.ws.rs.core 2 149 2 94 55
25 java.beans 1 1
26 java.io 3 27 3 26 1
27 java.lang 47 41 6
28 java.net 10 3 7 10 3 7
29 java.nio 10 4 10 4
30 java.sql 7 7
31 java.util 337 15 322
32 javax.faces.context 2 7 2 7
33 javax.json 123 100 23
34 javax.management.remote 2 2
35 javax.naming 7 6 1
36 javax.net.ssl 2 2
37 javax.script 1 1
38 javax.servlet 4 21 2 3 1 21 2
39 javax.validation 1 1 1 1
40 javax.ws.rs.client 1 1
41 javax.ws.rs.container 9 9
42 javax.ws.rs.core 3 149 1 2 94 55
43 javax.xml.transform.sax javax.xml.transform 1 4 6 1 4 6
44 javax.xml.transform.stream javax.xml.xpath 3 2 3 2
45 javax.xml.xpath jodd.json 3 10 3 10
46 jodd.json net.sf.saxon.s9api 5 10 5 10
47 ognl 6 6
48 org.apache.commons.codec 6 6
49 org.apache.commons.collections 394 9 385
50 org.apache.commons.collections4 394 9 385
51 org.apache.commons.io 22 22
52 org.apache.commons.jexl2 15 15
53 org.apache.commons.jexl3 15 15
54 org.apache.commons.lang3 423 292 131
55 org.apache.commons.ognl 6 6
56 org.apache.commons.text 272 220 52
57 org.apache.directory.ldap.client.api 1 1
58 org.apache.hc.core5.function 1 1
59 org.apache.hc.core5.http 1 2 39 1 2 39
60 org.apache.hc.core5.net 2 2
61 org.apache.hc.core5.util 24 18 6
62 org.apache.http 27 3 70 25 2 3 62 8
63 org.apache.ibatis.jdbc 6 6
64 org.apache.shiro.jndi 1 1
65 org.codehaus.groovy.control 1 1
66 org.dom4j 20 20
67 org.hibernate 7 7
68 org.jooq 1 1
69 org.json 236 198 38
70 org.mvel2 16 16
71 org.springframework.beans 26 26
72 org.springframework.cache 13 13
73 org.springframework.http 14 70 14 60 10
74 org.springframework.jdbc.core 10 10
75 org.springframework.jdbc.object 9 9
76 org.springframework.jndi 1 1
77 org.springframework.ldap 42 28 14
78 org.springframework.security.web.savedrequest 6 6
79 org.springframework.ui 32 32
80 org.springframework.util 139 87 52
81 org.springframework.validation 13 13
82 org.springframework.web.client 13 3 13 3
83 org.springframework.web.context.request 8 8
84 org.springframework.web.multipart 12 13 12 13
85 org.springframework.web.reactive.function.client 2 2
86 org.springframework.web.util 163 138 25
87 org.xml.sax 1 1
88 org.xmlpull.v1 3 3
89 play.mvc 4 4

View File

@@ -16,8 +16,8 @@ Java framework & library support
`Google Guava <https://guava.dev/>`_,``com.google.common.*``,,728,6,,6,,,,,
`JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,,,
Java Standard Library,``java.*``,3,423,30,13,,,7,,,10
Java extensions,"``javax.*``, ``jakarta.*``",54,552,31,,,4,,1,1,2
Java extensions,"``javax.*``, ``jakarta.*``",54,552,32,,,4,,1,1,2
`Spring <https://spring.io/>`_,``org.springframework.*``,29,469,91,,,,19,14,,29
Others,"``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.unboundid.ldap.sdk``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``ognl``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jooq``, ``org.mvel2``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``",7,26,146,,,,14,18,,
Totals,,116,4169,402,13,6,10,107,33,1,66
Others,"``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.unboundid.ldap.sdk``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jooq``, ``org.mvel2``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``",7,26,151,,,,14,18,,
Totals,,116,4169,408,13,6,10,107,33,1,66

View File

@@ -726,6 +726,9 @@ class StringLiteral extends Literal, @stringliteral {
*/
string getRepresentedString() { result = getValue() }
/** Holds if this string literal is a text block (`""" ... """`). */
predicate isTextBlock() { getLiteral().matches("\"\"\"%") }
override string getAPrimaryQlClass() { result = "StringLiteral" }
}

View File

@@ -110,6 +110,7 @@ private module Frameworks {
private import semmle.code.java.security.MvelInjection
private import semmle.code.java.security.OgnlInjection
private import semmle.code.java.security.XPath
private import semmle.code.java.security.XsltInjection
private import semmle.code.java.frameworks.android.Android
private import semmle.code.java.frameworks.android.SQLite
private import semmle.code.java.frameworks.Jdbc

View File

@@ -247,3 +247,20 @@ class ExportedAndroidIntentInput extends RemoteFlowSource, AndroidIntentInput {
override string getSourceType() { result = "Exported Android intent source" }
}
/** A parameter of an entry-point method declared in a `ContentProvider` class. */
class AndroidContentProviderInput extends DataFlow::Node {
AndroidContentProvider declaringType;
AndroidContentProviderInput() {
sourceNode(this, "contentprovider") and
this.getEnclosingCallable().getDeclaringType() = declaringType
}
}
/** A parameter of an entry-point method declared in an exported `ContentProvider` class. */
class ExportedAndroidContentProviderInput extends RemoteFlowSource, AndroidContentProviderInput {
ExportedAndroidContentProviderInput() { declaringType.isExported() }
override string getSourceType() { result = "Exported Android content provider source" }
}

View File

@@ -95,6 +95,9 @@ private class ContainerFlowSummaries extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"java.lang;Object;true;clone;;;MapKey of Argument[-1];MapKey of ReturnValue;value",
"java.lang;Object;true;clone;;;MapValue of Argument[-1];MapValue of ReturnValue;value",
"java.lang;Object;true;clone;;;Element of Argument[-1];Element of ReturnValue;value",
"java.util;Map$Entry;true;getKey;;;MapKey of Argument[-1];ReturnValue;value",
"java.util;Map$Entry;true;getValue;;;MapValue of Argument[-1];ReturnValue;value",
"java.util;Map$Entry;true;setValue;;;MapValue of Argument[-1];ReturnValue;value",

View File

@@ -326,18 +326,24 @@ class LambdaCallKind = Method; // the "apply" method in the functional interface
/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) {
exists(FunctionalExpr func, FunctionalInterface interface |
exists(ClassInstanceExpr func, Interface t, FunctionalInterface interface |
creation.asExpr() = func and
func.asMethod() = c and
func.getType().(RefType).getSourceDeclaration() = interface and
kind = interface.getRunMethod()
func.getAnonymousClass().getAMethod() = c and
func.getConstructedType().extendsOrImplements+(t) and
t.getSourceDeclaration() = interface and
c.(Method).overridesOrInstantiates+(pragma[only_bind_into](kind)) and
pragma[only_bind_into](kind) = interface.getRunMethod().getSourceDeclaration()
)
}
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
receiver = call.(SummaryCall).getReceiver() and
getNodeDataFlowType(receiver).getSourceDeclaration().(FunctionalInterface).getRunMethod() = kind
getNodeDataFlowType(receiver)
.getSourceDeclaration()
.(FunctionalInterface)
.getRunMethod()
.getSourceDeclaration() = kind
}
/** Extra data-flow steps needed for lambda flow analysis. */

View File

@@ -72,6 +72,14 @@ class AndroidContentProvider extends ExportableAndroidComponent {
AndroidContentProvider() {
this.getASupertype*().hasQualifiedName("android.content", "ContentProvider")
}
/**
* Holds if this content provider requires read and write permissions
* in an `AndroidManifest.xml` file.
*/
predicate requiresPermissions() {
getAndroidComponentXmlElement().(AndroidProviderXmlElement).requiresPermissions()
}
}
/** An Android content resolver. */
@@ -148,3 +156,39 @@ private class UriModel extends SummaryModelCsv {
]
}
}
private class ContentProviderSourceModels extends SourceModelCsv {
override predicate row(string row) {
row =
[
// ContentInterface models are here for backwards compatibility (it was removed in API 28)
"android.content;ContentInterface;true;call;(String,String,String,Bundle);;Parameter[0..3];contentprovider",
"android.content;ContentProvider;true;call;(String,String,String,Bundle);;Parameter[0..3];contentprovider",
"android.content;ContentProvider;true;call;(String,String,Bundle);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;delete;(Uri,String,String[]);;Parameter[0..2];contentprovider",
"android.content;ContentInterface;true;delete;(Uri,Bundle);;Parameter[0..1];contentprovider",
"android.content;ContentProvider;true;delete;(Uri,Bundle);;Parameter[0..1];contentprovider",
"android.content;ContentInterface;true;getType;(Uri);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;getType;(Uri);;Parameter[0];contentprovider",
"android.content;ContentInterface;true;insert;(Uri,ContentValues,Bundle);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;insert;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;insert;(Uri,ContentValues);;Parameter[0..1];contentprovider",
"android.content;ContentInterface;true;openAssetFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;openAssetFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;openAssetFile;(Uri,String);;Parameter[0];contentprovider",
"android.content;ContentInterface;true;openTypedAssetFile;(Uri,String,Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;openTypedAssetFile;(Uri,String,Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;openTypedAssetFile;(Uri,String,Bundle);;Parameter[0..2];contentprovider",
"android.content;ContentInterface;true;openFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;openFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
"android.content;ContentProvider;true;openFile;(Uri,String);;Parameter[0];contentprovider",
"android.content;ContentInterface;true;query;(Uri,String[],Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;query;(Uri,String[],Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;query;(Uri,String[],String,String[],String);;Parameter[0..4];contentprovider",
"android.content;ContentProvider;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Parameter[0..4];contentprovider",
"android.content;ContentInterface;true;update;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;update;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider",
"android.content;ContentProvider;true;update;(Uri,ContentValues,String,String[]);;Parameter[0..3];contentprovider"
]
}
}

View File

@@ -136,6 +136,9 @@ private class ApacheCollectionsModel extends SummaryModelCsv {
}
}
// Note that when lambdas are supported we should model the package `org.apache.commons.collections4.functors`,
// and when more general callable flow is supported we should model the package
// `org.apache.commons.collections4.sequence`.
/**
* Value-propagating models for classes in the package `org.apache.commons.collections4.keyvalue`.
*/
@@ -170,6 +173,24 @@ private class ApacheKeyValueModel extends SummaryModelCsv {
".keyvalue;DefaultMapEntry;true;DefaultMapEntry;(KeyValue);;MapValue of Argument[0];MapValue of Argument[-1];value",
".keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Entry);;MapKey of Argument[0];MapKey of Argument[-1];value",
".keyvalue;DefaultMapEntry;true;DefaultMapEntry;(Entry);;MapValue of Argument[0];MapValue of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object[]);;ArrayElement of Argument[0];Element of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object[],boolean);;ArrayElement of Argument[0];Element of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object,Object);;Argument[0];Element of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object,Object);;Argument[1];Element of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object);;Argument[0];Element of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object);;Argument[1];Element of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object);;Argument[2];Element of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object);;Argument[0];Element of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object);;Argument[1];Element of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object);;Argument[2];Element of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object);;Argument[3];Element of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object,Object);;Argument[0];Element of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object,Object);;Argument[1];Element of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object,Object);;Argument[2];Element of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object,Object);;Argument[3];Element of Argument[-1];value",
".keyvalue;MultiKey;true;MultiKey;(Object,Object,Object,Object,Object);;Argument[4];Element of Argument[-1];value",
".keyvalue;MultiKey;true;getKeys;;;Element of Argument[-1];ArrayElement of ReturnValue;value",
".keyvalue;MultiKey;true;getKey;;;Element of Argument[-1];ReturnValue;value",
".keyvalue;TiedMapEntry;true;TiedMapEntry;;;MapValue of Argument[0];MapValue of Argument[-1];value",
".keyvalue;TiedMapEntry;true;TiedMapEntry;;;Argument[1];MapKey of Argument[-1];value",
".keyvalue;UnmodifiableMapEntry;true;UnmodifiableMapEntry;(Object,Object);;Argument[0];MapKey of Argument[-1];value",
@@ -182,6 +203,560 @@ private class ApacheKeyValueModel extends SummaryModelCsv {
}
}
/**
* Value-propagating models for classes in the package `org.apache.commons.collections4.bag`.
*/
private class ApacheBagModel extends SummaryModelCsv {
override predicate row(string row) {
row =
["org.apache.commons.collections4", "org.apache.commons.collections"] +
[
// Note that when lambdas are supported we should have more models for TransformedBag, TransformedSortedBag
".bag;AbstractBagDecorator;true;AbstractBagDecorator;;;Element of Argument[0];Element of Argument[-1];value",
".bag;AbstractMapBag;true;AbstractMapBag;;;MapKey of Argument[0];Element of Argument[-1];value",
".bag;AbstractMapBag;true;getMap;;;Element of Argument[-1];MapKey of ReturnValue;value",
".bag;AbstractSortedBagDecorator;true;AbstractSortedBagDecorator;;;Element of Argument[0];Element of Argument[-1];value",
".bag;CollectionBag;true;CollectionBag;;;Element of Argument[0];Element of Argument[-1];value",
".bag;CollectionBag;true;collectionBag;;;Element of Argument[0];Element of ReturnValue;value",
".bag;CollectionSortedBag;true;CollectionSortedBag;;;Element of Argument[0];Element of Argument[-1];value",
".bag;CollectionSortedBag;true;collectionSortedBag;;;Element of Argument[0];Element of ReturnValue;value",
".bag;HashBag;true;HashBag;;;Element of Argument[0];Element of Argument[-1];value",
".bag;PredicatedBag;true;predicatedBag;;;Element of Argument[0];Element of ReturnValue;value",
".bag;PredicatedSortedBag;true;predicatedSortedBag;;;Element of Argument[0];Element of ReturnValue;value",
".bag;SynchronizedBag;true;synchronizedBag;;;Element of Argument[0];Element of ReturnValue;value",
".bag;SynchronizedSortedBag;true;synchronizedSortedBag;;;Element of Argument[0];Element of ReturnValue;value",
".bag;TransformedBag;true;transformedBag;;;Element of Argument[0];Element of ReturnValue;value",
".bag;TransformedSortedBag;true;transformedSortedBag;;;Element of Argument[0];Element of ReturnValue;value",
".bag;TreeBag;true;TreeBag;(Collection);;Element of Argument[0];Element of Argument[-1];value",
".bag;UnmodifiableBag;true;unmodifiableBag;;;Element of Argument[0];Element of ReturnValue;value",
".bag;UnmodifiableSortedBag;true;unmodifiableSortedBag;;;Element of Argument[0];Element of ReturnValue;value"
]
}
}
/**
* Value-propagating models for classes in the package `org.apache.commons.collections4.bidimap`.
*/
private class ApacheBidiMapModel extends SummaryModelCsv {
override predicate row(string row) {
row =
["org.apache.commons.collections4", "org.apache.commons.collections"] +
[
".bidimap;AbstractBidiMapDecorator;true;AbstractBidiMapDecorator;;;MapKey of Argument[0];MapKey of Argument[-1];value",
".bidimap;AbstractBidiMapDecorator;true;AbstractBidiMapDecorator;;;MapValue of Argument[0];MapValue of Argument[-1];value",
".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;MapKey of Argument[0];MapKey of Argument[-1];value",
".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;MapValue of Argument[0];MapValue of Argument[-1];value",
".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;MapKey of Argument[1];MapValue of Argument[-1];value",
".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;MapValue of Argument[1];MapKey of Argument[-1];value",
".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;MapKey of Argument[2];MapValue of Argument[-1];value",
".bidimap;AbstractDualBidiMap;true;AbstractDualBidiMap;;;MapValue of Argument[2];MapKey of Argument[-1];value",
".bidimap;AbstractOrderedBidiMapDecorator;true;AbstractOrderedBidiMapDecorator;;;MapKey of Argument[0];MapKey of Argument[-1];value",
".bidimap;AbstractOrderedBidiMapDecorator;true;AbstractOrderedBidiMapDecorator;;;MapValue of Argument[0];MapValue of Argument[-1];value",
".bidimap;AbstractSortedBidiMapDecorator;true;AbstractSortedBidiMapDecorator;;;MapKey of Argument[0];MapKey of Argument[-1];value",
".bidimap;AbstractSortedBidiMapDecorator;true;AbstractSortedBidiMapDecorator;;;MapValue of Argument[0];MapValue of Argument[-1];value",
".bidimap;DualHashBidiMap;true;DualHashBidiMap;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
".bidimap;DualHashBidiMap;true;DualHashBidiMap;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
".bidimap;DualLinkedHashBidiMap;true;DualLinkedHashBidiMap;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
".bidimap;DualLinkedHashBidiMap;true;DualLinkedHashBidiMap;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
".bidimap;DualTreeBidiMap;true;DualTreeBidiMap;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
".bidimap;DualTreeBidiMap;true;DualTreeBidiMap;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
".bidimap;DualTreeBidiMap;true;inverseOrderedBidiMap;;;MapKey of Argument[-1];MapValue of ReturnValue;value",
".bidimap;DualTreeBidiMap;true;inverseOrderedBidiMap;;;MapValue of Argument[-1];MapKey of ReturnValue;value",
".bidimap;DualTreeBidiMap;true;inverseSortedBidiMap;;;MapKey of Argument[-1];MapValue of ReturnValue;value",
".bidimap;DualTreeBidiMap;true;inverseSortedBidiMap;;;MapValue of Argument[-1];MapKey of ReturnValue;value",
".bidimap;TreeBidiMap;true;TreeBidiMap;;;MapKey of Argument[0];MapKey of Argument[-1];value",
".bidimap;TreeBidiMap;true;TreeBidiMap;;;MapValue of Argument[0];MapValue of Argument[-1];value",
".bidimap;UnmodifiableBidiMap;true;unmodifiableBidiMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".bidimap;UnmodifiableBidiMap;true;unmodifiableBidiMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".bidimap;UnmodifiableOrderedBidiMap;true;unmodifiableOrderedBidiMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".bidimap;UnmodifiableOrderedBidiMap;true;unmodifiableOrderedBidiMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".bidimap;UnmodifiableOrderedBidiMap;true;inverseOrderedBidiMap;;;MapKey of Argument[-1];MapValue of ReturnValue;value",
".bidimap;UnmodifiableOrderedBidiMap;true;inverseOrderedBidiMap;;;MapValue of Argument[-1];MapKey of ReturnValue;value",
".bidimap;UnmodifiableSortedBidiMap;true;unmodifiableSortedBidiMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".bidimap;UnmodifiableSortedBidiMap;true;unmodifiableSortedBidiMap;;;MapValue of Argument[0];MapValue of ReturnValue;value"
]
}
}
/**
* Value-propagating models for classes in the package `org.apache.commons.collections4.collection`.
*/
private class ApacheCollectionModel extends SummaryModelCsv {
override predicate row(string row) {
row =
["org.apache.commons.collections4", "org.apache.commons.collections"] +
[
// Note that when lambdas are supported we should have more models for TransformedCollection
".collection;AbstractCollectionDecorator;true;AbstractCollectionDecorator;;;Element of Argument[0];Element of Argument[-1];value",
".collection;AbstractCollectionDecorator;true;decorated;;;Element of Argument[-1];Element of ReturnValue;value",
".collection;AbstractCollectionDecorator;true;setCollection;;;Element of Argument[0];Element of Argument[-1];value",
".collection;CompositeCollection$CollectionMutator;true;add;;;Argument[2];Element of Argument[0];value",
".collection;CompositeCollection$CollectionMutator;true;add;;;Argument[2];Element of Element of Argument[1];value",
".collection;CompositeCollection$CollectionMutator;true;addAll;;;Element of Argument[2];Element of Argument[0];value",
".collection;CompositeCollection$CollectionMutator;true;addAll;;;Element of Argument[2];Element of Element of Argument[1];value",
".collection;CompositeCollection;true;CompositeCollection;(Collection);;Element of Argument[0];Element of Argument[-1];value",
".collection;CompositeCollection;true;CompositeCollection;(Collection,Collection);;Element of Argument[0];Element of Argument[-1];value",
".collection;CompositeCollection;true;CompositeCollection;(Collection,Collection);;Element of Argument[1];Element of Argument[-1];value",
".collection;CompositeCollection;true;CompositeCollection;(Collection[]);;Element of ArrayElement of Argument[0];Element of Argument[-1];value",
".collection;CompositeCollection;true;addComposited;(Collection);;Element of Argument[0];Element of Argument[-1];value",
".collection;CompositeCollection;true;addComposited;(Collection,Collection);;Element of Argument[0];Element of Argument[-1];value",
".collection;CompositeCollection;true;addComposited;(Collection,Collection);;Element of Argument[1];Element of Argument[-1];value",
".collection;CompositeCollection;true;addComposited;(Collection[]);;Element of ArrayElement of Argument[0];Element of Argument[-1];value",
".collection;CompositeCollection;true;toCollection;;;Element of Argument[-1];Element of ReturnValue;value",
".collection;CompositeCollection;true;getCollections;;;Element of Argument[-1];Element of Element of ReturnValue;value",
".collection;IndexedCollection;true;IndexedCollection;;;Element of Argument[0];Element of Argument[-1];value",
".collection;IndexedCollection;true;uniqueIndexedCollection;;;Element of Argument[0];Element of ReturnValue;value",
".collection;IndexedCollection;true;nonUniqueIndexedCollection;;;Element of Argument[0];Element of ReturnValue;value",
".collection;IndexedCollection;true;get;;;Element of Argument[-1];ReturnValue;value",
".collection;IndexedCollection;true;values;;;Element of Argument[-1];Element of ReturnValue;value",
".collection;PredicatedCollection$Builder;true;add;;;Argument[0];Element of Argument[-1];value",
".collection;PredicatedCollection$Builder;true;addAll;;;Element of Argument[0];Element of Argument[-1];value",
".collection;PredicatedCollection$Builder;true;createPredicatedList;;;Element of Argument[-1];Element of ReturnValue;value",
".collection;PredicatedCollection$Builder;true;createPredicatedList;;;Element of Argument[0];Element of ReturnValue;value",
".collection;PredicatedCollection$Builder;true;createPredicatedSet;;;Element of Argument[-1];Element of ReturnValue;value",
".collection;PredicatedCollection$Builder;true;createPredicatedSet;;;Element of Argument[0];Element of ReturnValue;value",
".collection;PredicatedCollection$Builder;true;createPredicatedMultiSet;;;Element of Argument[-1];Element of ReturnValue;value",
".collection;PredicatedCollection$Builder;true;createPredicatedMultiSet;;;Element of Argument[0];Element of ReturnValue;value",
".collection;PredicatedCollection$Builder;true;createPredicatedBag;;;Element of Argument[-1];Element of ReturnValue;value",
".collection;PredicatedCollection$Builder;true;createPredicatedBag;;;Element of Argument[0];Element of ReturnValue;value",
".collection;PredicatedCollection$Builder;true;createPredicatedQueue;;;Element of Argument[-1];Element of ReturnValue;value",
".collection;PredicatedCollection$Builder;true;createPredicatedQueue;;;Element of Argument[0];Element of ReturnValue;value",
".collection;PredicatedCollection$Builder;true;rejectedElements;;;Element of Argument[-1];Element of ReturnValue;value",
".collection;PredicatedCollection;true;predicatedCollection;;;Element of Argument[0];Element of ReturnValue;value",
".collection;SynchronizedCollection;true;synchronizedCollection;;;Element of Argument[0];Element of ReturnValue;value",
".collection;TransformedCollection;true;transformingCollection;;;Element of Argument[0];Element of ReturnValue;value",
".collection;UnmodifiableBoundedCollection;true;unmodifiableBoundedCollection;;;Element of Argument[0];Element of ReturnValue;value",
".collection;UnmodifiableCollection;true;unmodifiableCollection;;;Element of Argument[0];Element of ReturnValue;value"
]
}
}
/**
* Value-propagating models for the package `org.apache.commons.collections4.iterators`.
*/
private class ApacheIteratorsModel extends SummaryModelCsv {
override predicate row(string row) {
row =
["org.apache.commons.collections4", "org.apache.commons.collections"] +
[
// Note that when lambdas are supported we should have more models for TransformIterator
".iterators;AbstractIteratorDecorator;true;AbstractIteratorDecorator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;AbstractListIteratorDecorator;true;AbstractListIteratorDecorator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;AbstractListIteratorDecorator;true;getListIterator;;;Element of Argument[-1];Element of ReturnValue;value",
".iterators;AbstractMapIteratorDecorator;true;AbstractMapIteratorDecorator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;AbstractMapIteratorDecorator;true;AbstractMapIteratorDecorator;;;MapValue of Argument[0];MapValue of Argument[-1];value",
".iterators;AbstractMapIteratorDecorator;true;getMapIterator;;;Element of Argument[-1];Element of ReturnValue;value",
".iterators;AbstractMapIteratorDecorator;true;getMapIterator;;;MapValue of Argument[-1];MapValue of ReturnValue;value",
".iterators;AbstractOrderedMapIteratorDecorator;true;AbstractOrderedMapIteratorDecorator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;AbstractOrderedMapIteratorDecorator;true;AbstractOrderedMapIteratorDecorator;;;MapValue of Argument[0];MapValue of Argument[-1];value",
".iterators;AbstractOrderedMapIteratorDecorator;true;getOrderedMapIterator;;;Element of Argument[-1];Element of ReturnValue;value",
".iterators;AbstractOrderedMapIteratorDecorator;true;getOrderedMapIterator;;;MapValue of Argument[-1];MapValue of ReturnValue;value",
".iterators;AbstractUntypedIteratorDecorator;true;AbstractUntypedIteratorDecorator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;AbstractUntypedIteratorDecorator;true;getIterator;;;Element of Argument[-1];Element of ReturnValue;value",
".iterators;ArrayIterator;true;ArrayIterator;;;ArrayElement of Argument[0];Element of Argument[-1];value",
".iterators;ArrayIterator;true;getArray;;;Element of Argument[-1];ArrayElement of ReturnValue;value",
".iterators;ArrayListIterator;true;ArrayListIterator;;;ArrayElement of Argument[0];Element of Argument[-1];value",
".iterators;BoundedIterator;true;BoundedIterator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;CollatingIterator;true;CollatingIterator;(Comparator,Iterator,Iterator);;Element of Argument[1];Element of Argument[-1];value",
".iterators;CollatingIterator;true;CollatingIterator;(Comparator,Iterator,Iterator);;Element of Argument[2];Element of Argument[-1];value",
".iterators;CollatingIterator;true;CollatingIterator;(Comparator,Iterator[]);;Element of ArrayElement of Argument[1];Element of Argument[-1];value",
".iterators;CollatingIterator;true;CollatingIterator;(Comparator,Collection);;Element of Element of Argument[1];Element of Argument[-1];value",
".iterators;CollatingIterator;true;addIterator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;CollatingIterator;true;setIterator;;;Element of Argument[1];Element of Argument[-1];value",
".iterators;CollatingIterator;true;getIterators;;;Element of Argument[-1];Element of Element of ReturnValue;value",
".iterators;EnumerationIterator;true;EnumerationIterator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;EnumerationIterator;true;getEnumeration;;;Element of Argument[-1];Element of ReturnValue;value",
".iterators;EnumerationIterator;true;setEnumeration;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;FilterIterator;true;FilterIterator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;FilterIterator;true;getIterator;;;Element of Argument[-1];Element of ReturnValue;value",
".iterators;FilterIterator;true;setIterator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;FilterListIterator;true;FilterListIterator;(ListIterator);;Element of Argument[0];Element of Argument[-1];value",
".iterators;FilterListIterator;true;FilterListIterator;(ListIterator,Predicate);;Element of Argument[0];Element of Argument[-1];value",
".iterators;FilterListIterator;true;getListIterator;;;Element of Argument[-1];Element of ReturnValue;value",
".iterators;FilterListIterator;true;setListIterator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;IteratorChain;true;IteratorChain;(Iterator);;Element of Argument[0];Element of Argument[-1];value",
".iterators;IteratorChain;true;IteratorChain;(Iterator,Iterator);;Element of Argument[0];Element of Argument[-1];value",
".iterators;IteratorChain;true;IteratorChain;(Iterator,Iterator);;Element of Argument[1];Element of Argument[-1];value",
".iterators;IteratorChain;true;IteratorChain;(Iterator[]);;Element of ArrayElement of Argument[0];Element of Argument[-1];value",
".iterators;IteratorChain;true;IteratorChain;(Collection);;Element of Element of Argument[0];Element of Argument[-1];value",
".iterators;IteratorChain;true;addIterator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;IteratorEnumeration;true;IteratorEnumeration;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;IteratorEnumeration;true;getIterator;;;Element of Argument[-1];Element of ReturnValue;value",
".iterators;IteratorEnumeration;true;setIterator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;IteratorIterable;true;IteratorIterable;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;ListIteratorWrapper;true;ListIteratorWrapper;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;LoopingIterator;true;LoopingIterator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;LoopingListIterator;true;LoopingListIterator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;ObjectArrayIterator;true;ObjectArrayIterator;;;ArrayElement of Argument[0];Element of Argument[-1];value",
".iterators;ObjectArrayIterator;true;getArray;;;Element of Argument[-1];ArrayElement of ReturnValue;value",
".iterators;ObjectArrayListIterator;true;ObjectArrayListIterator;;;ArrayElement of Argument[0];Element of Argument[-1];value",
".iterators;PeekingIterator;true;PeekingIterator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;PeekingIterator;true;peekingIterator;;;Element of Argument[0];Element of ReturnValue;value",
".iterators;PeekingIterator;true;peek;;;Element of Argument[-1];ReturnValue;value",
".iterators;PeekingIterator;true;element;;;Element of Argument[-1];ReturnValue;value",
".iterators;PermutationIterator;true;PermutationIterator;;;Element of Argument[0];Element of Element of Argument[-1];value",
".iterators;PushbackIterator;true;PushbackIterator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;PushbackIterator;true;pushbackIterator;;;Element of Argument[0];Element of ReturnValue;value",
".iterators;PushbackIterator;true;pushback;;;Argument[0];Element of Argument[-1];value",
".iterators;ReverseListIterator;true;ReverseListIterator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;SingletonIterator;true;SingletonIterator;;;Argument[0];Element of Argument[-1];value",
".iterators;SingletonListIterator;true;SingletonListIterator;;;Argument[0];Element of Argument[-1];value",
".iterators;SkippingIterator;true;SkippingIterator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;UniqueFilterIterator;true;UniqueFilterIterator;;;Element of Argument[0];Element of Argument[-1];value",
".iterators;UnmodifiableIterator;true;unmodifiableIterator;;;Element of Argument[0];Element of ReturnValue;value",
".iterators;UnmodifiableListIterator;true;umodifiableListIterator;;;Element of Argument[0];Element of ReturnValue;value",
".iterators;UnmodifiableMapIterator;true;unmodifiableMapIterator;;;Element of Argument[0];Element of ReturnValue;value",
".iterators;UnmodifiableMapIterator;true;unmodifiableMapIterator;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".iterators;UnmodifiableOrderedMapIterator;true;unmodifiableOrderedMapIterator;;;Element of Argument[0];Element of ReturnValue;value",
".iterators;UnmodifiableOrderedMapIterator;true;unmodifiableOrderedMapIterator;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".iterators;ZippingIterator;true;ZippingIterator;(Iterator[]);;Element of ArrayElement of Argument[0];Element of Argument[-1];value",
".iterators;ZippingIterator;true;ZippingIterator;(Iterator,Iterator);;Element of Argument[0];Element of Argument[-1];value",
".iterators;ZippingIterator;true;ZippingIterator;(Iterator,Iterator);;Element of Argument[1];Element of Argument[-1];value",
".iterators;ZippingIterator;true;ZippingIterator;(Iterator,Iterator,Iterator);;Element of Argument[0];Element of Argument[-1];value",
".iterators;ZippingIterator;true;ZippingIterator;(Iterator,Iterator,Iterator);;Element of Argument[1];Element of Argument[-1];value",
".iterators;ZippingIterator;true;ZippingIterator;(Iterator,Iterator,Iterator);;Element of Argument[2];Element of Argument[-1];value"
]
}
}
/**
* Value-propagating models for the package `org.apache.commons.collections4.list`.
*/
private class ApacheListModel extends SummaryModelCsv {
override predicate row(string row) {
row =
["org.apache.commons.collections4", "org.apache.commons.collections"] +
[
// Note that when lambdas are supported we should have more models for TransformedList
".list;AbstractLinkedList;true;AbstractLinkedList;;;Element of Argument[0];Element of Argument[-1];value",
".list;AbstractLinkedList;true;getFirst;;;Element of Argument[-1];ReturnValue;value",
".list;AbstractLinkedList;true;getLast;;;Element of Argument[-1];ReturnValue;value",
".list;AbstractLinkedList;true;addFirst;;;Argument[0];Element of Argument[-1];value",
".list;AbstractLinkedList;true;addLast;;;Argument[0];Element of Argument[-1];value",
".list;AbstractLinkedList;true;removeFirst;;;Element of Argument[-1];ReturnValue;value",
".list;AbstractLinkedList;true;removeLast;;;Element of Argument[-1];ReturnValue;value",
".list;AbstractListDecorator;true;AbstractListDecorator;;;Element of Argument[0];Element of Argument[-1];value",
".list;AbstractSerializableListDecorator;true;AbstractSerializableListDecorator;;;Element of Argument[0];Element of Argument[-1];value",
".list;CursorableLinkedList;true;CursorableLinkedList;;;Element of Argument[0];Element of Argument[-1];value",
".list;CursorableLinkedList;true;cursor;;;Element of Argument[-1];Element of ReturnValue;value",
".list;FixedSizeList;true;fixedSizeList;;;Element of Argument[0];Element of ReturnValue;value",
".list;GrowthList;true;growthList;;;Element of Argument[0];Element of ReturnValue;value",
".list;LazyList;true;lazyList;;;Element of Argument[0];Element of ReturnValue;value",
".list;NodeCachingLinkedList;true;NodeCachingLinkedList;(Collection);;Element of Argument[0];Element of Argument[-1];value",
".list;PredicatedList;true;predicatedList;;;Element of Argument[0];Element of ReturnValue;value",
".list;SetUniqueList;true;setUniqueList;;;Element of Argument[0];Element of ReturnValue;value",
".list;SetUniqueList;true;asSet;;;Element of Argument[-1];Element of ReturnValue;value",
".list;TransformedList;true;transformingList;;;Element of Argument[0];Element of ReturnValue;value",
".list;TreeList;true;TreeList;;;Element of Argument[0];Element of Argument[-1];value",
".list;UnmodifiableList;true;UnmodifiableList;;;Element of Argument[0];Element of Argument[-1];value",
".list;UnmodifiableList;true;unmodifiableList;;;Element of Argument[0];Element of ReturnValue;value"
]
}
}
/**
* Value-propagating models for the package `org.apache.commons.collections4.map`.
*/
private class ApacheMapModel extends SummaryModelCsv {
override predicate row(string row) {
row =
["org.apache.commons.collections4", "org.apache.commons.collections"] +
[
// Note that when lambdas are supported we should have more models for DefaultedMap, LazyMap, TransformedMap, TransformedSortedMap
".map;AbstractHashedMap;true;AbstractHashedMap;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;AbstractHashedMap;true;AbstractHashedMap;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;AbstractLinkedMap;true;AbstractLinkedMap;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;AbstractLinkedMap;true;AbstractLinkedMap;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;AbstractMapDecorator;true;AbstractMapDecorator;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;AbstractMapDecorator;true;AbstractMapDecorator;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;AbstractMapDecorator;true;decorated;;;MapKey of Argument[-1];MapKey of ReturnValue;value",
".map;AbstractMapDecorator;true;decorated;;;MapValue of Argument[-1];MapValue of ReturnValue;value",
".map;AbstractOrderedMapDecorator;true;AbstractOrderedMapDecorator;(OrderedMap);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;AbstractOrderedMapDecorator;true;AbstractOrderedMapDecorator;(OrderedMap);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;AbstractSortedMapDecorator;true;AbstractSortedMapDecorator;(SortedMap);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;AbstractSortedMapDecorator;true;AbstractSortedMapDecorator;(SortedMap);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;CaseInsensitiveMap;true;CaseInsensitiveMap;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;CaseInsensitiveMap;true;CaseInsensitiveMap;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;CompositeMap;true;CompositeMap;(Map,Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;CompositeMap;true;CompositeMap;(Map,Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;CompositeMap;true;CompositeMap;(Map,Map);;MapKey of Argument[1];MapKey of Argument[-1];value",
".map;CompositeMap;true;CompositeMap;(Map,Map);;MapValue of Argument[1];MapValue of Argument[-1];value",
".map;CompositeMap;true;CompositeMap;(Map,Map,MapMutator);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;CompositeMap;true;CompositeMap;(Map,Map,MapMutator);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;CompositeMap;true;CompositeMap;(Map,Map,MapMutator);;MapKey of Argument[1];MapKey of Argument[-1];value",
".map;CompositeMap;true;CompositeMap;(Map,Map,MapMutator);;MapValue of Argument[1];MapValue of Argument[-1];value",
".map;CompositeMap;true;CompositeMap;(Map[]);;MapKey of ArrayElement of Argument[0];MapKey of Argument[-1];value",
".map;CompositeMap;true;CompositeMap;(Map[]);;MapValue of ArrayElement of Argument[0];MapValue of Argument[-1];value",
".map;CompositeMap;true;CompositeMap;(Map[],MapMutator);;MapKey of ArrayElement of Argument[0];MapKey of Argument[-1];value",
".map;CompositeMap;true;CompositeMap;(Map[],MapMutator);;MapValue of ArrayElement of Argument[0];MapValue of Argument[-1];value",
".map;CompositeMap;true;addComposited;;;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;CompositeMap;true;addComposited;;;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;CompositeMap;true;removeComposited;;;MapKey of Argument[-1];MapKey of ReturnValue;value",
".map;CompositeMap;true;removeComposited;;;MapValue of Argument[-1];MapValue of ReturnValue;value",
".map;CompositeMap;true;removeComposited;;;Argument[0];ReturnValue;value",
".map;DefaultedMap;true;DefaultedMap;(Object);;Argument[0];MapValue of Argument[-1];value",
".map;DefaultedMap;true;defaultedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".map;DefaultedMap;true;defaultedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".map;DefaultedMap;true;defaultedMap;(Map,Object);;Argument[1];MapValue of ReturnValue;value",
".map;EntrySetToMapIteratorAdapter;true;EntrySetToMapIteratorAdapter;;;MapKey of Element of Argument[0];Element of Argument[-1];value",
".map;EntrySetToMapIteratorAdapter;true;EntrySetToMapIteratorAdapter;;;MapValue of Element of Argument[0];MapValue of Argument[-1];value",
".map;FixedSizeMap;true;fixedSizeMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".map;FixedSizeMap;true;fixedSizeMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".map;FixedSizeSortedMap;true;fixedSizeSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".map;FixedSizeSortedMap;true;fixedSizeSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".map;Flat3Map;true;Flat3Map;;;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;Flat3Map;true;Flat3Map;;;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;HashedMap;true;HashedMap;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;HashedMap;true;HashedMap;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;LazyMap;true;lazyMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".map;LazyMap;true;lazyMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".map;LazySortedMap;true;lazySortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".map;LazySortedMap;true;lazySortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".map;LinkedMap;true;LinkedMap;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;LinkedMap;true;LinkedMap;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;LinkedMap;true;get;(int);;MapKey of Argument[-1];ReturnValue;value",
".map;LinkedMap;true;getValue;(int);;MapValue of Argument[-1];ReturnValue;value",
".map;LinkedMap;true;remove;(int);;MapValue of Argument[-1];ReturnValue;value",
".map;LinkedMap;true;asList;;;MapKey of Argument[-1];Element of ReturnValue;value",
".map;ListOrderedMap;true;listOrderedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".map;ListOrderedMap;true;listOrderedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".map;ListOrderedMap;true;putAll;;;MapKey of Argument[1];MapKey of Argument[-1];value",
".map;ListOrderedMap;true;putAll;;;MapValue of Argument[1];MapValue of Argument[-1];value",
".map;ListOrderedMap;true;keyList;;;MapKey of Argument[-1];Element of ReturnValue;value",
".map;ListOrderedMap;true;valueList;;;MapValue of Argument[-1];Element of ReturnValue;value",
".map;ListOrderedMap;true;get;(int);;MapKey of Argument[-1];ReturnValue;value",
".map;ListOrderedMap;true;getValue;(int);;MapValue of Argument[-1];ReturnValue;value",
".map;ListOrderedMap;true;setValue;;;Argument[1];MapValue of Argument[-1];value",
".map;ListOrderedMap;true;put;;;Argument[1];MapKey of Argument[-1];value",
".map;ListOrderedMap;true;put;;;Argument[2];MapValue of Argument[-1];value",
".map;ListOrderedMap;true;remove;(int);;MapValue of Argument[-1];ReturnValue;value",
".map;ListOrderedMap;true;asList;;;MapKey of Argument[-1];Element of ReturnValue;value",
".map;LRUMap;true;LRUMap;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;LRUMap;true;LRUMap;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;LRUMap;true;LRUMap;(Map,boolean);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;LRUMap;true;LRUMap;(Map,boolean);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;LRUMap;true;get;(Object,boolean);;MapValue of Argument[0];ReturnValue;value",
".map;MultiKeyMap;true;get;;;MapValue of Argument[-1];ReturnValue;value",
".map;MultiKeyMap;true;put;;;MapValue of Argument[-1];ReturnValue;value",
".map;MultiKeyMap;true;put;(Object,Object,Object);;Argument[0..1];Element of MapKey of Argument[-1];value",
".map;MultiKeyMap;true;put;(Object,Object,Object,Object);;Argument[0..2];Element of MapKey of Argument[-1];value",
".map;MultiKeyMap;true;put;(Object,Object,Object,Object,Object);;Argument[0..3];Element of MapKey of Argument[-1];value",
".map;MultiKeyMap;true;put;(Object,Object,Object,Object,Object,Object);;Argument[0..4];Element of MapKey of Argument[-1];value",
".map;MultiKeyMap;true;put;(Object,Object,Object);;Argument[2];MapValue of Argument[-1];value",
".map;MultiKeyMap;true;put;(Object,Object,Object,Object);;Argument[3];MapValue of Argument[-1];value",
".map;MultiKeyMap;true;put;(Object,Object,Object,Object,Object);;Argument[4];MapValue of Argument[-1];value",
".map;MultiKeyMap;true;put;(Object,Object,Object,Object,Object,Object);;Argument[5];MapValue of Argument[-1];value",
".map;MultiKeyMap;true;removeMultiKey;;;MapValue of Argument[-1];ReturnValue;value",
".map;MultiValueMap;true;multiValueMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".map;MultiValueMap;true;multiValueMap;;;Element of MapValue of Argument[0];Element of MapValue of ReturnValue;value",
".map;MultiValueMap;true;getCollection;;;Element of MapValue of Argument[-1];Element of ReturnValue;value",
".map;MultiValueMap;true;putAll;(Map);;MapValue of Argument[0];Element of MapValue of Argument[-1];value",
".map;MultiValueMap;true;putAll;(Map);;Element of MapValue of Argument[0];Element of MapValue of Argument[-1];value",
".map;MultiValueMap;true;values;;;Element of MapValue of Argument[-1];Element of ReturnValue;value",
".map;MultiValueMap;true;putAll;(Object,Collection);;Argument[0];MapKey of Argument[-1];value",
".map;MultiValueMap;true;putAll;(Object,Collection);;Element of Argument[1];Element of MapValue of Argument[-1];value",
".map;MultiValueMap;true;iterator;(Object);;Element of MapValue of Argument[-1];Element of ReturnValue;value",
".map;MultiValueMap;true;iterator;();;MapKey of Argument[-1];MapKey of Element of ReturnValue;value",
".map;MultiValueMap;true;iterator;();;Element of MapValue of Argument[-1];MapValue of Element of ReturnValue;value",
".map;PassiveExpiringMap;true;PassiveExpiringMap;(ExpirationPolicy,Map);;MapKey of Argument[1];MapKey of Argument[-1];value",
".map;PassiveExpiringMap;true;PassiveExpiringMap;(ExpirationPolicy,Map);;MapValue of Argument[1];MapValue of Argument[-1];value",
".map;PassiveExpiringMap;true;PassiveExpiringMap;(long,Map);;MapKey of Argument[1];MapKey of Argument[-1];value",
".map;PassiveExpiringMap;true;PassiveExpiringMap;(long,Map);;MapValue of Argument[1];MapValue of Argument[-1];value",
".map;PassiveExpiringMap;true;PassiveExpiringMap;(long,TimeUnit,Map);;MapKey of Argument[2];MapKey of Argument[-1];value",
".map;PassiveExpiringMap;true;PassiveExpiringMap;(long,TimeUnit,Map);;MapValue of Argument[2];MapValue of Argument[-1];value",
".map;PassiveExpiringMap;true;PassiveExpiringMap;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;PassiveExpiringMap;true;PassiveExpiringMap;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;PredicatedMap;true;predicatedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".map;PredicatedMap;true;predicatedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".map;PredicatedSortedMap;true;predicatedSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".map;PredicatedSortedMap;true;predicatedSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".map;SingletonMap;true;SingletonMap;(Object,Object);;Argument[0];MapKey of Argument[-1];value",
".map;SingletonMap;true;SingletonMap;(Object,Object);;Argument[1];MapValue of Argument[-1];value",
".map;SingletonMap;true;SingletonMap;(KeyValue);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;SingletonMap;true;SingletonMap;(KeyValue);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;SingletonMap;true;SingletonMap;(Entry);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;SingletonMap;true;SingletonMap;(Entry);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;SingletonMap;true;SingletonMap;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
".map;SingletonMap;true;SingletonMap;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
".map;SingletonMap;true;setValue;;;Argument[0];MapValue of Argument[-1];value",
".map;TransformedMap;true;transformingMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".map;TransformedMap;true;transformingMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".map;TransformedSortedMap;true;transformingSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".map;TransformedSortedMap;true;transformingSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".map;UnmodifiableEntrySet;true;unmodifiableEntrySet;;;MapKey of Element of Argument[0];MapKey of Element of ReturnValue;value",
".map;UnmodifiableEntrySet;true;unmodifiableEntrySet;;;MapValue of Element of Argument[0];MapValue of Element of ReturnValue;value",
".map;UnmodifiableMap;true;unmodifiableMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".map;UnmodifiableMap;true;unmodifiableMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".map;UnmodifiableOrderedMap;true;unmodifiableOrderedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".map;UnmodifiableOrderedMap;true;unmodifiableOrderedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
".map;UnmodifiableSortedMap;true;unmodifiableSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".map;UnmodifiableSortedMap;true;unmodifiableSortedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value"
]
}
}
/**
* Value-propagating models for the package `org.apache.commons.collections4.multimap`.
*/
private class ApacheMultiMapModel extends SummaryModelCsv {
override predicate row(string row) {
row =
["org.apache.commons.collections4", "org.apache.commons.collections"] +
[
// Note that when lambdas are supported we should have more models for TransformedMultiValuedMap
".multimap;ArrayListValuedHashMap;true;ArrayListValuedHashMap;(MultiValuedMap);;MapKey of Argument[0];MapKey of Argument[-1];value",
".multimap;ArrayListValuedHashMap;true;ArrayListValuedHashMap;(MultiValuedMap);;Element of MapValue of Argument[0];Element of MapValue of Argument[-1];value",
".multimap;ArrayListValuedHashMap;true;ArrayListValuedHashMap;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
".multimap;ArrayListValuedHashMap;true;ArrayListValuedHashMap;(Map);;MapValue of Argument[0];Element of MapValue of Argument[-1];value",
".multimap;HashSetValuedHashMap;true;HashSetValuedHashMap;(MultiValuedMap);;MapKey of Argument[0];MapKey of Argument[-1];value",
".multimap;HashSetValuedHashMap;true;HashSetValuedHashMap;(MultiValuedMap);;Element of MapValue of Argument[0];Element of MapValue of Argument[-1];value",
".multimap;HashSetValuedHashMap;true;HashSetValuedHashMap;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
".multimap;HashSetValuedHashMap;true;HashSetValuedHashMap;(Map);;MapValue of Argument[0];Element of MapValue of Argument[-1];value",
".multimap;TransformedMultiValuedMap;true;transformingMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".multimap;TransformedMultiValuedMap;true;transformingMap;;;Element of MapValue of Argument[0];Element of MapValue of ReturnValue;value",
".multimap;UnmodifiableMultiValuedMap;true;unmodifiableMultiValuedMap;(MultiValuedMap);;MapKey of Argument[0];MapKey of ReturnValue;value",
".multimap;UnmodifiableMultiValuedMap;true;unmodifiableMultiValuedMap;(MultiValuedMap);;Element of MapValue of Argument[0];Element of MapValue of ReturnValue;value"
]
}
}
/**
* Value-propagating models for the package `org.apache.commons.collections4.multiset`.
*/
private class ApacheMultiSetModel extends SummaryModelCsv {
override predicate row(string row) {
row =
["org.apache.commons.collections4", "org.apache.commons.collections"] +
[
".multiset;HashMultiSet;true;HashMultiSet;;;Element of Argument[0];Element of Argument[-1];value",
".multiset;PredicatedMultiSet;true;predicatedMultiSet;;;Element of Argument[0];Element of ReturnValue;value",
".multiset;SynchronizedMultiSet;true;synchronizedMultiSet;;;Element of Argument[0];Element of ReturnValue;value",
".multiset;UnmodifiableMultiSet;true;unmodifiableMultiSet;;;Element of Argument[0];Element of ReturnValue;value"
]
}
}
/**
* Value-propagating models for the package `org.apache.commons.collections4.properties`.
*/
private class ApachePropertiesModel extends SummaryModelCsv {
override predicate row(string row) {
row =
["org.apache.commons.collections4", "org.apache.commons.collections"] +
[
".properties;AbstractPropertiesFactory;true;load;(ClassLoader,String);;Argument[1];ReturnValue;taint",
".properties;AbstractPropertiesFactory;true;load;(File);;Argument[0];ReturnValue;taint",
".properties;AbstractPropertiesFactory;true;load;(InputStream);;Argument[0];ReturnValue;taint",
".properties;AbstractPropertiesFactory;true;load;(Path);;Argument[0];ReturnValue;taint",
".properties;AbstractPropertiesFactory;true;load;(Reader);;Argument[0];ReturnValue;taint",
".properties;AbstractPropertiesFactory;true;load;(String);;Argument[0];ReturnValue;taint",
".properties;AbstractPropertiesFactory;true;load;(URI);;Argument[0];ReturnValue;taint",
".properties;AbstractPropertiesFactory;true;load;(URL);;Argument[0];ReturnValue;taint"
]
}
}
/**
* Value-propagating models for the package `org.apache.commons.collections4.queue`.
*/
private class ApacheQueueModel extends SummaryModelCsv {
override predicate row(string row) {
row =
["org.apache.commons.collections4", "org.apache.commons.collections"] +
[
// Note that when lambdas are supported we should have more models for TransformedQueue
".queue;CircularFifoQueue;true;CircularFifoQueue;(Collection);;Element of Argument[0];Element of Argument[-1];value",
".queue;CircularFifoQueue;true;get;;;Element of Argument[-1];ReturnValue;value",
".queue;PredicatedQueue;true;predicatedQueue;;;Element of Argument[0];Element of ReturnValue;value",
".queue;SynchronizedQueue;true;synchronizedQueue;;;Element of Argument[0];Element of ReturnValue;value",
".queue;TransformedQueue;true;transformingQueue;;;Element of Argument[0];Element of ReturnValue;value",
".queue;UnmodifiableQueue;true;unmodifiableQueue;;;Element of Argument[0];Element of ReturnValue;value"
]
}
}
/**
* Value-propagating models for the package `org.apache.commons.collections4.set`.
*/
private class ApacheSetModel extends SummaryModelCsv {
override predicate row(string row) {
row =
["org.apache.commons.collections4", "org.apache.commons.collections"] +
[
// Note that when lambdas are supported we should have more models for TransformedNavigableSet
".set;AbstractNavigableSetDecorator;true;AbstractNavigableSetDecorator;;;Element of Argument[0];Element of Argument[-1];value",
".set;AbstractSetDecorator;true;AbstractSetDecorator;;;Element of Argument[0];Element of Argument[-1];value",
".set;AbstractSortedSetDecorator;true;AbstractSortedSetDecorator;;;Element of Argument[0];Element of Argument[-1];value",
".set;CompositeSet$SetMutator;true;add;;;Argument[2];Element of Argument[0];value",
".set;CompositeSet$SetMutator;true;add;;;Argument[2];Element of Element of Argument[1];value",
".set;CompositeSet$SetMutator;true;addAll;;;Element of Argument[2];Element of Argument[0];value",
".set;CompositeSet$SetMutator;true;addAll;;;Element of Argument[2];Element of Element of Argument[1];value",
".set;CompositeSet;true;CompositeSet;(Set);;Element of Argument[0];Element of Argument[-1];value",
".set;CompositeSet;true;CompositeSet;(Set[]);;Element of ArrayElement of Argument[0];Element of Argument[-1];value",
".set;CompositeSet;true;addComposited;(Set);;Element of Argument[0];Element of Argument[-1];value",
".set;CompositeSet;true;addComposited;(Set,Set);;Element of Argument[0];Element of Argument[-1];value",
".set;CompositeSet;true;addComposited;(Set,Set);;Element of Argument[1];Element of Argument[-1];value",
".set;CompositeSet;true;addComposited;(Set[]);;Element of ArrayElement of Argument[0];Element of Argument[-1];value",
".set;CompositeSet;true;toSet;;;Element of Argument[-1];Element of ReturnValue;value",
".set;CompositeSet;true;getSets;;;Element of Argument[-1];Element of Element of ReturnValue;value",
".set;ListOrderedSet;true;listOrderedSet;(Set);;Element of Argument[0];Element of ReturnValue;value",
".set;ListOrderedSet;true;listOrderedSet;(List);;Element of Argument[0];Element of ReturnValue;value",
".set;ListOrderedSet;true;asList;;;Element of Argument[-1];Element of ReturnValue;value",
".set;ListOrderedSet;true;get;;;Element of Argument[-1];ReturnValue;value",
".set;ListOrderedSet;true;add;;;Argument[1];Element of Argument[-1];value",
".set;ListOrderedSet;true;addAll;;;Element of Argument[1];Element of Argument[-1];value",
".set;MapBackedSet;true;mapBackedSet;;;MapKey of Argument[0];Element of ReturnValue;value",
".set;PredicatedNavigableSet;true;predicatedNavigableSet;;;Element of Argument[0];Element of ReturnValue;value",
".set;PredicatedSet;true;predicatedSet;;;Element of Argument[0];Element of ReturnValue;value",
".set;PredicatedSortedSet;true;predicatedSortedSet;;;Element of Argument[0];Element of ReturnValue;value",
".set;TransformedNavigableSet;true;transformingNavigableSet;;;Element of Argument[0];Element of ReturnValue;value",
".set;TransformedSet;true;transformingSet;;;Element of Argument[0];Element of ReturnValue;value",
".set;TransformedSortedSet;true;transformingSortedSet;;;Element of Argument[0];Element of ReturnValue;value",
".set;UnmodifiableNavigableSet;true;unmodifiableNavigableSet;;;Element of Argument[0];Element of ReturnValue;value",
".set;UnmodifiableSet;true;unmodifiableSet;;;Element of Argument[0];Element of ReturnValue;value",
".set;UnmodifiableSortedSet;true;unmodifiableSortedSet;;;Element of Argument[0];Element of ReturnValue;value"
]
}
}
/**
* Value-propagating models for the package `org.apache.commons.collections4.splitmap`.
*/
private class ApacheSplitMapModel extends SummaryModelCsv {
override predicate row(string row) {
row =
["org.apache.commons.collections4", "org.apache.commons.collections"] +
[
// Note that when lambdas are supported we should have more models for TransformedSplitMap
".splitmap;AbstractIterableGetMapDecorator;true;AbstractIterableGetMapDecorator;;;MapKey of Argument[0];MapKey of Argument[-1];value",
".splitmap;AbstractIterableGetMapDecorator;true;AbstractIterableGetMapDecorator;;;MapValue of Argument[0];MapValue of Argument[-1];value",
".splitmap;TransformedSplitMap;true;transformingMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".splitmap;TransformedSplitMap;true;transformingMap;;;MapValue of Argument[0];MapValue of ReturnValue;value"
]
}
}
/**
* Value-propagating models for the package `org.apache.commons.collections4.trie`.
*/
private class ApacheTrieModel extends SummaryModelCsv {
override predicate row(string row) {
row =
["org.apache.commons.collections4", "org.apache.commons.collections"] +
[
// Note that when lambdas are supported we should have more models for TransformedSplitMap
".trie;PatriciaTrie;true;PatriciaTrie;;;MapKey of Argument[0];MapKey of Argument[-1];value",
".trie;PatriciaTrie;true;PatriciaTrie;;;MapValue of Argument[0];MapValue of Argument[-1];value",
".trie;AbstractPatriciaTrie;true;select;;;MapKey of Argument[-1];MapKey of ReturnValue;value",
".trie;AbstractPatriciaTrie;true;select;;;MapValue of Argument[-1];MapValue of ReturnValue;value",
".trie;AbstractPatriciaTrie;true;selectKey;;;MapKey of Argument[-1];ReturnValue;value",
".trie;AbstractPatriciaTrie;true;selectValue;;;MapValue of Argument[-1];ReturnValue;value",
".trie;UnmodifiableTrie;true;unmodifiableTrie;;;MapKey of Argument[0];MapKey of ReturnValue;value",
".trie;UnmodifiableTrie;true;unmodifiableTrie;;;MapValue of Argument[0];MapValue of ReturnValue;value"
]
}
}
/**
* Value-propagating models for the class `org.apache.commons.collections4.MapUtils`.
*/
@@ -217,7 +792,7 @@ private class ApacheMapUtilsModel extends SummaryModelCsv {
";MapUtils;true;orderedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
";MapUtils;true;orderedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
";MapUtils;true;populateMap;(Map,Iterable,Transformer);;Element of Argument[1];MapValue of Argument[0];value",
";MapUtils;true;populateMap;(MultiMap,Iterable,Transformer);;Element of Argument[1];MapValue of Argument[0];value",
";MapUtils;true;populateMap;(MultiMap,Iterable,Transformer);;Element of Argument[1];Element of MapValue of Argument[0];value",
";MapUtils;true;predicatedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
";MapUtils;true;predicatedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
";MapUtils;true;predicatedSortedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
@@ -488,9 +1063,9 @@ private class ApacheMultiMapUtilsModel extends SummaryModelCsv {
";MultiMapUtils;true;getValuesAsList;;;Element of MapValue of Argument[0];Element of ReturnValue;value",
";MultiMapUtils;true;getValuesAsSet;;;Element of MapValue of Argument[0];Element of ReturnValue;value",
";MultiMapUtils;true;transformedMultiValuedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
";MultiMapUtils;true;transformedMultiValuedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value",
";MultiMapUtils;true;transformedMultiValuedMap;;;Element of MapValue of Argument[0];Element of MapValue of ReturnValue;value",
";MultiMapUtils;true;unmodifiableMultiValuedMap;;;MapKey of Argument[0];MapKey of ReturnValue;value",
";MultiMapUtils;true;unmodifiableMultiValuedMap;;;MapValue of Argument[0];MapValue of ReturnValue;value"
";MultiMapUtils;true;unmodifiableMultiValuedMap;;;Element of MapValue of Argument[0];Element of MapValue of ReturnValue;value"
]
}
}

View File

@@ -0,0 +1,48 @@
/**
* Provides classes for working with the Spring Expression Language (SpEL).
*/
import java
/**
* Methods that trigger the evaluation of a SpEL expression.
*/
class ExpressionEvaluationMethod extends Method {
ExpressionEvaluationMethod() {
this.getDeclaringType().getASupertype*() instanceof Expression and
this.hasName(["getValue", "getValueTypeDescriptor", "getValueType", "setValue"])
}
}
/**
* The class `org.springframework.expression.ExpressionParser`.
*/
class ExpressionParser extends RefType {
ExpressionParser() { hasQualifiedName("org.springframework.expression", "ExpressionParser") }
}
/**
* The class `org.springframework.expression.spel.support.SimpleEvaluationContext$Builder`.
*/
class SimpleEvaluationContextBuilder extends RefType {
SimpleEvaluationContextBuilder() {
hasQualifiedName("org.springframework.expression.spel.support",
"SimpleEvaluationContext$Builder")
}
}
/**
* The class `org.springframework.expression.Expression`.
*/
class Expression extends RefType {
Expression() { hasQualifiedName("org.springframework.expression", "Expression") }
}
/**
* The class `org.springframework.expression.spel.support.SimpleEvaluationContext`.
*/
class SimpleEvaluationContext extends RefType {
SimpleEvaluationContext() {
hasQualifiedName("org.springframework.expression.spel.support", "SimpleEvaluationContext")
}
}

View File

@@ -0,0 +1,42 @@
/** Provides classes to reason about SpEL injection attacks. */
import java
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.frameworks.spring.SpringExpression
/** A data flow sink for unvalidated user input that is used to construct SpEL expressions. */
abstract class SpelExpressionEvaluationSink extends DataFlow::ExprNode { }
/**
* A unit class for adding additional taint steps.
*
* Extend this class to add additional taint steps that should apply to the `SpELInjectionConfig`.
*/
class SpelExpressionInjectionAdditionalTaintStep extends Unit {
/**
* Holds if the step from `node1` to `node2` should be considered a taint
* step for the `SpELInjectionConfig` configuration.
*/
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
}
/** A set of additional taint steps to consider when taint tracking SpEL related data flows. */
private class DefaultSpelExpressionInjectionAdditionalTaintStep extends SpelExpressionInjectionAdditionalTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
expressionParsingStep(node1, node2)
}
}
/**
* Holds if `node1` to `node2` is a dataflow step that parses a SpEL expression,
* by calling `parser.parseExpression(tainted)`.
*/
private predicate expressionParsingStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
m.getDeclaringType().getASupertype*() instanceof ExpressionParser and
m.hasName(["parseExpression", "parseRaw"]) and
ma.getAnArgument() = node1.asExpr() and
node2.asExpr() = ma
)
}

View File

@@ -0,0 +1,86 @@
/** Provides taint tracking and dataflow configurations to be used in SpEL injection queries. */
import java
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.frameworks.spring.SpringExpression
private import semmle.code.java.security.SpelInjection
/**
* A taint-tracking configuration for unsafe user input
* that is used to construct and evaluate a SpEL expression.
*/
class SpelInjectionConfig extends TaintTracking::Configuration {
SpelInjectionConfig() { this = "SpelInjectionConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof SpelExpressionEvaluationSink }
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
any(SpelExpressionInjectionAdditionalTaintStep c).step(node1, node2)
}
}
/** Default sink for SpEL injection vulnerabilities. */
private class DefaultSpelExpressionEvaluationSink extends SpelExpressionEvaluationSink {
DefaultSpelExpressionEvaluationSink() {
exists(MethodAccess ma |
ma.getMethod() instanceof ExpressionEvaluationMethod and
ma.getQualifier() = this.asExpr() and
not exists(SafeEvaluationContextFlowConfig config |
config.hasFlowTo(DataFlow::exprNode(ma.getArgument(0)))
)
)
}
}
/**
* A configuration for safe evaluation context that may be used in expression evaluation.
*/
private class SafeEvaluationContextFlowConfig extends DataFlow2::Configuration {
SafeEvaluationContextFlowConfig() { this = "SpelInjection::SafeEvaluationContextFlowConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof SafeContextSource }
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
ma.getMethod() instanceof ExpressionEvaluationMethod and
ma.getArgument(0) = sink.asExpr()
)
}
override int fieldFlowBranchLimit() { result = 0 }
}
/**
* A `ContextSource` that is safe from SpEL injection.
*/
private class SafeContextSource extends DataFlow::ExprNode {
SafeContextSource() {
isSimpleEvaluationContextConstructorCall(getExpr()) or
isSimpleEvaluationContextBuilderCall(getExpr())
}
}
/**
* Holds if `expr` constructs `SimpleEvaluationContext`.
*/
private predicate isSimpleEvaluationContextConstructorCall(Expr expr) {
exists(ConstructorCall cc |
cc.getConstructedType() instanceof SimpleEvaluationContext and
cc = expr
)
}
/**
* Holds if `expr` builds `SimpleEvaluationContext` via `SimpleEvaluationContext.Builder`,
* for instance, `SimpleEvaluationContext.forReadWriteDataBinding().build()`.
*/
private predicate isSimpleEvaluationContextBuilderCall(Expr expr) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
m.getDeclaringType() instanceof SimpleEvaluationContextBuilder and
m.hasName("build") and
ma = expr
)
}

View File

@@ -0,0 +1,248 @@
/** Provides classes to reason about XSLT injection vulnerabilities. */
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.ExternalFlow
/**
* A data flow sink for unvalidated user input that is used in XSLT transformation.
* Extend this class to add your own XSLT Injection sinks.
*/
abstract class XsltInjectionSink extends DataFlow::Node { }
/** A default sink representing methods susceptible to XSLT Injection attacks. */
private class DefaultXsltInjectionSink extends XsltInjectionSink {
DefaultXsltInjectionSink() { sinkNode(this, "xslt") }
}
private class DefaultXsltInjectionSinkModel extends SinkModelCsv {
override predicate row(string row) {
row =
[
"javax.xml.transform;Transformer;false;transform;;;Argument[-1];xslt",
"net.sf.saxon.s9api;XsltTransformer;false;transform;;;Argument[-1];xslt",
"net.sf.saxon.s9api;Xslt30Transformer;false;transform;;;Argument[-1];xslt",
"net.sf.saxon.s9api;Xslt30Transformer;false;applyTemplates;;;Argument[-1];xslt",
"net.sf.saxon.s9api;Xslt30Transformer;false;callFunction;;;Argument[-1];xslt",
"net.sf.saxon.s9api;Xslt30Transformer;false;callTemplate;;;Argument[-1];xslt"
]
}
}
/**
* A unit class for adding additional taint steps.
*
* Extend this class to add additional taint steps that should apply to the `XsltInjectionFlowConfig`.
*/
class XsltInjectionAdditionalTaintStep extends Unit {
/**
* Holds if the step from `node1` to `node2` should be considered a taint
* step for the `XsltInjectionFlowConfig` configuration.
*/
abstract predicate step(DataFlow::Node node1, DataFlow::Node node2);
}
/** A set of additional taint steps to consider when taint tracking XSLT related data flows. */
private class DefaultXsltInjectionAdditionalTaintStep extends XsltInjectionAdditionalTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
xmlStreamReaderStep(node1, node2) or
xmlEventReaderStep(node1, node2) or
staxSourceStep(node1, node2) or
documentBuilderStep(node1, node2) or
domSourceStep(node1, node2) or
newTransformerFromTemplatesStep(node1, node2) or
xsltCompilerStep(node1, node2) or
xsltExecutableStep(node1, node2) or
xsltPackageStep(node1, node2)
}
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `InputStream` or `Reader` and
* `XMLStreamReader`, i.e. `XMLInputFactory.createXMLStreamReader(tainted)`.
*/
private predicate xmlStreamReaderStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(XmlInputFactoryStreamReader xmlStreamReader |
if xmlStreamReader.getMethod().getParameterType(0) instanceof TypeString
then n1.asExpr() = xmlStreamReader.getArgument(1)
else n1.asExpr() = xmlStreamReader.getArgument(0)
|
n2.asExpr() = xmlStreamReader
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `InputStream` or `Reader` and
* `XMLEventReader`, i.e. `XMLInputFactory.createXMLEventReader(tainted)`.
*/
private predicate xmlEventReaderStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(XmlInputFactoryEventReader xmlEventReader |
if xmlEventReader.getMethod().getParameterType(0) instanceof TypeString
then n1.asExpr() = xmlEventReader.getArgument(1)
else n1.asExpr() = xmlEventReader.getArgument(0)
|
n2.asExpr() = xmlEventReader
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `XMLStreamReader` or
* `XMLEventReader` and `StAXSource`, i.e. `new StAXSource(tainted)`.
*/
private predicate staxSourceStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeStAXSource |
n1.asExpr() = cc.getAnArgument() and
n2.asExpr() = cc
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `InputStream` and `Document`,
* i.e. `DocumentBuilder.parse(tainted)`.
*/
private predicate documentBuilderStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(DocumentBuilderParse documentBuilder |
n1.asExpr() = documentBuilder.getArgument(0) and
n2.asExpr() = documentBuilder
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `Document` and `DOMSource`, i.e.
* `new DOMSource(tainted)`.
*/
private predicate domSourceStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeDOMSource |
n1.asExpr() = cc.getAnArgument() and
n2.asExpr() = cc
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `Templates` and `Transformer`,
* i.e. `tainted.newTransformer()`.
*/
private predicate newTransformerFromTemplatesStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
n1.asExpr() = ma.getQualifier() and
n2.asExpr() = ma and
m.getDeclaringType() instanceof TypeTemplates and
m.hasName("newTransformer")
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `Source` or `URI` and
* `XsltExecutable` or `XsltPackage`, i.e. `XsltCompiler.compile(tainted)` or
* `XsltCompiler.loadExecutablePackage(tainted)` or `XsltCompiler.compilePackage(tainted)` or
* `XsltCompiler.loadLibraryPackage(tainted)`.
*/
private predicate xsltCompilerStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
n1.asExpr() = ma.getArgument(0) and
n2.asExpr() = ma and
m.getDeclaringType() instanceof TypeXsltCompiler and
m.hasName(["compile", "loadExecutablePackage", "compilePackage", "loadLibraryPackage"])
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `XsltExecutable` and
* `XsltTransformer` or `Xslt30Transformer`, i.e. `XsltExecutable.load()` or
* `XsltExecutable.load30()`.
*/
private predicate xsltExecutableStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
n1.asExpr() = ma.getQualifier() and
n2.asExpr() = ma and
m.getDeclaringType() instanceof TypeXsltExecutable and
m.hasName(["load", "load30"])
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `XsltPackage` and
* `XsltExecutable`, i.e. `XsltPackage.link()`.
*/
private predicate xsltPackageStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
n1.asExpr() = ma.getQualifier() and
n2.asExpr() = ma and
m.getDeclaringType() instanceof TypeXsltPackage and
m.hasName("link")
)
}
/** The class `javax.xml.transform.stax.StAXSource`. */
private class TypeStAXSource extends Class {
TypeStAXSource() { this.hasQualifiedName("javax.xml.transform.stax", "StAXSource") }
}
/** The class `javax.xml.transform.dom.DOMSource`. */
private class TypeDOMSource extends Class {
TypeDOMSource() { this.hasQualifiedName("javax.xml.transform.dom", "DOMSource") }
}
/** The interface `javax.xml.transform.Templates`. */
private class TypeTemplates extends Interface {
TypeTemplates() { this.hasQualifiedName("javax.xml.transform", "Templates") }
}
/** The class `net.sf.saxon.s9api.XsltCompiler`. */
private class TypeXsltCompiler extends Class {
TypeXsltCompiler() { this.hasQualifiedName("net.sf.saxon.s9api", "XsltCompiler") }
}
/** The class `net.sf.saxon.s9api.XsltExecutable`. */
private class TypeXsltExecutable extends Class {
TypeXsltExecutable() { this.hasQualifiedName("net.sf.saxon.s9api", "XsltExecutable") }
}
/** The class `net.sf.saxon.s9api.XsltPackage`. */
private class TypeXsltPackage extends Class {
TypeXsltPackage() { this.hasQualifiedName("net.sf.saxon.s9api", "XsltPackage") }
}
// XmlParsers classes
/** A call to `DocumentBuilder.parse`. */
private class DocumentBuilderParse extends MethodAccess {
DocumentBuilderParse() {
exists(Method m |
this.getMethod() = m and
m.getDeclaringType() instanceof DocumentBuilder and
m.hasName("parse")
)
}
}
/** The class `javax.xml.parsers.DocumentBuilder`. */
private class DocumentBuilder extends RefType {
DocumentBuilder() { this.hasQualifiedName("javax.xml.parsers", "DocumentBuilder") }
}
/** A call to `XMLInputFactory.createXMLStreamReader`. */
private class XmlInputFactoryStreamReader extends MethodAccess {
XmlInputFactoryStreamReader() {
exists(Method m |
this.getMethod() = m and
m.getDeclaringType() instanceof XmlInputFactory and
m.hasName("createXMLStreamReader")
)
}
}
/** A call to `XMLInputFactory.createEventReader`. */
private class XmlInputFactoryEventReader extends MethodAccess {
XmlInputFactoryEventReader() {
exists(Method m |
this.getMethod() = m and
m.getDeclaringType() instanceof XmlInputFactory and
m.hasName("createXMLEventReader")
)
}
}
/** The class `javax.xml.stream.XMLInputFactory`. */
private class XmlInputFactory extends RefType {
XmlInputFactory() { this.hasQualifiedName("javax.xml.stream", "XMLInputFactory") }
}

View File

@@ -0,0 +1,90 @@
/** Provides taint tracking configurations to be used in XSLT injection queries. */
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.security.XmlParsers
import semmle.code.java.security.XsltInjection
/**
* A taint-tracking configuration for unvalidated user input that is used in XSLT transformation.
*/
class XsltInjectionFlowConfig extends TaintTracking::Configuration {
XsltInjectionFlowConfig() { this = "XsltInjectionFlowConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof XsltInjectionSink }
override predicate isSanitizer(DataFlow::Node node) {
node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType
}
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
any(XsltInjectionAdditionalTaintStep c).step(node1, node2)
}
}
/**
* A set of additional taint steps to consider when taint tracking XSLT related data flows.
* These steps use data flow logic themselves.
*/
private class DataFlowXsltInjectionAdditionalTaintStep extends XsltInjectionAdditionalTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
newTransformerOrTemplatesStep(node1, node2)
}
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `Source` and `Transformer` or
* `Templates`, i.e. `TransformerFactory.newTransformer(tainted)` or
* `TransformerFactory.newTemplates(tainted)`.
*/
private predicate newTransformerOrTemplatesStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
n1.asExpr() = ma.getAnArgument() and
n2.asExpr() = ma and
m.getDeclaringType() instanceof TransformerFactory and
m.hasName(["newTransformer", "newTemplates"]) and
not exists(TransformerFactoryWithSecureProcessingFeatureFlowConfig conf |
conf.hasFlowToExpr(ma.getQualifier())
)
)
}
/**
* A data flow configuration for secure processing feature that is enabled on `TransformerFactory`.
*/
private class TransformerFactoryWithSecureProcessingFeatureFlowConfig extends DataFlow2::Configuration {
TransformerFactoryWithSecureProcessingFeatureFlowConfig() {
this = "TransformerFactoryWithSecureProcessingFeatureFlowConfig"
}
override predicate isSource(DataFlow::Node src) {
exists(Variable v | v = src.asExpr().(VarAccess).getVariable() |
exists(TransformerFactoryFeatureConfig config | config.getQualifier() = v.getAnAccess() |
config.enables(configSecureProcessing())
)
)
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
sink.asExpr() = ma.getQualifier() and
ma.getMethod().getDeclaringType() instanceof TransformerFactory
)
}
override int fieldFlowBranchLimit() { result = 0 }
}
/** A `ParserConfig` specific to `TransformerFactory`. */
private class TransformerFactoryFeatureConfig extends ParserConfig {
TransformerFactoryFeatureConfig() {
exists(Method m |
m = this.getMethod() and
m.getDeclaringType() instanceof TransformerFactory and
m.hasName("setFeature")
)
}
}

View File

@@ -79,6 +79,47 @@ class AndroidReceiverXmlElement extends AndroidComponentXmlElement {
*/
class AndroidProviderXmlElement extends AndroidComponentXmlElement {
AndroidProviderXmlElement() { this.getName() = "provider" }
/**
* Holds if this provider element has explicitly set a value for either its
* `android:permission` attribute or its `android:readPermission` and `android:writePermission`
* attributes.
*/
predicate requiresPermissions() {
this.getAnAttribute().(AndroidPermissionXmlAttribute).isFull()
or
this.getAnAttribute().(AndroidPermissionXmlAttribute).isWrite() and
this.getAnAttribute().(AndroidPermissionXmlAttribute).isRead()
}
}
/**
* The attribute `android:perrmission`, `android:readPermission`, or `android:writePermission`.
*/
class AndroidPermissionXmlAttribute extends XMLAttribute {
AndroidPermissionXmlAttribute() {
this.getNamespace().getPrefix() = "android" and
this.getName() = ["permission", "readPermission", "writePermission"]
}
/** Holds if this is an `android:permission` attribute. */
predicate isFull() { this.getName() = "permission" }
/** Holds if this is an `android:readPermission` attribute. */
predicate isRead() { this.getName() = "readPermission" }
/** Holds if this is an `android:writePermission` attribute. */
predicate isWrite() { this.getName() = "writePermission" }
}
/**
* The `<path-permission`> element of a `<provider>` in an Android manifest file.
*/
class AndroidPathPermissionXmlElement extends XMLElement {
AndroidPathPermissionXmlElement() {
this.getParent() instanceof AndroidProviderXmlElement and
this.hasName("path-permission")
}
}
/**

View File

@@ -4,12 +4,12 @@
<qhelp>
<overview>
<p>XSLT (Extensible Stylesheet Language Transformations) is a language for transforming XML
documents into other XML documents or other formats. Processing of unvalidated XSLT stylesheet can
let attacker to read arbitrary files from the filesystem or to execute arbitrary code.</p>
documents into other XML documents or other formats. Processing unvalidated XSLT stylesheets can
allow attackers to read arbitrary files from the filesystem or to execute arbitrary code.</p>
</overview>
<recommendation>
<p>The general recommendation is to not process untrusted XSLT stylesheets. If user provided
<p>The general recommendation is to not process untrusted XSLT stylesheets. If user-provided
stylesheets must be processed, enable the secure processing mode.</p>
</recommendation>
@@ -17,7 +17,7 @@ stylesheets must be processed, enable the secure processing mode.</p>
<p>In the following examples, the code accepts an XSLT stylesheet from the user and processes it.
</p>
<p>In the first example, the user provided XSLT stylesheet is parsed and processed.</p>
<p>In the first example, the user-provided XSLT stylesheet is parsed and processed.</p>
<p>In the second example, secure processing mode is enabled.</p>

View File

@@ -1,6 +1,6 @@
/**
* @name XSLT transformation with user-controlled stylesheet
* @description Doing an XSLT transformation with user-controlled stylesheet can lead to
* @description Performing an XSLT transformation with user-controlled stylesheets can lead to
* information disclosure or execution of arbitrary code.
* @kind path-problem
* @problem.severity error
@@ -11,8 +11,7 @@
*/
import java
import semmle.code.java.dataflow.FlowSources
import XsltInjectionLib
import semmle.code.java.security.XsltInjectionQuery
import DataFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, XsltInjectionFlowConfig conf

View File

@@ -4,7 +4,7 @@
<overview>
<p>
The Spring Expression Language (SpEL) is a powerful expression language
provided by Spring Framework. The language offers many features
provided by the Spring Framework. The language offers many features
including invocation of methods available in the JVM.
If a SpEL expression is built using attacker-controlled data,
and then evaluated in a powerful context,
@@ -31,7 +31,7 @@ that doesn't allow arbitrary method invocation.
<example>
<p>
The following example uses untrusted data to build a SpEL expression
and then runs it in the default powerfull context.
and then runs it in the default powerful context.
</p>
<sample src="UnsafeSpelExpressionEvaluation.java" />
@@ -53,4 +53,4 @@ However, it's recommended to avoid using untrusted input in SpEL expressions.
<a href="https://owasp.org/www-community/vulnerabilities/Expression_Language_Injection">Expression Language Injection</a>.
</li>
</references>
</qhelp>
</qhelp>

View File

@@ -11,9 +11,10 @@
*/
import java
import SpelInjectionLib
import semmle.code.java.security.SpelInjectionQuery
import semmle.code.java.dataflow.DataFlow
import DataFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, ExpressionInjectionConfig conf
from DataFlow::PathNode source, DataFlow::PathNode sink, SpelInjectionConfig conf
where conf.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "SpEL injection from $@.", source.getNode(), "this user input"

View File

@@ -1,288 +0,0 @@
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.XmlParsers
import DataFlow
/**
* A taint-tracking configuration for unvalidated user input that is used in XSLT transformation.
*/
class XsltInjectionFlowConfig extends TaintTracking::Configuration {
XsltInjectionFlowConfig() { this = "XsltInjectionFlowConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink instanceof XsltInjectionSink }
override predicate isSanitizer(DataFlow::Node node) {
node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType
}
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
xmlStreamReaderStep(node1, node2) or
xmlEventReaderStep(node1, node2) or
staxSourceStep(node1, node2) or
documentBuilderStep(node1, node2) or
domSourceStep(node1, node2) or
newTransformerOrTemplatesStep(node1, node2) or
newTransformerFromTemplatesStep(node1, node2) or
xsltCompilerStep(node1, node2) or
xsltExecutableStep(node1, node2) or
xsltPackageStep(node1, node2)
}
}
/** The class `javax.xml.transform.stax.StAXSource`. */
class TypeStAXSource extends Class {
TypeStAXSource() { this.hasQualifiedName("javax.xml.transform.stax", "StAXSource") }
}
/** The class `javax.xml.transform.dom.DOMSource`. */
class TypeDOMSource extends Class {
TypeDOMSource() { this.hasQualifiedName("javax.xml.transform.dom", "DOMSource") }
}
/** The interface `javax.xml.transform.Templates`. */
class TypeTemplates extends Interface {
TypeTemplates() { this.hasQualifiedName("javax.xml.transform", "Templates") }
}
/** The method `net.sf.saxon.s9api.XsltTransformer.transform`. */
class XsltTransformerTransformMethod extends Method {
XsltTransformerTransformMethod() {
this.getDeclaringType().hasQualifiedName("net.sf.saxon.s9api", "XsltTransformer") and
this.hasName("transform")
}
}
/** The method `net.sf.saxon.s9api.Xslt30Transformer.transform`. */
class Xslt30TransformerTransformMethod extends Method {
Xslt30TransformerTransformMethod() {
this.getDeclaringType().hasQualifiedName("net.sf.saxon.s9api", "Xslt30Transformer") and
this.hasName("transform")
}
}
/** The method `net.sf.saxon.s9api.Xslt30Transformer.applyTemplates`. */
class Xslt30TransformerApplyTemplatesMethod extends Method {
Xslt30TransformerApplyTemplatesMethod() {
this.getDeclaringType().hasQualifiedName("net.sf.saxon.s9api", "Xslt30Transformer") and
this.hasName("applyTemplates")
}
}
/** The method `net.sf.saxon.s9api.Xslt30Transformer.callFunction`. */
class Xslt30TransformerCallFunctionMethod extends Method {
Xslt30TransformerCallFunctionMethod() {
this.getDeclaringType().hasQualifiedName("net.sf.saxon.s9api", "Xslt30Transformer") and
this.hasName("callFunction")
}
}
/** The method `net.sf.saxon.s9api.Xslt30Transformer.callTemplate`. */
class Xslt30TransformerCallTemplateMethod extends Method {
Xslt30TransformerCallTemplateMethod() {
this.getDeclaringType().hasQualifiedName("net.sf.saxon.s9api", "Xslt30Transformer") and
this.hasName("callTemplate")
}
}
/** The class `net.sf.saxon.s9api.XsltCompiler`. */
class TypeXsltCompiler extends Class {
TypeXsltCompiler() { this.hasQualifiedName("net.sf.saxon.s9api", "XsltCompiler") }
}
/** The class `net.sf.saxon.s9api.XsltExecutable`. */
class TypeXsltExecutable extends Class {
TypeXsltExecutable() { this.hasQualifiedName("net.sf.saxon.s9api", "XsltExecutable") }
}
/** The class `net.sf.saxon.s9api.XsltPackage`. */
class TypeXsltPackage extends Class {
TypeXsltPackage() { this.hasQualifiedName("net.sf.saxon.s9api", "XsltPackage") }
}
/** A data flow sink for unvalidated user input that is used in XSLT transformation. */
class XsltInjectionSink extends DataFlow::ExprNode {
XsltInjectionSink() {
exists(MethodAccess ma, Method m | m = ma.getMethod() and ma.getQualifier() = this.getExpr() |
ma instanceof TransformerTransform or
m instanceof XsltTransformerTransformMethod or
m instanceof Xslt30TransformerTransformMethod or
m instanceof Xslt30TransformerApplyTemplatesMethod or
m instanceof Xslt30TransformerCallFunctionMethod or
m instanceof Xslt30TransformerCallTemplateMethod
)
}
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `InputStream` or `Reader` and
* `XMLStreamReader`, i.e. `XMLInputFactory.createXMLStreamReader(tainted)`.
*/
predicate xmlStreamReaderStep(ExprNode n1, ExprNode n2) {
exists(XmlInputFactoryStreamReader xmlStreamReader |
n1.asExpr() = xmlStreamReader.getSink() and
n2.asExpr() = xmlStreamReader
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `InputStream` or `Reader` and
* `XMLEventReader`, i.e. `XMLInputFactory.createXMLEventReader(tainted)`.
*/
predicate xmlEventReaderStep(ExprNode n1, ExprNode n2) {
exists(XmlInputFactoryEventReader xmlEventReader |
n1.asExpr() = xmlEventReader.getSink() and
n2.asExpr() = xmlEventReader
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `XMLStreamReader` or
* `XMLEventReader` and `StAXSource`, i.e. `new StAXSource(tainted)`.
*/
predicate staxSourceStep(ExprNode n1, ExprNode n2) {
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeStAXSource |
n1.asExpr() = cc.getAnArgument() and
n2.asExpr() = cc
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `InputStream` and `Document`,
* i.e. `DocumentBuilder.parse(tainted)`.
*/
predicate documentBuilderStep(ExprNode n1, ExprNode n2) {
exists(DocumentBuilderParse documentBuilder |
n1.asExpr() = documentBuilder.getSink() and
n2.asExpr() = documentBuilder
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `Document` and `DOMSource`, i.e.
* `new DOMSource(tainted)`.
*/
predicate domSourceStep(ExprNode n1, ExprNode n2) {
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeDOMSource |
n1.asExpr() = cc.getAnArgument() and
n2.asExpr() = cc
)
}
/**
* A data flow configuration for secure processing feature that is enabled on `TransformerFactory`.
*/
private class TransformerFactoryWithSecureProcessingFeatureFlowConfig extends DataFlow2::Configuration {
TransformerFactoryWithSecureProcessingFeatureFlowConfig() {
this = "TransformerFactoryWithSecureProcessingFeatureFlowConfig"
}
override predicate isSource(DataFlow::Node src) {
exists(Variable v | v = src.asExpr().(VarAccess).getVariable() |
exists(TransformerFactoryFeatureConfig config | config.getQualifier() = v.getAnAccess() |
config.enables(configSecureProcessing())
)
)
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
sink.asExpr() = ma.getQualifier() and
ma.getMethod().getDeclaringType() instanceof TransformerFactory
)
}
override int fieldFlowBranchLimit() { result = 0 }
}
/** A `ParserConfig` specific to `TransformerFactory`. */
private class TransformerFactoryFeatureConfig extends ParserConfig {
TransformerFactoryFeatureConfig() {
exists(Method m |
m = this.getMethod() and
m.getDeclaringType() instanceof TransformerFactory and
m.hasName("setFeature")
)
}
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `Source` and `Transformer` or
* `Templates`, i.e. `TransformerFactory.newTransformer(tainted)` or
* `TransformerFactory.newTemplates(tainted)`.
*/
predicate newTransformerOrTemplatesStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
n1.asExpr() = ma.getAnArgument() and
n2.asExpr() = ma and
(
m.getDeclaringType() instanceof TransformerFactory and m.hasName("newTransformer")
or
m.getDeclaringType() instanceof TransformerFactory and m.hasName("newTemplates")
) and
not exists(TransformerFactoryWithSecureProcessingFeatureFlowConfig conf |
conf.hasFlowToExpr(ma.getQualifier())
)
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `Templates` and `Transformer`,
* i.e. `tainted.newTransformer()`.
*/
predicate newTransformerFromTemplatesStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
n1.asExpr() = ma.getQualifier() and
n2.asExpr() = ma and
m.getDeclaringType() instanceof TypeTemplates and
m.hasName("newTransformer")
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `Source` or `URI` and
* `XsltExecutable` or `XsltPackage`, i.e. `XsltCompiler.compile(tainted)` or
* `XsltCompiler.loadExecutablePackage(tainted)` or `XsltCompiler.compilePackage(tainted)` or
* `XsltCompiler.loadLibraryPackage(tainted)`.
*/
predicate xsltCompilerStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
n1.asExpr() = ma.getArgument(0) and
n2.asExpr() = ma and
m.getDeclaringType() instanceof TypeXsltCompiler and
(
m.hasName("compile") or
m.hasName("loadExecutablePackage") or
m.hasName("compilePackage") or
m.hasName("loadLibraryPackage")
)
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `XsltExecutable` and
* `XsltTransformer` or `Xslt30Transformer`, i.e. `XsltExecutable.load()` or
* `XsltExecutable.load30()`.
*/
predicate xsltExecutableStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
n1.asExpr() = ma.getQualifier() and
n2.asExpr() = ma and
m.getDeclaringType() instanceof TypeXsltExecutable and
(m.hasName("load") or m.hasName("load30"))
)
}
/**
* Holds if `n1` to `n2` is a dataflow step that converts between `XsltPackage` and
* `XsltExecutable`, i.e. `XsltPackage.link()`.
*/
predicate xsltPackageStep(ExprNode n1, ExprNode n2) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
n1.asExpr() = ma.getQualifier() and
n2.asExpr() = ma and
m.getDeclaringType() instanceof TypeXsltPackage and
m.hasName("link")
)
}

View File

@@ -1,100 +0,0 @@
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.dataflow.TaintTracking2
import SpringFrameworkLib
/**
* A taint-tracking configuration for unsafe user input
* that is used to construct and evaluate a SpEL expression.
*/
class ExpressionInjectionConfig extends TaintTracking::Configuration {
ExpressionInjectionConfig() { this = "ExpressionInjectionConfig" }
override predicate isSource(DataFlow::Node source) {
source instanceof RemoteFlowSource or
source instanceof WebRequestSource
}
override predicate isSink(DataFlow::Node sink) { sink instanceof ExpressionEvaluationSink }
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
expressionParsingStep(node1, node2) or
springPropertiesStep(node1, node2)
}
}
/**
* A sink for SpEL injection vulnerabilities,
* i.e. methods that run evaluation of a SpEL expression in a powerfull context.
*/
class ExpressionEvaluationSink extends DataFlow::ExprNode {
ExpressionEvaluationSink() {
exists(MethodAccess ma, Method m | m = ma.getMethod() |
m instanceof ExpressionEvaluationMethod and
getExpr() = ma.getQualifier() and
not exists(SafeEvaluationContextFlowConfig config |
config.hasFlowTo(DataFlow::exprNode(ma.getArgument(0)))
)
)
}
}
/**
* Holds if `node1` to `node2` is a dataflow step that parses a SpEL expression,
* i.e. `parser.parseExpression(tainted)`.
*/
predicate expressionParsingStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
m.getDeclaringType().getAnAncestor*() instanceof ExpressionParser and
m.hasName("parseExpression") and
ma.getAnArgument() = node1.asExpr() and
node2.asExpr() = ma
)
}
/**
* A configuration for safe evaluation context that may be used in expression evaluation.
*/
class SafeEvaluationContextFlowConfig extends DataFlow2::Configuration {
SafeEvaluationContextFlowConfig() { this = "SpelInjection::SafeEvaluationContextFlowConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof SafeContextSource }
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma, Method m | m = ma.getMethod() |
m instanceof ExpressionEvaluationMethod and
ma.getArgument(0) = sink.asExpr()
)
}
override int fieldFlowBranchLimit() { result = 0 }
}
class SafeContextSource extends DataFlow::ExprNode {
SafeContextSource() {
isSimpleEvaluationContextConstructorCall(getExpr()) or
isSimpleEvaluationContextBuilderCall(getExpr())
}
}
/**
* Holds if `expr` constructs `SimpleEvaluationContext`.
*/
predicate isSimpleEvaluationContextConstructorCall(Expr expr) {
exists(ConstructorCall cc |
cc.getConstructedType() instanceof SimpleEvaluationContext and
cc = expr
)
}
/**
* Holds if `expr` builds `SimpleEvaluationContext` via `SimpleEvaluationContext.Builder`,
* e.g. `SimpleEvaluationContext.forReadWriteDataBinding().build()`.
*/
predicate isSimpleEvaluationContextBuilderCall(Expr expr) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
m.getDeclaringType() instanceof SimpleEvaluationContextBuilder and
m.hasName("build") and
ma = expr
)
}

View File

@@ -1,21 +1,6 @@
import java
import semmle.code.java.dataflow.DataFlow
/**
* Methods that trigger evaluation of an expression.
*/
class ExpressionEvaluationMethod extends Method {
ExpressionEvaluationMethod() {
getDeclaringType() instanceof Expression and
(
hasName("getValue") or
hasName("getValueTypeDescriptor") or
hasName("getValueType") or
hasName("setValue")
)
}
}
/**
* `WebRequest` interface is a source of tainted data.
*/
@@ -37,100 +22,6 @@ class WebRequestSource extends DataFlow::Node {
}
}
/**
* Holds if `node1` to `node2` is a dataflow step that converts `PropertyValues`
* to an array of `PropertyValue`, i.e. `tainted.getPropertyValues()`.
*/
predicate getPropertyValuesStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodAccess ma, Method m | m = ma.getMethod() |
node1.asExpr() = ma.getQualifier() and
node2.asExpr() = ma and
m.getDeclaringType() instanceof PropertyValues and
m.hasName("getPropertyValues")
)
}
/**
* Holds if `node1` to `node2` is a dataflow step that constructs `MutablePropertyValues`,
* i.e. `new MutablePropertyValues(tainted)`.
*/
predicate createMutablePropertyValuesStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(ConstructorCall cc | cc.getConstructedType() instanceof MutablePropertyValues |
node1.asExpr() = cc.getAnArgument() and
node2.asExpr() = cc
)
}
/**
* Holds if `node1` to `node2` is a dataflow step that returns a name of `PropertyValue`,
* i.e. `tainted.getName()`.
*/
predicate getPropertyNameStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodAccess ma, Method m | m = ma.getMethod() |
node1.asExpr() = ma.getQualifier() and
node2.asExpr() = ma and
m.getDeclaringType() instanceof PropertyValue and
m.hasName("getName")
)
}
/**
* Holds if `node1` to `node2` is a dataflow step that converts `MutablePropertyValues`
* to a list of `PropertyValue`, i.e. `tainted.getPropertyValueList()`.
*/
predicate getPropertyValueListStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodAccess ma, Method m | m = ma.getMethod() |
node1.asExpr() = ma.getQualifier() and
node2.asExpr() = ma and
m.getDeclaringType() instanceof MutablePropertyValues and
m.hasName("getPropertyValueList")
)
}
/**
* Holds if `node1` to `node2` is one of the dataflow steps that propagate
* tainted data via Spring properties.
*/
predicate springPropertiesStep(DataFlow::Node node1, DataFlow::Node node2) {
createMutablePropertyValuesStep(node1, node2) or
getPropertyNameStep(node1, node2) or
getPropertyValuesStep(node1, node2) or
getPropertyValueListStep(node1, node2)
}
class PropertyValue extends RefType {
PropertyValue() { hasQualifiedName("org.springframework.beans", "PropertyValue") }
}
class PropertyValues extends RefType {
PropertyValues() { hasQualifiedName("org.springframework.beans", "PropertyValues") }
}
class MutablePropertyValues extends RefType {
MutablePropertyValues() { hasQualifiedName("org.springframework.beans", "MutablePropertyValues") }
}
class SimpleEvaluationContext extends RefType {
SimpleEvaluationContext() {
hasQualifiedName("org.springframework.expression.spel.support", "SimpleEvaluationContext")
}
}
class SimpleEvaluationContextBuilder extends RefType {
SimpleEvaluationContextBuilder() {
hasQualifiedName("org.springframework.expression.spel.support",
"SimpleEvaluationContext$Builder")
}
}
class WebRequest extends RefType {
WebRequest() { hasQualifiedName("org.springframework.web.context.request", "WebRequest") }
}
class Expression extends RefType {
Expression() { hasQualifiedName("org.springframework.expression", "Expression") }
}
class ExpressionParser extends RefType {
ExpressionParser() { hasQualifiedName("org.springframework.expression", "ExpressionParser") }
}

View File

@@ -1,122 +0,0 @@
edges
| XsltInjection.java:30:27:30:67 | new StreamSource(...) : StreamSource | XsltInjection.java:31:5:31:59 | newTransformer(...) |
| XsltInjection.java:30:44:30:66 | getInputStream(...) : InputStream | XsltInjection.java:30:27:30:67 | new StreamSource(...) : StreamSource |
| XsltInjection.java:35:27:35:90 | new StreamSource(...) : StreamSource | XsltInjection.java:36:5:36:74 | newTransformer(...) |
| XsltInjection.java:35:44:35:89 | new InputStreamReader(...) : InputStreamReader | XsltInjection.java:35:27:35:90 | new StreamSource(...) : StreamSource |
| XsltInjection.java:35:66:35:88 | getInputStream(...) : InputStream | XsltInjection.java:35:44:35:89 | new InputStreamReader(...) : InputStreamReader |
| XsltInjection.java:40:45:40:70 | param : String | XsltInjection.java:42:61:42:64 | xslt : String |
| XsltInjection.java:42:27:42:66 | new StreamSource(...) : StreamSource | XsltInjection.java:43:5:43:59 | newTransformer(...) |
| XsltInjection.java:42:44:42:65 | new StringReader(...) : StringReader | XsltInjection.java:42:27:42:66 | new StreamSource(...) : StreamSource |
| XsltInjection.java:42:61:42:64 | xslt : String | XsltInjection.java:42:44:42:65 | new StringReader(...) : StringReader |
| XsltInjection.java:47:24:47:78 | new SAXSource(...) : SAXSource | XsltInjection.java:48:5:48:74 | newTransformer(...) |
| XsltInjection.java:47:38:47:77 | new InputSource(...) : InputSource | XsltInjection.java:47:24:47:78 | new SAXSource(...) : SAXSource |
| XsltInjection.java:47:54:47:76 | getInputStream(...) : InputStream | XsltInjection.java:47:38:47:77 | new InputSource(...) : InputSource |
| XsltInjection.java:52:24:52:107 | new SAXSource(...) : SAXSource | XsltInjection.java:53:5:53:59 | newTransformer(...) |
| XsltInjection.java:52:44:52:106 | new InputSource(...) : InputSource | XsltInjection.java:52:24:52:107 | new SAXSource(...) : SAXSource |
| XsltInjection.java:52:60:52:105 | new InputStreamReader(...) : InputStreamReader | XsltInjection.java:52:44:52:106 | new InputSource(...) : InputSource |
| XsltInjection.java:52:82:52:104 | getInputStream(...) : InputStream | XsltInjection.java:52:60:52:105 | new InputStreamReader(...) : InputStreamReader |
| XsltInjection.java:57:91:57:113 | getInputStream(...) : InputStream | XsltInjection.java:58:5:58:59 | newTransformer(...) |
| XsltInjection.java:62:98:62:143 | new InputStreamReader(...) : InputStreamReader | XsltInjection.java:63:5:63:74 | newTransformer(...) |
| XsltInjection.java:62:120:62:142 | getInputStream(...) : InputStream | XsltInjection.java:62:98:62:143 | new InputStreamReader(...) : InputStreamReader |
| XsltInjection.java:67:102:67:124 | getInputStream(...) : InputStream | XsltInjection.java:68:5:68:59 | newTransformer(...) |
| XsltInjection.java:72:27:72:67 | new StreamSource(...) : StreamSource | XsltInjection.java:76:5:76:34 | newTransformer(...) |
| XsltInjection.java:72:44:72:66 | getInputStream(...) : InputStream | XsltInjection.java:72:27:72:67 | new StreamSource(...) : StreamSource |
| XsltInjection.java:80:27:80:67 | new StreamSource(...) : StreamSource | XsltInjection.java:83:5:83:34 | newTransformer(...) |
| XsltInjection.java:80:44:80:66 | getInputStream(...) : InputStream | XsltInjection.java:80:27:80:67 | new StreamSource(...) : StreamSource |
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:90:5:90:35 | load(...) |
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:91:5:91:37 | load30(...) |
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:92:5:92:37 | load30(...) |
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:93:5:93:37 | load30(...) |
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:94:5:94:37 | load30(...) |
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:95:5:95:37 | load30(...) |
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:96:5:96:37 | load30(...) |
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:97:5:97:37 | load30(...) |
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:98:5:98:37 | load30(...) |
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | XsltInjection.java:99:5:99:37 | load30(...) |
| XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource |
| XsltInjection.java:103:36:103:61 | param : String | XsltInjection.java:104:23:104:27 | param : String |
| XsltInjection.java:104:15:104:28 | new URI(...) : URI | XsltInjection.java:108:5:108:46 | load(...) |
| XsltInjection.java:104:15:104:28 | new URI(...) : URI | XsltInjection.java:110:5:110:50 | load(...) |
| XsltInjection.java:104:23:104:27 | param : String | XsltInjection.java:104:15:104:28 | new URI(...) : URI |
| XsltInjection.java:105:27:105:67 | new StreamSource(...) : StreamSource | XsltInjection.java:109:5:109:49 | load(...) |
| XsltInjection.java:105:44:105:66 | getInputStream(...) : InputStream | XsltInjection.java:105:27:105:67 | new StreamSource(...) : StreamSource |
nodes
| XsltInjection.java:30:27:30:67 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
| XsltInjection.java:30:44:30:66 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| XsltInjection.java:31:5:31:59 | newTransformer(...) | semmle.label | newTransformer(...) |
| XsltInjection.java:35:27:35:90 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
| XsltInjection.java:35:44:35:89 | new InputStreamReader(...) : InputStreamReader | semmle.label | new InputStreamReader(...) : InputStreamReader |
| XsltInjection.java:35:66:35:88 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| XsltInjection.java:36:5:36:74 | newTransformer(...) | semmle.label | newTransformer(...) |
| XsltInjection.java:40:45:40:70 | param : String | semmle.label | param : String |
| XsltInjection.java:42:27:42:66 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
| XsltInjection.java:42:44:42:65 | new StringReader(...) : StringReader | semmle.label | new StringReader(...) : StringReader |
| XsltInjection.java:42:61:42:64 | xslt : String | semmle.label | xslt : String |
| XsltInjection.java:43:5:43:59 | newTransformer(...) | semmle.label | newTransformer(...) |
| XsltInjection.java:47:24:47:78 | new SAXSource(...) : SAXSource | semmle.label | new SAXSource(...) : SAXSource |
| XsltInjection.java:47:38:47:77 | new InputSource(...) : InputSource | semmle.label | new InputSource(...) : InputSource |
| XsltInjection.java:47:54:47:76 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| XsltInjection.java:48:5:48:74 | newTransformer(...) | semmle.label | newTransformer(...) |
| XsltInjection.java:52:24:52:107 | new SAXSource(...) : SAXSource | semmle.label | new SAXSource(...) : SAXSource |
| XsltInjection.java:52:44:52:106 | new InputSource(...) : InputSource | semmle.label | new InputSource(...) : InputSource |
| XsltInjection.java:52:60:52:105 | new InputStreamReader(...) : InputStreamReader | semmle.label | new InputStreamReader(...) : InputStreamReader |
| XsltInjection.java:52:82:52:104 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| XsltInjection.java:53:5:53:59 | newTransformer(...) | semmle.label | newTransformer(...) |
| XsltInjection.java:57:91:57:113 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| XsltInjection.java:58:5:58:59 | newTransformer(...) | semmle.label | newTransformer(...) |
| XsltInjection.java:62:98:62:143 | new InputStreamReader(...) : InputStreamReader | semmle.label | new InputStreamReader(...) : InputStreamReader |
| XsltInjection.java:62:120:62:142 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| XsltInjection.java:63:5:63:74 | newTransformer(...) | semmle.label | newTransformer(...) |
| XsltInjection.java:67:102:67:124 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| XsltInjection.java:68:5:68:59 | newTransformer(...) | semmle.label | newTransformer(...) |
| XsltInjection.java:72:27:72:67 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
| XsltInjection.java:72:44:72:66 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| XsltInjection.java:76:5:76:34 | newTransformer(...) | semmle.label | newTransformer(...) |
| XsltInjection.java:80:27:80:67 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
| XsltInjection.java:80:44:80:66 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| XsltInjection.java:83:5:83:34 | newTransformer(...) | semmle.label | newTransformer(...) |
| XsltInjection.java:87:27:87:67 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
| XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| XsltInjection.java:90:5:90:35 | load(...) | semmle.label | load(...) |
| XsltInjection.java:91:5:91:37 | load30(...) | semmle.label | load30(...) |
| XsltInjection.java:92:5:92:37 | load30(...) | semmle.label | load30(...) |
| XsltInjection.java:93:5:93:37 | load30(...) | semmle.label | load30(...) |
| XsltInjection.java:94:5:94:37 | load30(...) | semmle.label | load30(...) |
| XsltInjection.java:95:5:95:37 | load30(...) | semmle.label | load30(...) |
| XsltInjection.java:96:5:96:37 | load30(...) | semmle.label | load30(...) |
| XsltInjection.java:97:5:97:37 | load30(...) | semmle.label | load30(...) |
| XsltInjection.java:98:5:98:37 | load30(...) | semmle.label | load30(...) |
| XsltInjection.java:99:5:99:37 | load30(...) | semmle.label | load30(...) |
| XsltInjection.java:103:36:103:61 | param : String | semmle.label | param : String |
| XsltInjection.java:104:15:104:28 | new URI(...) : URI | semmle.label | new URI(...) : URI |
| XsltInjection.java:104:23:104:27 | param : String | semmle.label | param : String |
| XsltInjection.java:105:27:105:67 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
| XsltInjection.java:105:44:105:66 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| XsltInjection.java:108:5:108:46 | load(...) | semmle.label | load(...) |
| XsltInjection.java:109:5:109:49 | load(...) | semmle.label | load(...) |
| XsltInjection.java:110:5:110:50 | load(...) | semmle.label | load(...) |
subpaths
#select
| XsltInjection.java:31:5:31:59 | newTransformer(...) | XsltInjection.java:30:44:30:66 | getInputStream(...) : InputStream | XsltInjection.java:31:5:31:59 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:30:44:30:66 | getInputStream(...) | this user input |
| XsltInjection.java:36:5:36:74 | newTransformer(...) | XsltInjection.java:35:66:35:88 | getInputStream(...) : InputStream | XsltInjection.java:36:5:36:74 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:35:66:35:88 | getInputStream(...) | this user input |
| XsltInjection.java:43:5:43:59 | newTransformer(...) | XsltInjection.java:40:45:40:70 | param : String | XsltInjection.java:43:5:43:59 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:40:45:40:70 | param | this user input |
| XsltInjection.java:48:5:48:74 | newTransformer(...) | XsltInjection.java:47:54:47:76 | getInputStream(...) : InputStream | XsltInjection.java:48:5:48:74 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:47:54:47:76 | getInputStream(...) | this user input |
| XsltInjection.java:53:5:53:59 | newTransformer(...) | XsltInjection.java:52:82:52:104 | getInputStream(...) : InputStream | XsltInjection.java:53:5:53:59 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:52:82:52:104 | getInputStream(...) | this user input |
| XsltInjection.java:58:5:58:59 | newTransformer(...) | XsltInjection.java:57:91:57:113 | getInputStream(...) : InputStream | XsltInjection.java:58:5:58:59 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:57:91:57:113 | getInputStream(...) | this user input |
| XsltInjection.java:63:5:63:74 | newTransformer(...) | XsltInjection.java:62:120:62:142 | getInputStream(...) : InputStream | XsltInjection.java:63:5:63:74 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:62:120:62:142 | getInputStream(...) | this user input |
| XsltInjection.java:68:5:68:59 | newTransformer(...) | XsltInjection.java:67:102:67:124 | getInputStream(...) : InputStream | XsltInjection.java:68:5:68:59 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:67:102:67:124 | getInputStream(...) | this user input |
| XsltInjection.java:76:5:76:34 | newTransformer(...) | XsltInjection.java:72:44:72:66 | getInputStream(...) : InputStream | XsltInjection.java:76:5:76:34 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:72:44:72:66 | getInputStream(...) | this user input |
| XsltInjection.java:83:5:83:34 | newTransformer(...) | XsltInjection.java:80:44:80:66 | getInputStream(...) : InputStream | XsltInjection.java:83:5:83:34 | newTransformer(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:80:44:80:66 | getInputStream(...) | this user input |
| XsltInjection.java:90:5:90:35 | load(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:90:5:90:35 | load(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
| XsltInjection.java:91:5:91:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:91:5:91:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
| XsltInjection.java:92:5:92:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:92:5:92:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
| XsltInjection.java:93:5:93:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:93:5:93:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
| XsltInjection.java:94:5:94:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:94:5:94:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
| XsltInjection.java:95:5:95:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:95:5:95:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
| XsltInjection.java:96:5:96:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:96:5:96:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
| XsltInjection.java:97:5:97:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:97:5:97:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
| XsltInjection.java:98:5:98:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:98:5:98:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
| XsltInjection.java:99:5:99:37 | load30(...) | XsltInjection.java:87:44:87:66 | getInputStream(...) : InputStream | XsltInjection.java:99:5:99:37 | load30(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:87:44:87:66 | getInputStream(...) | this user input |
| XsltInjection.java:108:5:108:46 | load(...) | XsltInjection.java:103:36:103:61 | param : String | XsltInjection.java:108:5:108:46 | load(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:103:36:103:61 | param | this user input |
| XsltInjection.java:109:5:109:49 | load(...) | XsltInjection.java:105:44:105:66 | getInputStream(...) : InputStream | XsltInjection.java:109:5:109:49 | load(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:105:44:105:66 | getInputStream(...) | this user input |
| XsltInjection.java:110:5:110:50 | load(...) | XsltInjection.java:103:36:103:61 | param : String | XsltInjection.java:110:5:110:50 | load(...) | XSLT transformation might include stylesheet from $@. | XsltInjection.java:103:36:103:61 | param | this user input |

View File

@@ -1 +0,0 @@
experimental/Security/CWE/CWE-074/XsltInjection.ql

View File

@@ -1 +0,0 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/Saxon-HE-9.9.1-7

View File

@@ -1,76 +0,0 @@
edges
| SpelInjection.java:15:22:15:44 | getInputStream(...) : InputStream | SpelInjection.java:18:13:18:14 | in : InputStream |
| SpelInjection.java:18:13:18:14 | in : InputStream | SpelInjection.java:18:21:18:25 | bytes [post update] : byte[] |
| SpelInjection.java:18:21:18:25 | bytes [post update] : byte[] | SpelInjection.java:19:31:19:35 | bytes : byte[] |
| SpelInjection.java:19:20:19:42 | new String(...) : String | SpelInjection.java:23:5:23:14 | expression |
| SpelInjection.java:19:31:19:35 | bytes : byte[] | SpelInjection.java:19:20:19:42 | new String(...) : String |
| SpelInjection.java:27:22:27:44 | getInputStream(...) : InputStream | SpelInjection.java:30:13:30:14 | in : InputStream |
| SpelInjection.java:30:13:30:14 | in : InputStream | SpelInjection.java:30:21:30:25 | bytes [post update] : byte[] |
| SpelInjection.java:30:21:30:25 | bytes [post update] : byte[] | SpelInjection.java:31:31:31:35 | bytes : byte[] |
| SpelInjection.java:31:20:31:42 | new String(...) : String | SpelInjection.java:34:5:34:14 | expression |
| SpelInjection.java:31:31:31:35 | bytes : byte[] | SpelInjection.java:31:20:31:42 | new String(...) : String |
| SpelInjection.java:38:22:38:44 | getInputStream(...) : InputStream | SpelInjection.java:41:13:41:14 | in : InputStream |
| SpelInjection.java:41:13:41:14 | in : InputStream | SpelInjection.java:41:21:41:25 | bytes [post update] : byte[] |
| SpelInjection.java:41:21:41:25 | bytes [post update] : byte[] | SpelInjection.java:42:31:42:35 | bytes : byte[] |
| SpelInjection.java:42:20:42:42 | new String(...) : String | SpelInjection.java:48:5:48:14 | expression |
| SpelInjection.java:42:31:42:35 | bytes : byte[] | SpelInjection.java:42:20:42:42 | new String(...) : String |
| SpelInjection.java:52:22:52:44 | getInputStream(...) : InputStream | SpelInjection.java:55:13:55:14 | in : InputStream |
| SpelInjection.java:55:13:55:14 | in : InputStream | SpelInjection.java:55:21:55:25 | bytes [post update] : byte[] |
| SpelInjection.java:55:21:55:25 | bytes [post update] : byte[] | SpelInjection.java:56:31:56:35 | bytes : byte[] |
| SpelInjection.java:56:20:56:42 | new String(...) : String | SpelInjection.java:59:5:59:14 | expression |
| SpelInjection.java:56:31:56:35 | bytes : byte[] | SpelInjection.java:56:20:56:42 | new String(...) : String |
| SpelInjection.java:63:22:63:44 | getInputStream(...) : InputStream | SpelInjection.java:66:13:66:14 | in : InputStream |
| SpelInjection.java:66:13:66:14 | in : InputStream | SpelInjection.java:66:21:66:25 | bytes [post update] : byte[] |
| SpelInjection.java:66:21:66:25 | bytes [post update] : byte[] | SpelInjection.java:67:31:67:35 | bytes : byte[] |
| SpelInjection.java:67:20:67:42 | new String(...) : String | SpelInjection.java:70:5:70:14 | expression |
| SpelInjection.java:67:31:67:35 | bytes : byte[] | SpelInjection.java:67:20:67:42 | new String(...) : String |
| SpelInjection.java:74:22:74:44 | getInputStream(...) : InputStream | SpelInjection.java:77:13:77:14 | in : InputStream |
| SpelInjection.java:77:13:77:14 | in : InputStream | SpelInjection.java:77:21:77:25 | bytes [post update] : byte[] |
| SpelInjection.java:77:21:77:25 | bytes [post update] : byte[] | SpelInjection.java:78:31:78:35 | bytes : byte[] |
| SpelInjection.java:78:20:78:42 | new String(...) : String | SpelInjection.java:83:5:83:14 | expression |
| SpelInjection.java:78:31:78:35 | bytes : byte[] | SpelInjection.java:78:20:78:42 | new String(...) : String |
nodes
| SpelInjection.java:15:22:15:44 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| SpelInjection.java:18:13:18:14 | in : InputStream | semmle.label | in : InputStream |
| SpelInjection.java:18:21:18:25 | bytes [post update] : byte[] | semmle.label | bytes [post update] : byte[] |
| SpelInjection.java:19:20:19:42 | new String(...) : String | semmle.label | new String(...) : String |
| SpelInjection.java:19:31:19:35 | bytes : byte[] | semmle.label | bytes : byte[] |
| SpelInjection.java:23:5:23:14 | expression | semmle.label | expression |
| SpelInjection.java:27:22:27:44 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| SpelInjection.java:30:13:30:14 | in : InputStream | semmle.label | in : InputStream |
| SpelInjection.java:30:21:30:25 | bytes [post update] : byte[] | semmle.label | bytes [post update] : byte[] |
| SpelInjection.java:31:20:31:42 | new String(...) : String | semmle.label | new String(...) : String |
| SpelInjection.java:31:31:31:35 | bytes : byte[] | semmle.label | bytes : byte[] |
| SpelInjection.java:34:5:34:14 | expression | semmle.label | expression |
| SpelInjection.java:38:22:38:44 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| SpelInjection.java:41:13:41:14 | in : InputStream | semmle.label | in : InputStream |
| SpelInjection.java:41:21:41:25 | bytes [post update] : byte[] | semmle.label | bytes [post update] : byte[] |
| SpelInjection.java:42:20:42:42 | new String(...) : String | semmle.label | new String(...) : String |
| SpelInjection.java:42:31:42:35 | bytes : byte[] | semmle.label | bytes : byte[] |
| SpelInjection.java:48:5:48:14 | expression | semmle.label | expression |
| SpelInjection.java:52:22:52:44 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| SpelInjection.java:55:13:55:14 | in : InputStream | semmle.label | in : InputStream |
| SpelInjection.java:55:21:55:25 | bytes [post update] : byte[] | semmle.label | bytes [post update] : byte[] |
| SpelInjection.java:56:20:56:42 | new String(...) : String | semmle.label | new String(...) : String |
| SpelInjection.java:56:31:56:35 | bytes : byte[] | semmle.label | bytes : byte[] |
| SpelInjection.java:59:5:59:14 | expression | semmle.label | expression |
| SpelInjection.java:63:22:63:44 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| SpelInjection.java:66:13:66:14 | in : InputStream | semmle.label | in : InputStream |
| SpelInjection.java:66:21:66:25 | bytes [post update] : byte[] | semmle.label | bytes [post update] : byte[] |
| SpelInjection.java:67:20:67:42 | new String(...) : String | semmle.label | new String(...) : String |
| SpelInjection.java:67:31:67:35 | bytes : byte[] | semmle.label | bytes : byte[] |
| SpelInjection.java:70:5:70:14 | expression | semmle.label | expression |
| SpelInjection.java:74:22:74:44 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| SpelInjection.java:77:13:77:14 | in : InputStream | semmle.label | in : InputStream |
| SpelInjection.java:77:21:77:25 | bytes [post update] : byte[] | semmle.label | bytes [post update] : byte[] |
| SpelInjection.java:78:20:78:42 | new String(...) : String | semmle.label | new String(...) : String |
| SpelInjection.java:78:31:78:35 | bytes : byte[] | semmle.label | bytes : byte[] |
| SpelInjection.java:83:5:83:14 | expression | semmle.label | expression |
subpaths
#select
| SpelInjection.java:23:5:23:14 | expression | SpelInjection.java:15:22:15:44 | getInputStream(...) : InputStream | SpelInjection.java:23:5:23:14 | expression | SpEL injection from $@. | SpelInjection.java:15:22:15:44 | getInputStream(...) | this user input |
| SpelInjection.java:34:5:34:14 | expression | SpelInjection.java:27:22:27:44 | getInputStream(...) : InputStream | SpelInjection.java:34:5:34:14 | expression | SpEL injection from $@. | SpelInjection.java:27:22:27:44 | getInputStream(...) | this user input |
| SpelInjection.java:48:5:48:14 | expression | SpelInjection.java:38:22:38:44 | getInputStream(...) : InputStream | SpelInjection.java:48:5:48:14 | expression | SpEL injection from $@. | SpelInjection.java:38:22:38:44 | getInputStream(...) | this user input |
| SpelInjection.java:59:5:59:14 | expression | SpelInjection.java:52:22:52:44 | getInputStream(...) : InputStream | SpelInjection.java:59:5:59:14 | expression | SpEL injection from $@. | SpelInjection.java:52:22:52:44 | getInputStream(...) | this user input |
| SpelInjection.java:70:5:70:14 | expression | SpelInjection.java:63:22:63:44 | getInputStream(...) : InputStream | SpelInjection.java:70:5:70:14 | expression | SpEL injection from $@. | SpelInjection.java:63:22:63:44 | getInputStream(...) | this user input |
| SpelInjection.java:83:5:83:14 | expression | SpelInjection.java:74:22:74:44 | getInputStream(...) : InputStream | SpelInjection.java:83:5:83:14 | expression | SpEL injection from $@. | SpelInjection.java:74:22:74:44 | getInputStream(...) | this user input |

View File

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

View File

@@ -48,6 +48,8 @@ public class A {
return null;
}
public interface Producer1Consumer3<E> extends Producer1<E[]>, Consumer3<E[]> { }
static Object source(int i) { return null; }
static void sink(Object o) { }
@@ -71,7 +73,7 @@ public class A {
applyConsumer1(source(4), new Consumer1() {
@Override public void eat(Object o) {
sink(o); // $ MISSING: flow=4
sink(o); // $ flow=4
}
});
@@ -96,5 +98,16 @@ public class A {
sink(applyConverter1((Integer)source(9), i -> i)); // $ flow=9
sink(applyConverter1((Integer)source(10), i -> new int[]{i})[0]); // $ flow=10
Producer1Consumer3<Integer> pc = new Producer1Consumer3<Integer>() {
@Override public Integer[] make() {
return new Integer[] { (Integer)source(11) };
}
@Override public void eat(Integer[] xs) {
sink(xs[0]); // $ flow=12
}
};
applyConsumer3(new Integer[] { (Integer)source(12) }, pc);
sink(applyProducer1(pc)[0]); // $ flow=11
}
}

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="com.example.app">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name=".Test"
android:authority="com.example.myapp.Test"
android:exported="true" />
<provider
android:name=".Safe"
android:authority="com.example.myapp.Safe"
android:exported="false" />
</application>
</manifest>

View File

@@ -0,0 +1,174 @@
package com.example.app;
import java.io.FileNotFoundException;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
// This Content Provider isn't exported, so there shouldn't be any flow
public class Safe extends ContentProvider {
void sink(Object o) {}
@Override
public Bundle call(String authority, String method, String arg, Bundle extras) {
sink(authority);
sink(method);
sink(arg);
sink(extras.get("some_key"));
return null;
}
public Bundle call(String method, String arg, Bundle extras) {
sink(method);
sink(arg);
sink(extras.get("some_key"));
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
sink(uri);
sink(selection);
sink(selectionArgs);
return 0;
}
@Override
public int delete(Uri uri, Bundle extras) {
sink(uri);
sink(extras.get("some_key"));
return 0;
}
@Override
public String getType(Uri uri) {
sink(uri);
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values, Bundle extras) {
sink(uri);
sink(values);
sink(extras.get("some_key"));
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
sink(uri);
sink(values);
return null;
}
@Override
public AssetFileDescriptor openAssetFile(Uri uri, String mode, CancellationSignal signal) {
sink(uri);
sink(mode);
sink(signal);
return null;
}
@Override
public AssetFileDescriptor openAssetFile(Uri uri, String mode) {
sink(uri);
sink(mode);
return null;
}
@Override
public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts,
CancellationSignal signal) throws RemoteException, FileNotFoundException {
sink(uri);
sink(mimeTypeFilter);
sink(opts.get("some_key"));
sink(signal);
return null;
}
@Override
public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
throws FileNotFoundException {
sink(uri);
sink(mimeTypeFilter);
sink(opts.get("some_key"));
return null;
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode, CancellationSignal signal) {
sink(uri);
sink(mode);
sink(signal);
return null;
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) {
sink(uri);
sink(mode);
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, Bundle queryArgs,
CancellationSignal cancellationSignal) {
sink(uri);
sink(projection);
sink(queryArgs.get("some_key"));
sink(cancellationSignal);
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
sink(uri);
sink(projection);
sink(selection);
sink(selectionArgs);
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder, CancellationSignal cancellationSignal) {
sink(uri);
sink(projection);
sink(selection);
sink(selectionArgs);
sink(sortOrder);
sink(cancellationSignal);
return null;
}
@Override
public int update(Uri uri, ContentValues values, Bundle extras) {
sink(uri);
sink(values);
sink(extras.get("some_key"));
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
sink(uri);
sink(values);
sink(selection);
sink(selectionArgs);
return 0;
}
@Override
public boolean onCreate() {
return false;
}
}

View File

@@ -0,0 +1,190 @@
package com.example.app;
import java.io.FileNotFoundException;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
public class Test extends ContentProvider {
void sink(Object o) {}
// "android.content;ContentProvider;true;call;(String,String,String,Bundle);;Parameter[0..3];contentprovider",
@Override
public Bundle call(String authority, String method, String arg, Bundle extras) {
sink(authority); // $ hasTaintFlow
sink(method); // $ hasTaintFlow
sink(arg); // $ hasTaintFlow
sink(extras.get("some_key")); // $ hasTaintFlow
return null;
}
// "android.content;ContentProvider;true;call;(String,String,Bundle);;Parameter[0..2];contentprovider",
public Bundle call(String method, String arg, Bundle extras) {
sink(method); // $ hasTaintFlow
sink(arg); // $ hasTaintFlow
sink(extras.get("some_key")); // $ hasTaintFlow
return null;
}
// "android.content;ContentProvider;true;delete;(Uri,String,String[]);;Parameter[0..2];contentprovider",
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
sink(uri); // $ hasTaintFlow
sink(selection); // $ hasTaintFlow
sink(selectionArgs); // $ hasTaintFlow
return 0;
}
// "android.content;ContentProvider;true;delete;(Uri,Bundle);;Parameter[0..1];contentprovider",
@Override
public int delete(Uri uri, Bundle extras) {
sink(uri); // $ hasTaintFlow
sink(extras.get("some_key")); // $ hasTaintFlow
return 0;
}
// "android.content;ContentProvider;true;getType;(Uri);;Parameter[0];contentprovider",
@Override
public String getType(Uri uri) {
sink(uri); // $ hasTaintFlow
return null;
}
// "android.content;ContentProvider;true;insert;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider",
@Override
public Uri insert(Uri uri, ContentValues values, Bundle extras) {
sink(uri); // $ hasTaintFlow
sink(values); // $ hasTaintFlow
sink(extras.get("some_key")); // $ hasTaintFlow
return null;
}
// "android.content;ContentProvider;true;insert;(Uri,ContentValues);;Parameter[0..1];contentprovider",
@Override
public Uri insert(Uri uri, ContentValues values) {
sink(uri); // $ hasTaintFlow
sink(values); // $ hasTaintFlow
return null;
}
// "android.content;ContentProvider;true;openAssetFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
@Override
public AssetFileDescriptor openAssetFile(Uri uri, String mode, CancellationSignal signal) {
sink(uri); // $ hasTaintFlow
sink(mode); // Safe
sink(signal); // Safe
return null;
}
// "android.content;ContentProvider;true;openAssetFile;(Uri,String);;Parameter[0];contentprovider",
@Override
public AssetFileDescriptor openAssetFile(Uri uri, String mode) {
sink(uri); // $ hasTaintFlow
sink(mode); // Safe
return null;
}
// "android.content;ContentProvider;true;openTypedAssetFile;(Uri,String,Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
@Override
public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts,
CancellationSignal signal) throws RemoteException, FileNotFoundException {
sink(uri); // $ hasTaintFlow
sink(mimeTypeFilter); // $ hasTaintFlow
sink(opts.get("some_key")); // $ hasTaintFlow
sink(signal); // Safe
return null;
}
// "android.content;ContentProvider;true;openTypedAssetFile;(Uri,String,Bundle);;Parameter[0..2];contentprovider",
@Override
public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
throws FileNotFoundException {
sink(uri); // $ hasTaintFlow
sink(mimeTypeFilter); // $ hasTaintFlow
sink(opts.get("some_key")); // $ hasTaintFlow
return null;
}
// "android.content;ContentProvider;true;openFile;(Uri,String,CancellationSignal);;Parameter[0];contentprovider",
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode, CancellationSignal signal) {
sink(uri); // $ hasTaintFlow
sink(mode); // Safe
sink(signal); // Safe
return null;
}
// "android.content;ContentProvider;true;openFile;(Uri,String);;Parameter[0..1];contentprovider",
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) {
sink(uri); // $ hasTaintFlow
sink(mode); // Safe
return null;
}
// "android.content;ContentProvider;true;query;(Uri,String[],Bundle,CancellationSignal);;Parameter[0..2];contentprovider",
@Override
public Cursor query(Uri uri, String[] projection, Bundle queryArgs,
CancellationSignal cancellationSignal) {
sink(uri); // $ hasTaintFlow
sink(projection); // $ hasTaintFlow
sink(queryArgs.get("some_key")); // $ hasTaintFlow
sink(cancellationSignal); // Safe
return null;
}
// "android.content;ContentProvider;true;query;(Uri,String[],String,String[],String);;Parameter[0..4];contentprovider",
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
sink(uri); // $ hasTaintFlow
sink(projection); // $ hasTaintFlow
sink(selection); // $ hasTaintFlow
sink(selectionArgs); // $ hasTaintFlow
return null;
}
// "android.content;ContentProvider;true;query;(Uri,String[],String,String[],String,CancellationSignal);;Parameter[0..4];contentprovider",
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder, CancellationSignal cancellationSignal) {
sink(uri); // $ hasTaintFlow
sink(projection); // $ hasTaintFlow
sink(selection); // $ hasTaintFlow
sink(selectionArgs); // $ hasTaintFlow
sink(sortOrder); // $ hasTaintFlow
sink(cancellationSignal); // Safe
return null;
}
// "android.content;ContentProvider;true;update;(Uri,ContentValues,Bundle);;Parameter[0..2];contentprovider",
@Override
public int update(Uri uri, ContentValues values, Bundle extras) {
sink(uri); // $ hasTaintFlow
sink(values); // $ hasTaintFlow
sink(extras.get("some_key")); // $ hasTaintFlow
return 0;
}
// "android.content;ContentProvider;true;update;(Uri,ContentValues,String,String[]);;Parameter[0..3];contentprovider"
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
sink(uri); // $ hasTaintFlow
sink(values); // $ hasTaintFlow
sink(selection); // $ hasTaintFlow
sink(selectionArgs); // $ hasTaintFlow
return 0;
}
@Override
public boolean onCreate() {
return false;
}
}

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/google-android-9.0.0

View File

@@ -0,0 +1,11 @@
import java
import semmle.code.java.dataflow.FlowSources
import TestUtilities.InlineFlowTest
class ProviderTaintFlowConf extends DefaultTaintFlowConf {
override predicate isSource(DataFlow::Node n) { n instanceof RemoteFlowSource }
}
class ProviderInlineFlowTest extends InlineFlowTest {
override DataFlow::Configuration getValueFlowConfig() { none() }
}

View File

@@ -1,7 +1,4 @@
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.ExternalFlow
import semmle.code.java.dataflow.TaintTracking
import TestUtilities.InlineFlowTest
class SummaryModelTest extends SummaryModelCsv {
@@ -9,8 +6,6 @@ class SummaryModelTest extends SummaryModelCsv {
row =
[
//"package;type;overrides;name;signature;ext;inputspec;outputspec;kind",
// This is temporarily modelled for the helper function newEnumerationWithElement, until the relevant package is modelled
"org.apache.commons.collections4.iterators;IteratorEnumeration;true;IteratorEnumeration;;;Element of Argument[0];Element of Argument[-1];value",
"generatedtest;Test;false;newRBWithMapValue;;;Argument[0];MapValue of ReturnValue;value",
"generatedtest;Test;false;newRBWithMapKey;;;Argument[0];MapKey of ReturnValue;value"
]

View File

@@ -25,47 +25,51 @@ import net.sf.saxon.s9api.XdmValue;
import net.sf.saxon.s9api.XsltCompiler;
@Controller
public class XsltInjection {
public class XsltInjectionTest {
public void testStreamSourceInputStream(Socket socket) throws Exception {
StreamSource source = new StreamSource(socket.getInputStream());
TransformerFactory.newInstance().newTransformer(source).transform(null, null);
TransformerFactory.newInstance().newTransformer(source).transform(null, null); // $hasXsltInjection
}
public void testStreamSourceReader(Socket socket) throws Exception {
StreamSource source = new StreamSource(new InputStreamReader(socket.getInputStream()));
TransformerFactory.newInstance().newTemplates(source).newTransformer().transform(null, null);
TransformerFactory.newInstance().newTemplates(source).newTransformer().transform(null, null); // $hasXsltInjection
}
@RequestMapping
public void testStreamSourceInjectedParam(@RequestParam String param) throws Exception {
String xslt = "<xsl:stylesheet [...]" + param + "</xsl:stylesheet>";
StreamSource source = new StreamSource(new StringReader(xslt));
TransformerFactory.newInstance().newTransformer(source).transform(null, null);
TransformerFactory.newInstance().newTransformer(source).transform(null, null); // $hasXsltInjection
}
public void testSAXSourceInputStream(Socket socket) throws Exception {
SAXSource source = new SAXSource(new InputSource(socket.getInputStream()));
TransformerFactory.newInstance().newTemplates(source).newTransformer().transform(null, null);
TransformerFactory.newInstance().newTemplates(source).newTransformer().transform(null, null); // $hasXsltInjection
}
public void testSAXSourceReader(Socket socket) throws Exception {
SAXSource source = new SAXSource(null, new InputSource(new InputStreamReader(socket.getInputStream())));
TransformerFactory.newInstance().newTransformer(source).transform(null, null);
SAXSource source =
new SAXSource(null, new InputSource(new InputStreamReader(socket.getInputStream())));
TransformerFactory.newInstance().newTransformer(source).transform(null, null); // $hasXsltInjection
}
public void testStAXSourceEventReader(Socket socket) throws Exception {
StAXSource source = new StAXSource(XMLInputFactory.newInstance().createXMLEventReader(socket.getInputStream()));
TransformerFactory.newInstance().newTransformer(source).transform(null, null);
StAXSource source =
new StAXSource(XMLInputFactory.newInstance().createXMLEventReader(socket.getInputStream()));
TransformerFactory.newInstance().newTransformer(source).transform(null, null); // $hasXsltInjection
}
public void testStAXSourceEventStream(Socket socket) throws Exception {
StAXSource source = new StAXSource(XMLInputFactory.newInstance().createXMLStreamReader(null, new InputStreamReader(socket.getInputStream())));
TransformerFactory.newInstance().newTemplates(source).newTransformer().transform(null, null);
StAXSource source = new StAXSource(XMLInputFactory.newInstance().createXMLStreamReader(null,
new InputStreamReader(socket.getInputStream())));
TransformerFactory.newInstance().newTemplates(source).newTransformer().transform(null, null); // $hasXsltInjection
}
public void testDOMSource(Socket socket) throws Exception {
DOMSource source = new DOMSource(DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(socket.getInputStream()));
TransformerFactory.newInstance().newTransformer(source).transform(null, null);
DOMSource source = new DOMSource(
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(socket.getInputStream()));
TransformerFactory.newInstance().newTransformer(source).transform(null, null); // $hasXsltInjection
}
public void testDisabledXXE(Socket socket) throws Exception {
@@ -73,30 +77,30 @@ public class XsltInjection {
TransformerFactory factory = TransformerFactory.newInstance();
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
factory.newTransformer(source).transform(null, null);
factory.newTransformer(source).transform(null, null); // $hasXsltInjection
}
public void testFeatureSecureProcessingDisabled(Socket socket) throws Exception {
StreamSource source = new StreamSource(socket.getInputStream());
TransformerFactory factory = TransformerFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false);
factory.newTransformer(source).transform(null, null);
factory.newTransformer(source).transform(null, null); // $hasXsltInjection
}
public void testSaxon(Socket socket) throws Exception {
StreamSource source = new StreamSource(socket.getInputStream());
XsltCompiler compiler = new Processor(true).newXsltCompiler();
compiler.compile(source).load().transform();
compiler.compile(source).load30().transform(null, null);
compiler.compile(source).load30().applyTemplates((Source) null);
compiler.compile(source).load30().applyTemplates((Source) null, null);
compiler.compile(source).load30().applyTemplates((XdmValue) null);
compiler.compile(source).load30().applyTemplates((XdmValue) null, null);
compiler.compile(source).load30().callFunction(null, null);
compiler.compile(source).load30().callFunction(null, null, null);
compiler.compile(source).load30().callTemplate(null);
compiler.compile(source).load30().callTemplate(null, null);
compiler.compile(source).load().transform(); // $hasXsltInjection
compiler.compile(source).load30().transform(null, null); // $hasXsltInjection
compiler.compile(source).load30().applyTemplates((Source) null); // $hasXsltInjection
compiler.compile(source).load30().applyTemplates((Source) null, null); // $hasXsltInjection
compiler.compile(source).load30().applyTemplates((XdmValue) null); // $hasXsltInjection
compiler.compile(source).load30().applyTemplates((XdmValue) null, null); // $hasXsltInjection
compiler.compile(source).load30().callFunction(null, null); // $hasXsltInjection
compiler.compile(source).load30().callFunction(null, null, null); // $hasXsltInjection
compiler.compile(source).load30().callTemplate(null); // $hasXsltInjection
compiler.compile(source).load30().callTemplate(null, null); // $hasXsltInjection
}
@RequestMapping
@@ -104,24 +108,24 @@ public class XsltInjection {
URI uri = new URI(param);
StreamSource source = new StreamSource(socket.getInputStream());
XsltCompiler compiler = new Processor(true).newXsltCompiler();
compiler.loadExecutablePackage(uri).load().transform();
compiler.compilePackage(source).link().load().transform();
compiler.loadLibraryPackage(uri).link().load().transform();
compiler.loadExecutablePackage(uri).load().transform(); // $hasXsltInjection
compiler.compilePackage(source).link().load().transform(); // $hasXsltInjection
compiler.loadLibraryPackage(uri).link().load().transform(); // $hasXsltInjection
}
public void testOkFeatureSecureProcessing(Socket socket) throws Exception {
StreamSource source = new StreamSource(socket.getInputStream());
TransformerFactory factory = TransformerFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
factory.newTransformer(source).transform(null, null);
factory.newTransformer(source).transform(null, null); // Safe
}
public void testOkSaxon(Socket socket) throws Exception {
StreamSource source = new StreamSource(socket.getInputStream());
XsltCompiler compiler = new Processor(true).newXsltCompiler();
compiler.compile(source).load().close();
compiler.compile((Source) new Object()).load().transform();
compiler.compile(source).load().close(); // Safe
compiler.compile((Source) new Object()).load().transform(); // Safe
}
}
}

View File

@@ -0,0 +1,22 @@
import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.XsltInjectionQuery
import TestUtilities.InlineExpectationsTest
class HasXsltInjectionTest extends InlineExpectationsTest {
HasXsltInjectionTest() { this = "HasXsltInjectionTest" }
override string getARelevantTag() { result = "hasXsltInjection" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "hasXsltInjection" and
exists(DataFlow::Node src, DataFlow::Node sink, XsltInjectionFlowConfig conf |
conf.hasFlow(src, sink)
|
sink.getLocation() = location and
element = sink.toString() and
value = ""
)
}
}

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/shiro-core-1.5.2:${testdir}/../../../stubs/spring-ldap-2.3.2
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/shiro-core-1.5.2:${testdir}/../../../stubs/spring-ldap-2.3.2:${testdir}/../../../stubs/Saxon-HE-9.9.1-7

View File

@@ -3,11 +3,12 @@ import java.io.InputStream;
import java.net.Socket;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class SpelInjection {
public class SpelInjectionTest {
private static final ExpressionParser PARSER = new SpelExpressionParser();
@@ -20,7 +21,18 @@ public class SpelInjection {
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression(input);
expression.getValue();
expression.getValue(); // $hasSpelInjection
}
public void testGetValueWithParseRaw(Socket socket) throws IOException {
InputStream in = socket.getInputStream();
byte[] bytes = new byte[1024];
int n = in.read(bytes);
String input = new String(bytes, 0, n);
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expression = parser.parseRaw(input);
expression.getValue(); // $hasSpelInjection
}
public void testGetValueWithChainedCalls(Socket socket) throws IOException {
@@ -31,7 +43,7 @@ public class SpelInjection {
String input = new String(bytes, 0, n);
Expression expression = new SpelExpressionParser().parseExpression(input);
expression.getValue();
expression.getValue(); // $hasSpelInjection
}
public void testSetValueWithRootObject(Socket socket) throws IOException {
@@ -45,7 +57,7 @@ public class SpelInjection {
Object root = new Object();
Object value = new Object();
expression.setValue(root, value);
expression.setValue(root, value); // $hasSpelInjection
}
public void testGetValueWithStaticParser(Socket socket) throws IOException {
@@ -56,7 +68,7 @@ public class SpelInjection {
String input = new String(bytes, 0, n);
Expression expression = PARSER.parseExpression(input);
expression.getValue();
expression.getValue(); // $hasSpelInjection
}
public void testGetValueType(Socket socket) throws IOException {
@@ -67,7 +79,7 @@ public class SpelInjection {
String input = new String(bytes, 0, n);
Expression expression = PARSER.parseExpression(input);
expression.getValueType();
expression.getValueType(); // $hasSpelInjection
}
public void testWithStandardEvaluationContext(Socket socket) throws IOException {
@@ -80,7 +92,7 @@ public class SpelInjection {
Expression expression = PARSER.parseExpression(input);
StandardEvaluationContext context = new StandardEvaluationContext();
expression.getValue(context);
expression.getValue(context); // $hasSpelInjection
}
public void testWithSimpleEvaluationContext(Socket socket) throws IOException {
@@ -93,8 +105,7 @@ public class SpelInjection {
Expression expression = PARSER.parseExpression(input);
SimpleEvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
// the expression is evaluated in a limited context
expression.getValue(context);
expression.getValue(context); // Safe - the expression is evaluated in a limited context
}
}

View File

@@ -0,0 +1,22 @@
import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.SpelInjectionQuery
import TestUtilities.InlineExpectationsTest
class HasSpelInjectionTest extends InlineExpectationsTest {
HasSpelInjectionTest() { this = "HasSpelInjectionTest" }
override string getARelevantTag() { result = "hasSpelInjection" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "hasSpelInjection" and
exists(DataFlow::Node src, DataFlow::Node sink, SpelInjectionConfig conf |
conf.hasFlow(src, sink)
|
sink.getLocation() = location and
element = sink.toString() and
value = ""
)
}
}

View File

@@ -0,0 +1,11 @@
// Generated automatically from org.apache.commons.collections4.BoundedCollection for testing purposes
package org.apache.commons.collections4;
import java.util.Collection;
public interface BoundedCollection<E> extends Collection<E>
{
boolean isFull();
int maxSize();
}

View File

@@ -0,0 +1,11 @@
// Generated automatically from org.apache.commons.collections4.BoundedMap for testing purposes
package org.apache.commons.collections4;
import org.apache.commons.collections4.IterableMap;
public interface BoundedMap<K, V> extends IterableMap<K, V>
{
boolean isFull();
int maxSize();
}

View File

@@ -0,0 +1,13 @@
// Generated automatically from org.apache.commons.collections4.SortedBidiMap for testing purposes
package org.apache.commons.collections4;
import java.util.Comparator;
import java.util.SortedMap;
import org.apache.commons.collections4.OrderedBidiMap;
public interface SortedBidiMap<K, V> extends OrderedBidiMap<K, V>, SortedMap<K, V>
{
Comparator<? super V> valueComparator();
SortedBidiMap<V, K> inverseBidiMap();
}

View File

@@ -0,0 +1,20 @@
// Generated automatically from org.apache.commons.collections4.bag.AbstractBagDecorator for testing purposes
package org.apache.commons.collections4.bag;
import java.util.Set;
import org.apache.commons.collections4.Bag;
import org.apache.commons.collections4.collection.AbstractCollectionDecorator;
abstract public class AbstractBagDecorator<E> extends AbstractCollectionDecorator<E> implements Bag<E>
{
protected AbstractBagDecorator(){}
protected AbstractBagDecorator(Bag<E> p0){}
protected Bag<E> decorated(){ return null; }
public Set<E> uniqueSet(){ return null; }
public boolean add(E p0, int p1){ return false; }
public boolean equals(Object p0){ return false; }
public boolean remove(Object p0, int p1){ return false; }
public int getCount(Object p0){ return 0; }
public int hashCode(){ return 0; }
}

View File

@@ -39,7 +39,7 @@ abstract public class AbstractMapBag<E> implements Bag<E>
public int hashCode(){ return 0; }
public int size(){ return 0; }
public void clear(){}
static class MutableInteger
protected static class MutableInteger
{
protected MutableInteger() {}
MutableInteger(int p0){}

View File

@@ -0,0 +1,17 @@
// Generated automatically from org.apache.commons.collections4.bag.AbstractSortedBagDecorator for testing purposes
package org.apache.commons.collections4.bag;
import java.util.Comparator;
import org.apache.commons.collections4.SortedBag;
import org.apache.commons.collections4.bag.AbstractBagDecorator;
abstract public class AbstractSortedBagDecorator<E> extends AbstractBagDecorator<E> implements SortedBag<E>
{
protected AbstractSortedBagDecorator(){}
protected AbstractSortedBagDecorator(SortedBag<E> p0){}
protected SortedBag<E> decorated(){ return null; }
public Comparator<? super E> comparator(){ return null; }
public E first(){ return null; }
public E last(){ return null; }
}

View File

@@ -0,0 +1,21 @@
// Generated automatically from org.apache.commons.collections4.bag.CollectionBag for testing purposes
package org.apache.commons.collections4.bag;
import java.util.Collection;
import org.apache.commons.collections4.Bag;
import org.apache.commons.collections4.bag.AbstractBagDecorator;
public class CollectionBag<E> extends AbstractBagDecorator<E>
{
protected CollectionBag() {}
public CollectionBag(Bag<E> p0){}
public boolean add(E p0){ return false; }
public boolean add(E p0, int p1){ return false; }
public boolean addAll(Collection<? extends E> p0){ return false; }
public boolean containsAll(Collection<? extends Object> p0){ return false; }
public boolean remove(Object p0){ return false; }
public boolean removeAll(Collection<? extends Object> p0){ return false; }
public boolean retainAll(Collection<? extends Object> p0){ return false; }
public static <E> Bag<E> collectionBag(Bag<E> p0){ return null; }
}

View File

@@ -0,0 +1,21 @@
// Generated automatically from org.apache.commons.collections4.bag.CollectionSortedBag for testing purposes
package org.apache.commons.collections4.bag;
import java.util.Collection;
import org.apache.commons.collections4.SortedBag;
import org.apache.commons.collections4.bag.AbstractSortedBagDecorator;
public class CollectionSortedBag<E> extends AbstractSortedBagDecorator<E>
{
protected CollectionSortedBag() {}
public CollectionSortedBag(SortedBag<E> p0){}
public boolean add(E p0){ return false; }
public boolean add(E p0, int p1){ return false; }
public boolean addAll(Collection<? extends E> p0){ return false; }
public boolean containsAll(Collection<? extends Object> p0){ return false; }
public boolean remove(Object p0){ return false; }
public boolean removeAll(Collection<? extends Object> p0){ return false; }
public boolean retainAll(Collection<? extends Object> p0){ return false; }
public static <E> SortedBag<E> collectionSortedBag(SortedBag<E> p0){ return null; }
}

View File

@@ -0,0 +1,13 @@
// Generated automatically from org.apache.commons.collections4.bag.HashBag for testing purposes
package org.apache.commons.collections4.bag;
import java.io.Serializable;
import java.util.Collection;
import org.apache.commons.collections4.bag.AbstractMapBag;
public class HashBag<E> extends AbstractMapBag<E> implements Serializable
{
public HashBag(){}
public HashBag(Collection<? extends E> p0){}
}

View File

@@ -0,0 +1,22 @@
// Generated automatically from org.apache.commons.collections4.bag.PredicatedBag for testing purposes
package org.apache.commons.collections4.bag;
import java.util.Set;
import org.apache.commons.collections4.Bag;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.collection.PredicatedCollection;
public class PredicatedBag<E> extends PredicatedCollection<E> implements Bag<E>
{
protected PredicatedBag() {}
protected Bag<E> decorated(){ return null; }
protected PredicatedBag(Bag<E> p0, Predicate<? super E> p1){}
public Set<E> uniqueSet(){ return null; }
public boolean add(E p0, int p1){ return false; }
public boolean equals(Object p0){ return false; }
public boolean remove(Object p0, int p1){ return false; }
public int getCount(Object p0){ return 0; }
public int hashCode(){ return 0; }
public static <E> PredicatedBag<E> predicatedBag(Bag<E> p0, Predicate<? super E> p1){ return null; }
}

View File

@@ -0,0 +1,19 @@
// Generated automatically from org.apache.commons.collections4.bag.PredicatedSortedBag for testing purposes
package org.apache.commons.collections4.bag;
import java.util.Comparator;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.SortedBag;
import org.apache.commons.collections4.bag.PredicatedBag;
public class PredicatedSortedBag<E> extends PredicatedBag<E> implements SortedBag<E>
{
protected PredicatedSortedBag() {}
protected PredicatedSortedBag(SortedBag<E> p0, Predicate<? super E> p1){}
protected SortedBag<E> decorated(){ return null; }
public Comparator<? super E> comparator(){ return null; }
public E first(){ return null; }
public E last(){ return null; }
public static <E> PredicatedSortedBag<E> predicatedSortedBag(SortedBag<E> p0, Predicate<? super E> p1){ return null; }
}

View File

@@ -0,0 +1,22 @@
// Generated automatically from org.apache.commons.collections4.bag.SynchronizedBag for testing purposes
package org.apache.commons.collections4.bag;
import java.util.Set;
import org.apache.commons.collections4.Bag;
import org.apache.commons.collections4.collection.SynchronizedCollection;
public class SynchronizedBag<E> extends SynchronizedCollection<E> implements Bag<E>
{
protected SynchronizedBag() {}
protected Bag<E> getBag(){ return null; }
protected SynchronizedBag(Bag<E> p0){}
protected SynchronizedBag(Bag<E> p0, Object p1){}
public Set<E> uniqueSet(){ return null; }
public boolean add(E p0, int p1){ return false; }
public boolean equals(Object p0){ return false; }
public boolean remove(Object p0, int p1){ return false; }
public int getCount(Object p0){ return 0; }
public int hashCode(){ return 0; }
public static <E> SynchronizedBag<E> synchronizedBag(Bag<E> p0){ return null; }
}

View File

@@ -0,0 +1,20 @@
// Generated automatically from org.apache.commons.collections4.bag.SynchronizedSortedBag for testing purposes
package org.apache.commons.collections4.bag;
import java.util.Comparator;
import org.apache.commons.collections4.Bag;
import org.apache.commons.collections4.SortedBag;
import org.apache.commons.collections4.bag.SynchronizedBag;
public class SynchronizedSortedBag<E> extends SynchronizedBag<E> implements SortedBag<E>
{
protected SynchronizedSortedBag() {}
protected SortedBag<E> getSortedBag(){ return null; }
protected SynchronizedSortedBag(Bag<E> p0, Object p1){}
protected SynchronizedSortedBag(SortedBag<E> p0){}
public Comparator<? super E> comparator(){ return null; }
public E first(){ return null; }
public E last(){ return null; }
public static <E> SynchronizedSortedBag<E> synchronizedSortedBag(SortedBag<E> p0){ return null; }
}

View File

@@ -0,0 +1,23 @@
// Generated automatically from org.apache.commons.collections4.bag.TransformedBag for testing purposes
package org.apache.commons.collections4.bag;
import java.util.Set;
import org.apache.commons.collections4.Bag;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.collection.TransformedCollection;
public class TransformedBag<E> extends TransformedCollection<E> implements Bag<E>
{
protected TransformedBag() {}
protected Bag<E> getBag(){ return null; }
protected TransformedBag(Bag<E> p0, Transformer<? super E, ? extends E> p1){}
public Set<E> uniqueSet(){ return null; }
public boolean add(E p0, int p1){ return false; }
public boolean equals(Object p0){ return false; }
public boolean remove(Object p0, int p1){ return false; }
public int getCount(Object p0){ return 0; }
public int hashCode(){ return 0; }
public static <E> Bag<E> transformedBag(Bag<E> p0, Transformer<? super E, ? extends E> p1){ return null; }
public static <E> Bag<E> transformingBag(Bag<E> p0, Transformer<? super E, ? extends E> p1){ return null; }
}

View File

@@ -0,0 +1,20 @@
// Generated automatically from org.apache.commons.collections4.bag.TransformedSortedBag for testing purposes
package org.apache.commons.collections4.bag;
import java.util.Comparator;
import org.apache.commons.collections4.SortedBag;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.bag.TransformedBag;
public class TransformedSortedBag<E> extends TransformedBag<E> implements SortedBag<E>
{
protected TransformedSortedBag() {}
protected SortedBag<E> getSortedBag(){ return null; }
protected TransformedSortedBag(SortedBag<E> p0, Transformer<? super E, ? extends E> p1){}
public Comparator<? super E> comparator(){ return null; }
public E first(){ return null; }
public E last(){ return null; }
public static <E> TransformedSortedBag<E> transformedSortedBag(SortedBag<E> p0, Transformer<? super E, ? extends E> p1){ return null; }
public static <E> TransformedSortedBag<E> transformingSortedBag(SortedBag<E> p0, Transformer<? super E, ? extends E> p1){ return null; }
}

View File

@@ -0,0 +1,28 @@
// Generated automatically from org.apache.commons.collections4.bag.UnmodifiableBag for testing purposes
package org.apache.commons.collections4.bag;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Predicate;
import org.apache.commons.collections4.Bag;
import org.apache.commons.collections4.Unmodifiable;
import org.apache.commons.collections4.bag.AbstractBagDecorator;
public class UnmodifiableBag<E> extends AbstractBagDecorator<E> implements Unmodifiable
{
protected UnmodifiableBag() {}
public Iterator<E> iterator(){ return null; }
public Set<E> uniqueSet(){ return null; }
public boolean add(E p0){ return false; }
public boolean add(E p0, int p1){ return false; }
public boolean addAll(Collection<? extends E> p0){ return false; }
public boolean remove(Object p0){ return false; }
public boolean remove(Object p0, int p1){ return false; }
public boolean removeAll(Collection<? extends Object> p0){ return false; }
public boolean removeIf(Predicate<? super E> p0){ return false; }
public boolean retainAll(Collection<? extends Object> p0){ return false; }
public static <E> Bag<E> unmodifiableBag(Bag<? extends E> p0){ return null; }
public void clear(){}
}

View File

@@ -0,0 +1,28 @@
// Generated automatically from org.apache.commons.collections4.bag.UnmodifiableSortedBag for testing purposes
package org.apache.commons.collections4.bag;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Predicate;
import org.apache.commons.collections4.SortedBag;
import org.apache.commons.collections4.Unmodifiable;
import org.apache.commons.collections4.bag.AbstractSortedBagDecorator;
public class UnmodifiableSortedBag<E> extends AbstractSortedBagDecorator<E> implements Unmodifiable
{
protected UnmodifiableSortedBag() {}
public Iterator<E> iterator(){ return null; }
public Set<E> uniqueSet(){ return null; }
public boolean add(E p0){ return false; }
public boolean add(E p0, int p1){ return false; }
public boolean addAll(Collection<? extends E> p0){ return false; }
public boolean remove(Object p0){ return false; }
public boolean remove(Object p0, int p1){ return false; }
public boolean removeAll(Collection<? extends Object> p0){ return false; }
public boolean removeIf(Predicate<? super E> p0){ return false; }
public boolean retainAll(Collection<? extends Object> p0){ return false; }
public static <E> SortedBag<E> unmodifiableSortedBag(SortedBag<E> p0){ return null; }
public void clear(){}
}

View File

@@ -0,0 +1,20 @@
// Generated automatically from org.apache.commons.collections4.bidimap.AbstractBidiMapDecorator for testing purposes
package org.apache.commons.collections4.bidimap;
import java.util.Set;
import org.apache.commons.collections4.BidiMap;
import org.apache.commons.collections4.MapIterator;
import org.apache.commons.collections4.map.AbstractMapDecorator;
abstract public class AbstractBidiMapDecorator<K, V> extends AbstractMapDecorator<K, V> implements BidiMap<K, V>
{
protected AbstractBidiMapDecorator() {}
protected AbstractBidiMapDecorator(BidiMap<K, V> p0){}
protected BidiMap<K, V> decorated(){ return null; }
public BidiMap<V, K> inverseBidiMap(){ return null; }
public K getKey(Object p0){ return null; }
public K removeValue(Object p0){ return null; }
public MapIterator<K, V> mapIterator(){ return null; }
public Set<V> values(){ return null; }
}

View File

@@ -0,0 +1,39 @@
// Generated automatically from org.apache.commons.collections4.bidimap.AbstractDualBidiMap for testing purposes
package org.apache.commons.collections4.bidimap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections4.BidiMap;
import org.apache.commons.collections4.MapIterator;
abstract public class AbstractDualBidiMap<K, V> implements BidiMap<K, V>
{
protected AbstractDualBidiMap(){}
protected AbstractDualBidiMap(Map<K, V> p0, Map<V, K> p1){}
protected AbstractDualBidiMap(Map<K, V> p0, Map<V, K> p1, BidiMap<V, K> p2){}
protected Iterator<K> createKeySetIterator(Iterator<K> p0){ return null; }
protected Iterator<Map.Entry<K, V>> createEntrySetIterator(Iterator<Map.Entry<K, V>> p0){ return null; }
protected Iterator<V> createValuesIterator(Iterator<V> p0){ return null; }
protected abstract BidiMap<V, K> createBidiMap(Map<V, K> p0, Map<K, V> p1, BidiMap<K, V> p2);
public BidiMap<V, K> inverseBidiMap(){ return null; }
public K getKey(Object p0){ return null; }
public K removeValue(Object p0){ return null; }
public MapIterator<K, V> mapIterator(){ return null; }
public Set<K> keySet(){ return null; }
public Set<Map.Entry<K, V>> entrySet(){ return null; }
public Set<V> values(){ return null; }
public String toString(){ return null; }
public V get(Object p0){ return null; }
public V put(K p0, V p1){ return null; }
public V remove(Object p0){ return null; }
public boolean containsKey(Object p0){ return false; }
public boolean containsValue(Object p0){ return false; }
public boolean equals(Object p0){ return false; }
public boolean isEmpty(){ return false; }
public int hashCode(){ return 0; }
public int size(){ return 0; }
public void clear(){}
public void putAll(Map<? extends K, ? extends V> p0){}
}

View File

@@ -0,0 +1,20 @@
// Generated automatically from org.apache.commons.collections4.bidimap.AbstractOrderedBidiMapDecorator for testing purposes
package org.apache.commons.collections4.bidimap;
import org.apache.commons.collections4.OrderedBidiMap;
import org.apache.commons.collections4.OrderedMapIterator;
import org.apache.commons.collections4.bidimap.AbstractBidiMapDecorator;
abstract public class AbstractOrderedBidiMapDecorator<K, V> extends AbstractBidiMapDecorator<K, V> implements OrderedBidiMap<K, V>
{
protected AbstractOrderedBidiMapDecorator() {}
protected AbstractOrderedBidiMapDecorator(OrderedBidiMap<K, V> p0){}
protected OrderedBidiMap<K, V> decorated(){ return null; }
public K firstKey(){ return null; }
public K lastKey(){ return null; }
public K nextKey(K p0){ return null; }
public K previousKey(K p0){ return null; }
public OrderedBidiMap<V, K> inverseBidiMap(){ return null; }
public OrderedMapIterator<K, V> mapIterator(){ return null; }
}

View File

@@ -0,0 +1,21 @@
// Generated automatically from org.apache.commons.collections4.bidimap.AbstractSortedBidiMapDecorator for testing purposes
package org.apache.commons.collections4.bidimap;
import java.util.Comparator;
import java.util.SortedMap;
import org.apache.commons.collections4.SortedBidiMap;
import org.apache.commons.collections4.bidimap.AbstractOrderedBidiMapDecorator;
abstract public class AbstractSortedBidiMapDecorator<K, V> extends AbstractOrderedBidiMapDecorator<K, V> implements SortedBidiMap<K, V>
{
protected AbstractSortedBidiMapDecorator() {}
protected SortedBidiMap<K, V> decorated(){ return null; }
public AbstractSortedBidiMapDecorator(SortedBidiMap<K, V> p0){}
public Comparator<? super K> comparator(){ return null; }
public Comparator<? super V> valueComparator(){ return null; }
public SortedBidiMap<V, K> inverseBidiMap(){ return null; }
public SortedMap<K, V> headMap(K p0){ return null; }
public SortedMap<K, V> subMap(K p0, K p1){ return null; }
public SortedMap<K, V> tailMap(K p0){ return null; }
}

View File

@@ -0,0 +1,16 @@
// Generated automatically from org.apache.commons.collections4.bidimap.DualHashBidiMap for testing purposes
package org.apache.commons.collections4.bidimap;
import java.io.Serializable;
import java.util.Map;
import org.apache.commons.collections4.BidiMap;
import org.apache.commons.collections4.bidimap.AbstractDualBidiMap;
public class DualHashBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements Serializable
{
protected BidiMap<V, K> createBidiMap(Map<V, K> p0, Map<K, V> p1, BidiMap<K, V> p2){ return null; }
protected DualHashBidiMap(Map<K, V> p0, Map<V, K> p1, BidiMap<V, K> p2){}
public DualHashBidiMap(){}
public DualHashBidiMap(Map<? extends K, ? extends V> p0){}
}

View File

@@ -0,0 +1,16 @@
// Generated automatically from org.apache.commons.collections4.bidimap.DualLinkedHashBidiMap for testing purposes
package org.apache.commons.collections4.bidimap;
import java.io.Serializable;
import java.util.Map;
import org.apache.commons.collections4.BidiMap;
import org.apache.commons.collections4.bidimap.AbstractDualBidiMap;
public class DualLinkedHashBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements Serializable
{
protected BidiMap<V, K> createBidiMap(Map<V, K> p0, Map<K, V> p1, BidiMap<K, V> p2){ return null; }
protected DualLinkedHashBidiMap(Map<K, V> p0, Map<V, K> p1, BidiMap<V, K> p2){}
public DualLinkedHashBidiMap(){}
public DualLinkedHashBidiMap(Map<? extends K, ? extends V> p0){}
}

View File

@@ -0,0 +1,35 @@
// Generated automatically from org.apache.commons.collections4.bidimap.DualTreeBidiMap for testing purposes
package org.apache.commons.collections4.bidimap;
import java.io.Serializable;
import java.util.Comparator;
import java.util.Map;
import java.util.SortedMap;
import org.apache.commons.collections4.BidiMap;
import org.apache.commons.collections4.OrderedBidiMap;
import org.apache.commons.collections4.OrderedMapIterator;
import org.apache.commons.collections4.SortedBidiMap;
import org.apache.commons.collections4.bidimap.AbstractDualBidiMap;
public class DualTreeBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements Serializable, SortedBidiMap<K, V>
{
protected DualTreeBidiMap(Map<K, V> p0, Map<V, K> p1, BidiMap<V, K> p2){}
protected DualTreeBidiMap<V, K> createBidiMap(Map<V, K> p0, Map<K, V> p1, BidiMap<K, V> p2){ return null; }
public Comparator<? super K> comparator(){ return null; }
public Comparator<? super V> valueComparator(){ return null; }
public DualTreeBidiMap(){}
public DualTreeBidiMap(Comparator<? super K> p0, Comparator<? super V> p1){}
public DualTreeBidiMap(Map<? extends K, ? extends V> p0){}
public K firstKey(){ return null; }
public K lastKey(){ return null; }
public K nextKey(K p0){ return null; }
public K previousKey(K p0){ return null; }
public OrderedBidiMap<V, K> inverseOrderedBidiMap(){ return null; }
public OrderedMapIterator<K, V> mapIterator(){ return null; }
public SortedBidiMap<V, K> inverseBidiMap(){ return null; }
public SortedBidiMap<V, K> inverseSortedBidiMap(){ return null; }
public SortedMap<K, V> headMap(K p0){ return null; }
public SortedMap<K, V> subMap(K p0, K p1){ return null; }
public SortedMap<K, V> tailMap(K p0){ return null; }
}

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