mirror of
https://github.com/github/codeql.git
synced 2026-04-26 09:15:12 +02:00
Merge branch 'main' into jcogs33/java/insecure-spring-actuator-config-promotion
This commit is contained in:
@@ -143,4 +143,73 @@ public class Guards {
|
||||
chk(); // $ guarded=found:true guarded='i < a.length:false'
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean testNotNull1(String input) {
|
||||
return input != null && input.length() > 0;
|
||||
}
|
||||
|
||||
public static boolean testNotNull2(String input) {
|
||||
if (input == null) return false;
|
||||
return input.length() > 0;
|
||||
}
|
||||
|
||||
public static int getNumOrDefault(Integer number) {
|
||||
return number == null ? 0 : number;
|
||||
}
|
||||
|
||||
public static String concatNonNull(String s1, String s2) {
|
||||
if (s1 == null || s2 == null) return null;
|
||||
return s1 + s2;
|
||||
}
|
||||
|
||||
public static Status testEnumWrapper(boolean flag) {
|
||||
return flag ? Status.SUCCESS : Status.FAILURE;
|
||||
}
|
||||
|
||||
enum Status { SUCCESS, FAILURE }
|
||||
|
||||
void testWrappers(String s, Integer i) {
|
||||
if (testNotNull1(s)) {
|
||||
chk(); // $ guarded='s:not null' guarded=testNotNull1(...):true
|
||||
} else {
|
||||
chk(); // $ guarded=testNotNull1(...):false
|
||||
}
|
||||
|
||||
if (testNotNull2(s)) {
|
||||
chk(); // $ guarded='s:not null' guarded=testNotNull2(...):true
|
||||
} else {
|
||||
chk(); // $ guarded=testNotNull2(...):false
|
||||
}
|
||||
|
||||
if (0 == getNumOrDefault(i)) {
|
||||
chk(); // $ guarded='0 == getNumOrDefault(...):true' guarded='getNumOrDefault(...):0'
|
||||
} else {
|
||||
chk(); // $ guarded='0 == getNumOrDefault(...):false' guarded='getNumOrDefault(...):not 0' guarded='i:not 0' guarded='i:not null'
|
||||
}
|
||||
|
||||
if (null == concatNonNull(s, "suffix")) {
|
||||
chk(); // $ guarded='concatNonNull(...):null' guarded='null == concatNonNull(...):true'
|
||||
} else {
|
||||
chk(); // $ guarded='concatNonNull(...):not null' guarded='null == concatNonNull(...):false' guarded='s:not null'
|
||||
}
|
||||
|
||||
switch (testEnumWrapper(g(1))) {
|
||||
case SUCCESS:
|
||||
chk(); // $ guarded='testEnumWrapper(...):SUCCESS' guarded='testEnumWrapper(...):match SUCCESS' guarded=g(1):true
|
||||
break;
|
||||
case FAILURE:
|
||||
chk(); // $ guarded='testEnumWrapper(...):FAILURE' guarded='testEnumWrapper(...):match FAILURE' guarded=g(1):false
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ensureNotNull(Object o) throws Exception {
|
||||
if (o == null) throw new Exception();
|
||||
}
|
||||
|
||||
void testExceptionWrapper(String s) throws Exception {
|
||||
chk(); // nothing guards here
|
||||
ensureNotNull(s);
|
||||
chk(); // $ guarded='ensureNotNull(...):no exception' guarded='s:not null'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,3 +89,28 @@
|
||||
| Guards.java:139:9:139:13 | chk(...) | found:true |
|
||||
| Guards.java:143:7:143:11 | chk(...) | 'i < a.length:false' |
|
||||
| Guards.java:143:7:143:11 | chk(...) | found:true |
|
||||
| Guards.java:173:7:173:11 | chk(...) | 's:not null' |
|
||||
| Guards.java:173:7:173:11 | chk(...) | testNotNull1(...):true |
|
||||
| Guards.java:175:7:175:11 | chk(...) | testNotNull1(...):false |
|
||||
| Guards.java:179:7:179:11 | chk(...) | 's:not null' |
|
||||
| Guards.java:179:7:179:11 | chk(...) | testNotNull2(...):true |
|
||||
| Guards.java:181:7:181:11 | chk(...) | testNotNull2(...):false |
|
||||
| Guards.java:185:7:185:11 | chk(...) | '0 == getNumOrDefault(...):true' |
|
||||
| Guards.java:185:7:185:11 | chk(...) | 'getNumOrDefault(...):0' |
|
||||
| Guards.java:187:7:187:11 | chk(...) | '0 == getNumOrDefault(...):false' |
|
||||
| Guards.java:187:7:187:11 | chk(...) | 'getNumOrDefault(...):not 0' |
|
||||
| Guards.java:187:7:187:11 | chk(...) | 'i:not 0' |
|
||||
| Guards.java:187:7:187:11 | chk(...) | 'i:not null' |
|
||||
| Guards.java:191:7:191:11 | chk(...) | 'concatNonNull(...):null' |
|
||||
| Guards.java:191:7:191:11 | chk(...) | 'null == concatNonNull(...):true' |
|
||||
| Guards.java:193:7:193:11 | chk(...) | 'concatNonNull(...):not null' |
|
||||
| Guards.java:193:7:193:11 | chk(...) | 'null == concatNonNull(...):false' |
|
||||
| Guards.java:193:7:193:11 | chk(...) | 's:not null' |
|
||||
| Guards.java:198:9:198:13 | chk(...) | 'testEnumWrapper(...):SUCCESS' |
|
||||
| Guards.java:198:9:198:13 | chk(...) | 'testEnumWrapper(...):match SUCCESS' |
|
||||
| Guards.java:198:9:198:13 | chk(...) | g(1):true |
|
||||
| Guards.java:201:9:201:13 | chk(...) | 'testEnumWrapper(...):FAILURE' |
|
||||
| Guards.java:201:9:201:13 | chk(...) | 'testEnumWrapper(...):match FAILURE' |
|
||||
| Guards.java:201:9:201:13 | chk(...) | g(1):false |
|
||||
| Guards.java:213:5:213:9 | chk(...) | 'ensureNotNull(...):no exception' |
|
||||
| Guards.java:213:5:213:9 | chk(...) | 's:not null' |
|
||||
|
||||
@@ -408,4 +408,111 @@ public class B {
|
||||
x.hashCode(); // NPE
|
||||
}
|
||||
}
|
||||
|
||||
public void corrCondLoop1(boolean a[]) {
|
||||
Object x = new Object();
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
boolean b = a[i];
|
||||
if (b) {
|
||||
x = null;
|
||||
}
|
||||
if (!b) {
|
||||
x.hashCode(); // NPE - false negative
|
||||
}
|
||||
// flow can loop around from one iteration to the next
|
||||
}
|
||||
}
|
||||
|
||||
public void corrCondLoop2(boolean a[]) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
// x is local to the loop iteration and thus cannot loop around and reach the sink
|
||||
Object x = new Object();
|
||||
boolean b = a[i];
|
||||
if (b) {
|
||||
x = null;
|
||||
}
|
||||
if (!b) {
|
||||
x.hashCode(); // OK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loopCorrTest1(int[] a) {
|
||||
boolean ready = a.length > 7;
|
||||
Object x = new Object();
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
// condition correlates with itself through iterations when ready isn't updated
|
||||
if (!ready) {
|
||||
x = null;
|
||||
} else {
|
||||
x.hashCode(); // Spurious NPE - false positive
|
||||
}
|
||||
if ((a[i] & 1) != 0) {
|
||||
ready = (a[i] & 2) != 0;
|
||||
x = new Object();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loopCorrTest2(boolean[] a) {
|
||||
Object x = new Object();
|
||||
boolean cur = a[0];
|
||||
for (int i = 1; i < a.length; i++) {
|
||||
boolean prev = cur;
|
||||
cur = a[i];
|
||||
if (!prev) {
|
||||
// correctly guarded by !cur from the _previous_ iteration
|
||||
x.hashCode(); // Spurious NPE - false positive
|
||||
} else {
|
||||
x = new Object();
|
||||
}
|
||||
if (cur) {
|
||||
x = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loopCorrTest3(String[] ss) {
|
||||
Object x = null;
|
||||
Object t = null;
|
||||
for (String s : ss) {
|
||||
if (t == null) {
|
||||
t = s;
|
||||
} else {
|
||||
if (t instanceof String) {
|
||||
x = new Object();
|
||||
t = new Object();
|
||||
}
|
||||
// correctly guarded by t: null -> String -> Object
|
||||
x.hashCode(); // Spurious NPE - false positive
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void initCorr(boolean b) {
|
||||
Object o2 = b ? null : "";
|
||||
if (b)
|
||||
o2 = "";
|
||||
else
|
||||
o2.hashCode(); // OK
|
||||
}
|
||||
|
||||
public void complexLoopTest(int[] xs, int[] ys) {
|
||||
int len = ys != null ? ys.length : 0;
|
||||
for (int i = 0, j = 0; i < xs.length; i++) {
|
||||
if (j < len && ys[j] == 42) { // OK
|
||||
j++;
|
||||
} else if (j > 0) {
|
||||
ys[0]++; // OK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void trackTest(Object o, int n) {
|
||||
boolean isnull = o == null;
|
||||
int c = -1;
|
||||
if (maybe) { }
|
||||
if (c == 100) { return; }
|
||||
o.hashCode(); // NPE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ public class C {
|
||||
obj = new Object();
|
||||
} else if (a[i] == 2) {
|
||||
verifyNotNull(obj);
|
||||
obj.hashCode(); // NPE - false positive
|
||||
obj.hashCode(); // OK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
| B.java:279:7:279:7 | a | Variable $@ may be null at this access because of $@ assignment. | B.java:276:5:276:19 | int[] a | a | B.java:276:11:276:18 | a | this |
|
||||
| B.java:292:7:292:7 | b | Variable $@ may be null at this access because of $@ assignment. | B.java:287:5:287:44 | int[] b | b | B.java:287:11:287:43 | b | this |
|
||||
| B.java:408:7:408:7 | x | Variable $@ may be null at this access as suggested by $@ null guard. | B.java:374:23:374:30 | x | x | B.java:375:23:375:31 | ... != ... | this |
|
||||
| B.java:448:9:448:9 | x | Variable $@ may be null at this access because of $@ assignment. | B.java:442:5:442:28 | Object x | x | B.java:446:9:446:16 | ...=... | this |
|
||||
| B.java:465:9:465:9 | x | Variable $@ may be null at this access because of $@ assignment. | B.java:458:5:458:28 | Object x | x | B.java:470:9:470:16 | ...=... | this |
|
||||
| B.java:487:9:487:9 | x | Variable $@ may be null at this access because of $@ assignment. | B.java:476:5:476:20 | Object x | x | B.java:476:12:476:19 | x | this |
|
||||
| B.java:516:5:516:5 | o | Variable $@ may be null at this access as suggested by $@ null guard. | B.java:511:25:511:32 | o | o | B.java:512:22:512:30 | ... == ... | this |
|
||||
| C.java:9:44:9:45 | a2 | Variable $@ may be null at this access as suggested by $@ null guard. | C.java:6:5:6:23 | long[][] a2 | a2 | C.java:7:34:7:54 | ... != ... | this |
|
||||
| C.java:9:44:9:45 | a2 | Variable $@ may be null at this access because of $@ assignment. | C.java:6:5:6:23 | long[][] a2 | a2 | C.java:6:14:6:22 | a2 | this |
|
||||
| C.java:10:17:10:18 | a3 | Variable $@ may be null at this access as suggested by $@ null guard. | C.java:8:5:8:21 | long[] a3 | a3 | C.java:9:38:9:58 | ... != ... | this |
|
||||
@@ -29,7 +33,6 @@
|
||||
| C.java:137:7:137:10 | obj2 | Variable $@ may be null at this access as suggested by $@ null guard. | C.java:131:5:131:23 | Object obj2 | obj2 | C.java:132:9:132:20 | ... != ... | this |
|
||||
| C.java:144:15:144:15 | a | Variable $@ may be null at this access as suggested by $@ null guard. | C.java:141:20:141:26 | a | a | C.java:142:13:142:21 | ... == ... | this |
|
||||
| C.java:188:9:188:11 | obj | Variable $@ may be null at this access because of $@ assignment. | C.java:181:5:181:22 | Object obj | obj | C.java:181:12:181:21 | obj | this |
|
||||
| C.java:207:9:207:11 | obj | Variable $@ may be null at this access because of $@ assignment. | C.java:201:5:201:22 | Object obj | obj | C.java:201:12:201:21 | obj | this |
|
||||
| C.java:219:9:219:10 | o1 | Variable $@ may be null at this access as suggested by $@ null guard. | C.java:212:20:212:28 | o1 | o1 | C.java:213:9:213:18 | ... == ... | this |
|
||||
| C.java:233:7:233:8 | xs | Variable $@ may be null at this access because of $@ assignment. | C.java:231:5:231:56 | int[] xs | xs | C.java:231:11:231:55 | xs | this |
|
||||
| F.java:11:5:11:7 | obj | Variable $@ may be null at this access as suggested by $@ null guard. | F.java:8:18:8:27 | obj | obj | F.java:9:9:9:19 | ... == ... | this |
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.ServletException;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ExternalAPISinkExample extends HttpServlet {
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
// BAD: a request parameter is written directly to an error response page
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND,
|
||||
"The page \"" + request.getParameter("page") + "\" was not found."); // $ Alert
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.ServletException;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ExternalAPITaintStepExample extends HttpServlet {
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
|
||||
StringBuilder sqlQueryBuilder = new StringBuilder();
|
||||
sqlQueryBuilder.append("SELECT * FROM user WHERE user_id='");
|
||||
// BAD: a request parameter is concatenated directly into a SQL query
|
||||
sqlQueryBuilder.append(request.getParameter("user_id"));
|
||||
sqlQueryBuilder.append("'");
|
||||
|
||||
// ...
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
| javax.servlet.http.HttpServletResponse.sendError(int,java.lang.String) [param 1] | 1 | 1 |
|
||||
@@ -0,0 +1 @@
|
||||
Security/CWE/CWE-020/ExternalAPIsUsedWithUntrustedData.ql
|
||||
@@ -0,0 +1,11 @@
|
||||
#select
|
||||
| ExternalAPISinkExample.java:12:5:12:70 | ... + ... | ExternalAPISinkExample.java:12:21:12:48 | getParameter(...) : String | ExternalAPISinkExample.java:12:5:12:70 | ... + ... | Call to javax.servlet.http.HttpServletResponse.sendError with untrusted data from $@. | ExternalAPISinkExample.java:12:21:12:48 | getParameter(...) : String | getParameter(...) : String |
|
||||
edges
|
||||
| ExternalAPISinkExample.java:12:21:12:48 | getParameter(...) : String | ExternalAPISinkExample.java:12:5:12:70 | ... + ... | provenance | Src:MaD:2 Sink:MaD:1 |
|
||||
models
|
||||
| 1 | Sink: javax.servlet.http; HttpServletResponse; false; sendError; (int,String); ; Argument[1]; information-leak; manual |
|
||||
| 2 | Source: javax.servlet; ServletRequest; false; getParameter; (String); ; ReturnValue; remote; manual |
|
||||
nodes
|
||||
| ExternalAPISinkExample.java:12:5:12:70 | ... + ... | semmle.label | ... + ... |
|
||||
| ExternalAPISinkExample.java:12:21:12:48 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
subpaths
|
||||
@@ -0,0 +1,4 @@
|
||||
query: Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,4 +3,4 @@ extensions:
|
||||
pack: codeql/java-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["loginjection", "LogInjectionTest", False, "source", "()", "", "ReturnValue", "remote", "manual"]
|
||||
- ["loginjection", "LogInjectionTest", False, "source", "()", "", "ReturnValue", "remote", "manual"]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +0,0 @@
|
||||
import java
|
||||
import semmle.code.java.security.LogInjectionQuery
|
||||
import utils.test.InlineFlowTest
|
||||
import TaintFlowTest<LogInjectionConfig>
|
||||
@@ -0,0 +1,4 @@
|
||||
query: Security/CWE/CWE-117/LogInjection.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
@@ -0,0 +1,13 @@
|
||||
| UnsafeCertTrustTest.java:24:3:24:11 | sslEngine | Unsafe configuration of trusted certificates. |
|
||||
| UnsafeCertTrustTest.java:25:3:25:11 | sslEngine | Unsafe configuration of trusted certificates. |
|
||||
| UnsafeCertTrustTest.java:26:3:26:11 | sslEngine | Unsafe configuration of trusted certificates. |
|
||||
| UnsafeCertTrustTest.java:35:3:35:11 | sslEngine | Unsafe configuration of trusted certificates. |
|
||||
| UnsafeCertTrustTest.java:36:3:36:11 | sslEngine | Unsafe configuration of trusted certificates. |
|
||||
| UnsafeCertTrustTest.java:37:3:37:11 | sslEngine | Unsafe configuration of trusted certificates. |
|
||||
| UnsafeCertTrustTest.java:64:3:64:8 | socket | Unsafe configuration of trusted certificates. |
|
||||
| UnsafeCertTrustTest.java:74:3:74:8 | socket | Unsafe configuration of trusted certificates. |
|
||||
| UnsafeCertTrustTest.java:84:3:84:8 | socket | Unsafe configuration of trusted certificates. |
|
||||
| UnsafeCertTrustTest.java:91:3:91:8 | socket | Unsafe configuration of trusted certificates. |
|
||||
| UnsafeCertTrustTest.java:141:3:141:8 | socket | Unsafe configuration of trusted certificates. |
|
||||
| UnsafeCertTrustTest.java:153:4:153:60 | useSslProtocol(...) | Unsafe configuration of trusted certificates. |
|
||||
| UnsafeCertTrustTest.java:157:4:157:70 | setSslContextFactory(...) | Unsafe configuration of trusted certificates. |
|
||||
|
||||
@@ -21,9 +21,9 @@ public class UnsafeCertTrustTest {
|
||||
SSLParameters sslParameters = sslEngine.getSSLParameters();
|
||||
sslParameters.setEndpointIdentificationAlgorithm(null);
|
||||
sslEngine.setSSLParameters(sslParameters);
|
||||
sslEngine.beginHandshake(); // $hasUnsafeCertTrust
|
||||
sslEngine.wrap(new ByteBuffer[] {}, null); // $hasUnsafeCertTrust
|
||||
sslEngine.unwrap(null, null, 0, 0); // $hasUnsafeCertTrust
|
||||
sslEngine.beginHandshake(); // $ Alert
|
||||
sslEngine.wrap(new ByteBuffer[] {}, null); // $ Alert
|
||||
sslEngine.unwrap(null, null, 0, 0); // $ Alert
|
||||
}
|
||||
|
||||
public void testSSLEngineEndpointIdSetEmpty() throws Exception {
|
||||
@@ -32,9 +32,9 @@ public class UnsafeCertTrustTest {
|
||||
SSLParameters sslParameters = sslEngine.getSSLParameters();
|
||||
sslParameters.setEndpointIdentificationAlgorithm("");
|
||||
sslEngine.setSSLParameters(sslParameters);
|
||||
sslEngine.beginHandshake(); // $hasUnsafeCertTrust
|
||||
sslEngine.wrap(new ByteBuffer[] {}, null); // $hasUnsafeCertTrust
|
||||
sslEngine.unwrap(null, null, 0, 0); // $hasUnsafeCertTrust
|
||||
sslEngine.beginHandshake(); // $ Alert
|
||||
sslEngine.wrap(new ByteBuffer[] {}, null); // $ Alert
|
||||
sslEngine.unwrap(null, null, 0, 0); // $ Alert
|
||||
}
|
||||
|
||||
public void testSSLEngineEndpointIdSafe() throws Exception {
|
||||
@@ -61,7 +61,7 @@ public class UnsafeCertTrustTest {
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
|
||||
SSLSocket socket = (SSLSocket) socketFactory.createSocket();
|
||||
socket.getOutputStream(); // $hasUnsafeCertTrust
|
||||
socket.getOutputStream(); // $ Alert
|
||||
}
|
||||
|
||||
public void testSSLSocketEndpointIdSetNull() throws Exception {
|
||||
@@ -71,7 +71,7 @@ public class UnsafeCertTrustTest {
|
||||
SSLParameters sslParameters = socket.getSSLParameters();
|
||||
sslParameters.setEndpointIdentificationAlgorithm(null);
|
||||
socket.setSSLParameters(sslParameters);
|
||||
socket.getOutputStream(); // $hasUnsafeCertTrust
|
||||
socket.getOutputStream(); // $ Alert
|
||||
}
|
||||
|
||||
public void testSSLSocketEndpointIdSetEmpty() throws Exception {
|
||||
@@ -81,14 +81,14 @@ public class UnsafeCertTrustTest {
|
||||
SSLParameters sslParameters = socket.getSSLParameters();
|
||||
sslParameters.setEndpointIdentificationAlgorithm("");
|
||||
socket.setSSLParameters(sslParameters);
|
||||
socket.getOutputStream(); // $hasUnsafeCertTrust
|
||||
socket.getOutputStream(); // $ Alert
|
||||
}
|
||||
|
||||
public void testSSLSocketEndpointIdAfterConnecting() throws Exception {
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
|
||||
SSLSocket socket = (SSLSocket) socketFactory.createSocket();
|
||||
socket.getOutputStream(); // $hasUnsafeCertTrust
|
||||
socket.getOutputStream(); // $ Alert
|
||||
SSLParameters sslParameters = socket.getSSLParameters();
|
||||
sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
|
||||
socket.setSSLParameters(sslParameters);
|
||||
@@ -138,7 +138,7 @@ public class UnsafeCertTrustTest {
|
||||
SSLParameters sslParameters = sslSocket.getSSLParameters();
|
||||
sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
|
||||
sslSocket.setSSLParameters(sslParameters);
|
||||
socket.getOutputStream(); // $ SPURIOUS: hasUnsafeCertTrust
|
||||
socket.getOutputStream(); // $ SPURIOUS: Alert
|
||||
}
|
||||
|
||||
public void testSocketEndpointIdNotSet() throws Exception {
|
||||
@@ -150,11 +150,11 @@ public class UnsafeCertTrustTest {
|
||||
public void testRabbitMQFactoryEnableHostnameVerificationNotSet() throws Exception {
|
||||
{
|
||||
ConnectionFactory connectionFactory = new ConnectionFactory();
|
||||
connectionFactory.useSslProtocol(SSLContext.getDefault()); // $hasUnsafeCertTrust
|
||||
connectionFactory.useSslProtocol(SSLContext.getDefault()); // $ Alert
|
||||
}
|
||||
{
|
||||
ConnectionFactory connectionFactory = new ConnectionFactory();
|
||||
connectionFactory.setSslContextFactory(new TestSslContextFactory()); // $hasUnsafeCertTrust
|
||||
connectionFactory.setSslContextFactory(new TestSslContextFactory()); // $ Alert
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import java
|
||||
import semmle.code.java.security.UnsafeCertTrustQuery
|
||||
import utils.test.InlineExpectationsTest
|
||||
|
||||
module UnsafeCertTrustTest implements TestSig {
|
||||
string getARelevantTag() { result = "hasUnsafeCertTrust" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "hasUnsafeCertTrust" and
|
||||
exists(Expr unsafeTrust |
|
||||
unsafeTrust instanceof RabbitMQEnableHostnameVerificationNotSet
|
||||
or
|
||||
SslEndpointIdentificationFlow::flowTo(DataFlow::exprNode(unsafeTrust))
|
||||
|
|
||||
unsafeTrust.getLocation() = location and
|
||||
element = unsafeTrust.toString() and
|
||||
value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import MakeTest<UnsafeCertTrustTest>
|
||||
@@ -0,0 +1,4 @@
|
||||
query: Security/CWE/CWE-273/UnsafeCertTrust.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
@@ -0,0 +1,11 @@
|
||||
#select
|
||||
| TrustBoundaryViolations.java:14:52:14:56 | input | TrustBoundaryViolations.java:11:24:11:52 | getParameter(...) : String | TrustBoundaryViolations.java:14:52:14:56 | input | This servlet reads data from a $@ and writes it to a session variable. | TrustBoundaryViolations.java:11:24:11:52 | getParameter(...) : String | remote source |
|
||||
edges
|
||||
| TrustBoundaryViolations.java:11:24:11:52 | getParameter(...) : String | TrustBoundaryViolations.java:14:52:14:56 | input | provenance | Src:MaD:2 Sink:MaD:1 |
|
||||
models
|
||||
| 1 | Sink: javax.servlet.http; HttpSession; true; setAttribute; ; ; Argument[0..1]; trust-boundary-violation; manual |
|
||||
| 2 | Source: javax.servlet; ServletRequest; false; getParameter; (String); ; ReturnValue; remote; manual |
|
||||
nodes
|
||||
| TrustBoundaryViolations.java:11:24:11:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| TrustBoundaryViolations.java:14:52:14:56 | input | semmle.label | input |
|
||||
subpaths
|
||||
|
||||
@@ -8,10 +8,10 @@ public class TrustBoundaryViolations extends HttpServlet {
|
||||
Validator validator;
|
||||
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) {
|
||||
String input = request.getParameter("input");
|
||||
String input = request.getParameter("input"); // $ Source
|
||||
|
||||
// BAD: The input is written to the session without being sanitized.
|
||||
request.getSession().setAttribute("input", input); // $ hasTaintFlow
|
||||
request.getSession().setAttribute("input", input); // $ Alert
|
||||
|
||||
String input2 = request.getParameter("input2");
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
import java
|
||||
import semmle.code.java.security.TrustBoundaryViolationQuery
|
||||
import utils.test.InlineFlowTest
|
||||
import TaintFlowTest<TrustBoundaryConfig>
|
||||
@@ -0,0 +1,4 @@
|
||||
query: Security/CWE/CWE-501/TrustBoundaryViolation.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
@@ -0,0 +1,15 @@
|
||||
#select
|
||||
| Test.java:7:21:7:53 | ... + ... | Test.java:7:46:7:53 | password : String | Test.java:7:21:7:53 | ... + ... | This $@ is written to a log file. | Test.java:7:46:7:53 | password | potentially sensitive information |
|
||||
| Test.java:8:22:8:52 | ... + ... | Test.java:8:44:8:52 | authToken : String | Test.java:8:22:8:52 | ... + ... | This $@ is written to a log file. | Test.java:8:44:8:52 | authToken | potentially sensitive information |
|
||||
edges
|
||||
| Test.java:7:46:7:53 | password : String | Test.java:7:21:7:53 | ... + ... | provenance | Sink:MaD:2 |
|
||||
| Test.java:8:44:8:52 | authToken : String | Test.java:8:22:8:52 | ... + ... | provenance | Sink:MaD:1 |
|
||||
models
|
||||
| 1 | Sink: org.apache.logging.log4j; Logger; true; error; (String); ; Argument[0]; log-injection; manual |
|
||||
| 2 | Sink: org.apache.logging.log4j; Logger; true; info; (String); ; Argument[0]; log-injection; manual |
|
||||
nodes
|
||||
| Test.java:7:21:7:53 | ... + ... | semmle.label | ... + ... |
|
||||
| Test.java:7:46:7:53 | password : String | semmle.label | password : String |
|
||||
| Test.java:8:22:8:52 | ... + ... | semmle.label | ... + ... |
|
||||
| Test.java:8:44:8:52 | authToken : String | semmle.label | authToken : String |
|
||||
subpaths
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
import java
|
||||
import utils.test.InlineFlowTest
|
||||
import semmle.code.java.security.SensitiveLoggingQuery
|
||||
import TaintFlowTest<SensitiveLoggerConfig>
|
||||
@@ -0,0 +1,4 @@
|
||||
query: Security/CWE/CWE-532/SensitiveInfoLog.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
@@ -4,8 +4,8 @@ class Test {
|
||||
void test(String password, String authToken, String username, String nullToken, String stringTokenizer) {
|
||||
Logger logger = null;
|
||||
|
||||
logger.info("User's password is: " + password); // $ hasTaintFlow
|
||||
logger.error("Auth failed for: " + authToken); // $ hasTaintFlow
|
||||
logger.info("User's password is: " + password); // $ Alert
|
||||
logger.error("Auth failed for: " + authToken); // $ Alert
|
||||
logger.error("Auth failed for: " + username); // Safe
|
||||
logger.error("Auth failed for: " + nullToken); // Safe
|
||||
logger.error("Auth failed for: " + stringTokenizer); // Safe
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#select
|
||||
| ConditionalBypassTest.java:24:4:24:24 | login(...) | ConditionalBypassTest.java:19:20:19:50 | getParameter(...) : String | ConditionalBypassTest.java:23:7:23:24 | ... == ... | Sensitive method may not be executed depending on a $@, which flows from $@. | ConditionalBypassTest.java:23:7:23:24 | ... == ... | this condition | ConditionalBypassTest.java:19:20:19:50 | getParameter(...) | user-controlled value |
|
||||
| ConditionalBypassTest.java:30:4:30:24 | login(...) | ConditionalBypassTest.java:29:7:29:28 | getValue(...) : String | ConditionalBypassTest.java:29:7:29:44 | equals(...) | Sensitive method may not be executed depending on a $@, which flows from $@. | ConditionalBypassTest.java:29:7:29:44 | equals(...) | this condition | ConditionalBypassTest.java:29:7:29:28 | getValue(...) | user-controlled value |
|
||||
| ConditionalBypassTest.java:77:4:77:24 | login(...) | ConditionalBypassTest.java:76:7:76:28 | getValue(...) : String | ConditionalBypassTest.java:76:7:76:39 | ... == ... | Sensitive method may not be executed depending on a $@, which flows from $@. | ConditionalBypassTest.java:76:7:76:39 | ... == ... | this condition | ConditionalBypassTest.java:76:7:76:28 | getValue(...) | user-controlled value |
|
||||
| ConditionalBypassTest.java:89:4:89:24 | login(...) | ConditionalBypassTest.java:88:7:88:28 | getValue(...) : String | ConditionalBypassTest.java:88:7:88:39 | ... == ... | Sensitive method may not be executed depending on a $@, which flows from $@. | ConditionalBypassTest.java:88:7:88:39 | ... == ... | this condition | ConditionalBypassTest.java:88:7:88:28 | getValue(...) | user-controlled value |
|
||||
| ConditionalBypassTest.java:134:4:134:24 | login(...) | ConditionalBypassTest.java:133:7:133:28 | getValue(...) : String | ConditionalBypassTest.java:133:7:133:39 | ... == ... | Sensitive method may not be executed depending on a $@, which flows from $@. | ConditionalBypassTest.java:133:7:133:39 | ... == ... | this condition | ConditionalBypassTest.java:133:7:133:28 | getValue(...) | user-controlled value |
|
||||
| ConditionalBypassTest.java:146:5:146:29 | authorize(...) | ConditionalBypassTest.java:145:8:145:29 | getValue(...) : String | ConditionalBypassTest.java:145:8:145:40 | ... == ... | Sensitive method may not be executed depending on a $@, which flows from $@. | ConditionalBypassTest.java:145:8:145:40 | ... == ... | this condition | ConditionalBypassTest.java:145:8:145:29 | getValue(...) | user-controlled value |
|
||||
edges
|
||||
| ConditionalBypassTest.java:19:20:19:50 | getParameter(...) : String | ConditionalBypassTest.java:23:7:23:24 | ... == ... | provenance | Src:MaD:2 |
|
||||
| ConditionalBypassTest.java:29:7:29:28 | getValue(...) : String | ConditionalBypassTest.java:29:7:29:44 | equals(...) | provenance | Src:MaD:1 |
|
||||
| ConditionalBypassTest.java:76:7:76:28 | getValue(...) : String | ConditionalBypassTest.java:76:7:76:39 | ... == ... | provenance | Src:MaD:1 |
|
||||
| ConditionalBypassTest.java:88:7:88:28 | getValue(...) : String | ConditionalBypassTest.java:88:7:88:39 | ... == ... | provenance | Src:MaD:1 |
|
||||
| ConditionalBypassTest.java:133:7:133:28 | getValue(...) : String | ConditionalBypassTest.java:133:7:133:39 | ... == ... | provenance | Src:MaD:1 |
|
||||
| ConditionalBypassTest.java:145:8:145:29 | getValue(...) : String | ConditionalBypassTest.java:145:8:145:40 | ... == ... | provenance | Src:MaD:1 |
|
||||
models
|
||||
| 1 | Source: javax.servlet.http; Cookie; false; getValue; (); ; ReturnValue; remote; manual |
|
||||
| 2 | Source: javax.servlet; ServletRequest; false; getParameter; (String); ; ReturnValue; remote; manual |
|
||||
nodes
|
||||
| ConditionalBypassTest.java:19:20:19:50 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| ConditionalBypassTest.java:23:7:23:24 | ... == ... | semmle.label | ... == ... |
|
||||
| ConditionalBypassTest.java:29:7:29:28 | getValue(...) : String | semmle.label | getValue(...) : String |
|
||||
| ConditionalBypassTest.java:29:7:29:44 | equals(...) | semmle.label | equals(...) |
|
||||
| ConditionalBypassTest.java:76:7:76:28 | getValue(...) : String | semmle.label | getValue(...) : String |
|
||||
| ConditionalBypassTest.java:76:7:76:39 | ... == ... | semmle.label | ... == ... |
|
||||
| ConditionalBypassTest.java:88:7:88:28 | getValue(...) : String | semmle.label | getValue(...) : String |
|
||||
| ConditionalBypassTest.java:88:7:88:39 | ... == ... | semmle.label | ... == ... |
|
||||
| ConditionalBypassTest.java:133:7:133:28 | getValue(...) : String | semmle.label | getValue(...) : String |
|
||||
| ConditionalBypassTest.java:133:7:133:39 | ... == ... | semmle.label | ... == ... |
|
||||
| ConditionalBypassTest.java:145:8:145:29 | getValue(...) : String | semmle.label | getValue(...) : String |
|
||||
| ConditionalBypassTest.java:145:8:145:40 | ... == ... | semmle.label | ... == ... |
|
||||
subpaths
|
||||
|
||||
@@ -16,18 +16,18 @@ class ConditionalBypassTest {
|
||||
String user = request.getParameter("user");
|
||||
String password = request.getParameter("password");
|
||||
|
||||
String isAdmin = request.getParameter("isAdmin");
|
||||
String isAdmin = request.getParameter("isAdmin"); // $ Source
|
||||
|
||||
// BAD: login is only executed if isAdmin is false, but isAdmin
|
||||
// is controlled by the user
|
||||
if (isAdmin == "false") // $ hasConditionalBypassTest
|
||||
login(user, password);
|
||||
if (isAdmin == "false") // $ Sink
|
||||
login(user, password); // $ Alert
|
||||
|
||||
Cookie adminCookie = getCookies()[0];
|
||||
// BAD: login is only executed if the cookie value is false, but the cookie
|
||||
// is controlled by the user
|
||||
if (adminCookie.getValue().equals("false")) // $ hasConditionalBypassTest
|
||||
login(user, password);
|
||||
if (adminCookie.getValue().equals("false")) // $ Source Sink
|
||||
login(user, password); // $ Alert
|
||||
|
||||
// GOOD: both methods are conditionally executed, but they probably
|
||||
// both perform the security-critical action
|
||||
@@ -38,7 +38,7 @@ class ConditionalBypassTest {
|
||||
}
|
||||
|
||||
// FALSE NEGATIVE: we have no way of telling that the skipped method is sensitive
|
||||
if (adminCookie.getValue() == "false") // $ MISSING: hasConditionalBypassTest
|
||||
if (adminCookie.getValue() == "false") // $ MISSING: Alert
|
||||
doReallyImportantSecurityWork();
|
||||
|
||||
InetAddress local = InetAddress.getLocalHost();
|
||||
@@ -73,8 +73,8 @@ class ConditionalBypassTest {
|
||||
public static void test2(String user, String password) {
|
||||
Cookie adminCookie = getCookies()[0];
|
||||
// BAD: login may happen once or twice
|
||||
if (adminCookie.getValue() == "false") // $ hasConditionalBypassTest
|
||||
login(user, password);
|
||||
if (adminCookie.getValue() == "false") // $ Source Sink
|
||||
login(user, password); // $ Alert
|
||||
else {
|
||||
// do something else
|
||||
doIt();
|
||||
@@ -85,8 +85,8 @@ class ConditionalBypassTest {
|
||||
public static void test3(String user, String password) {
|
||||
Cookie adminCookie = getCookies()[0];
|
||||
// BAD: login may not happen
|
||||
if (adminCookie.getValue() == "false") // $ hasConditionalBypassTest
|
||||
login(user, password);
|
||||
if (adminCookie.getValue() == "false") // $ Source Sink
|
||||
login(user, password); // $ Alert
|
||||
else {
|
||||
// do something else
|
||||
doIt();
|
||||
@@ -130,8 +130,8 @@ class ConditionalBypassTest {
|
||||
public static void test7(String user, String password) {
|
||||
Cookie adminCookie = getCookies()[0];
|
||||
// BAD: login is bypasseable
|
||||
if (adminCookie.getValue() == "false") { // $ hasConditionalBypassTest
|
||||
login(user, password);
|
||||
if (adminCookie.getValue() == "false") { // $ Source Sink
|
||||
login(user, password); // $ Alert
|
||||
return;
|
||||
} else {
|
||||
doIt();
|
||||
@@ -142,8 +142,8 @@ class ConditionalBypassTest {
|
||||
Cookie adminCookie = getCookies()[0];
|
||||
{
|
||||
// BAD: login may not happen
|
||||
if (adminCookie.getValue() == "false") // $ hasConditionalBypassTest
|
||||
authorize(user, password);
|
||||
if (adminCookie.getValue() == "false") // $ Source Sink
|
||||
authorize(user, password); // $ Alert
|
||||
else {
|
||||
// do something else
|
||||
doIt();
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import java
|
||||
import semmle.code.java.security.ConditionalBypassQuery
|
||||
import utils.test.InlineExpectationsTest
|
||||
|
||||
module ConditionalBypassTest implements TestSig {
|
||||
string getARelevantTag() { result = "hasConditionalBypassTest" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "hasConditionalBypassTest" and
|
||||
exists(DataFlow::Node sink | ConditionalBypassFlow::flowTo(sink) |
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import MakeTest<ConditionalBypassTest>
|
||||
@@ -0,0 +1,4 @@
|
||||
query: Security/CWE/CWE-807/ConditionalBypass.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
@@ -1,4 +0,0 @@
|
||||
import java
|
||||
import semmle.code.java.security.AndroidSensitiveCommunicationQuery
|
||||
import utils.test.InlineFlowTest
|
||||
import TaintFlowTest<SensitiveCommunicationConfig>
|
||||
@@ -0,0 +1,80 @@
|
||||
#select
|
||||
| SensitiveCommunication.java:14:31:14:36 | intent | SensitiveCommunication.java:12:34:12:38 | token : String | SensitiveCommunication.java:14:31:14:36 | intent | This call may leak $@. | SensitiveCommunication.java:12:34:12:38 | token | sensitive information |
|
||||
| SensitiveCommunication.java:14:31:14:36 | intent | SensitiveCommunication.java:13:41:13:52 | refreshToken : String | SensitiveCommunication.java:14:31:14:36 | intent | This call may leak $@. | SensitiveCommunication.java:13:41:13:52 | refreshToken | sensitive information |
|
||||
| SensitiveCommunication.java:26:31:26:36 | intent | SensitiveCommunication.java:25:32:25:39 | password : String | SensitiveCommunication.java:26:31:26:36 | intent | This call may leak $@. | SensitiveCommunication.java:25:32:25:39 | password | sensitive information |
|
||||
| SensitiveCommunication.java:38:31:38:36 | intent | SensitiveCommunication.java:36:35:36:39 | email : String | SensitiveCommunication.java:38:31:38:36 | intent | This call may leak $@. | SensitiveCommunication.java:36:35:36:39 | email | sensitive information |
|
||||
| SensitiveCommunication.java:52:31:52:36 | intent | SensitiveCommunication.java:50:22:50:29 | password : String | SensitiveCommunication.java:52:31:52:36 | intent | This call may leak $@. | SensitiveCommunication.java:50:22:50:29 | password | sensitive information |
|
||||
| SensitiveCommunication.java:98:54:98:59 | intent | SensitiveCommunication.java:97:35:97:40 | ticket : String | SensitiveCommunication.java:98:54:98:59 | intent | This call may leak $@. | SensitiveCommunication.java:97:35:97:40 | ticket | sensitive information |
|
||||
| SensitiveCommunication.java:111:54:111:59 | intent | SensitiveCommunication.java:109:32:109:39 | passcode : String | SensitiveCommunication.java:111:54:111:59 | intent | This call may leak $@. | SensitiveCommunication.java:109:32:109:39 | passcode | sensitive information |
|
||||
| SensitiveCommunication.java:140:54:140:59 | intent | SensitiveCommunication.java:136:33:136:38 | passwd : String | SensitiveCommunication.java:140:54:140:59 | intent | This call may leak $@. | SensitiveCommunication.java:136:33:136:38 | passwd | sensitive information |
|
||||
| SensitiveCommunication.java:158:54:158:59 | intent | SensitiveCommunication.java:155:45:155:52 | password : String | SensitiveCommunication.java:158:54:158:59 | intent | This call may leak $@. | SensitiveCommunication.java:155:45:155:52 | password | sensitive information |
|
||||
edges
|
||||
| SensitiveCommunication.java:12:9:12:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | SensitiveCommunication.java:14:31:14:36 | intent | provenance | Sink:MaD:1 Sink:MaD:1 |
|
||||
| SensitiveCommunication.java:12:34:12:38 | token : String | SensitiveCommunication.java:12:9:12:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | provenance | MaD:3 |
|
||||
| SensitiveCommunication.java:13:9:13:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | SensitiveCommunication.java:14:31:14:36 | intent | provenance | Sink:MaD:1 Sink:MaD:1 |
|
||||
| SensitiveCommunication.java:13:41:13:52 | refreshToken : String | SensitiveCommunication.java:13:9:13:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | provenance | MaD:3 |
|
||||
| SensitiveCommunication.java:25:9:25:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | SensitiveCommunication.java:26:31:26:36 | intent | provenance | Sink:MaD:1 Sink:MaD:1 |
|
||||
| SensitiveCommunication.java:25:32:25:39 | password : String | SensitiveCommunication.java:25:9:25:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | provenance | MaD:3 |
|
||||
| SensitiveCommunication.java:36:9:36:14 | bundle [post update] : Bundle [<map.value>] : String | SensitiveCommunication.java:37:26:37:31 | bundle : Bundle [<map.value>] : String | provenance | |
|
||||
| SensitiveCommunication.java:36:35:36:39 | email : String | SensitiveCommunication.java:36:9:36:14 | bundle [post update] : Bundle [<map.value>] : String | provenance | MaD:6 |
|
||||
| SensitiveCommunication.java:37:9:37:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | SensitiveCommunication.java:38:31:38:36 | intent | provenance | Sink:MaD:1 Sink:MaD:1 |
|
||||
| SensitiveCommunication.java:37:26:37:31 | bundle : Bundle [<map.value>] : String | SensitiveCommunication.java:37:9:37:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | provenance | MaD:4 |
|
||||
| SensitiveCommunication.java:50:9:50:16 | userinfo [post update] : ArrayList [<element>] : String | SensitiveCommunication.java:51:52:51:59 | userinfo : ArrayList [<element>] : String | provenance | |
|
||||
| SensitiveCommunication.java:50:22:50:29 | password : String | SensitiveCommunication.java:50:9:50:16 | userinfo [post update] : ArrayList [<element>] : String | provenance | MaD:7 |
|
||||
| SensitiveCommunication.java:51:9:51:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>, <element>] : String | SensitiveCommunication.java:52:31:52:36 | intent | provenance | Sink:MaD:1 Sink:MaD:1 |
|
||||
| SensitiveCommunication.java:51:9:51:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>, <element>] : String | SensitiveCommunication.java:52:31:52:36 | intent | provenance | Sink:MaD:1 Sink:MaD:1 Sink:MaD:1 |
|
||||
| SensitiveCommunication.java:51:52:51:59 | userinfo : ArrayList [<element>] : String | SensitiveCommunication.java:51:9:51:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>, <element>] : String | provenance | MaD:5 |
|
||||
| SensitiveCommunication.java:97:9:97:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | SensitiveCommunication.java:98:54:98:59 | intent | provenance | Sink:MaD:2 Sink:MaD:2 |
|
||||
| SensitiveCommunication.java:97:35:97:40 | ticket : String | SensitiveCommunication.java:97:9:97:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | provenance | MaD:3 |
|
||||
| SensitiveCommunication.java:109:9:109:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | SensitiveCommunication.java:111:54:111:59 | intent | provenance | Sink:MaD:2 Sink:MaD:2 |
|
||||
| SensitiveCommunication.java:109:32:109:39 | passcode : String | SensitiveCommunication.java:109:9:109:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | provenance | MaD:3 |
|
||||
| SensitiveCommunication.java:136:9:136:14 | bundle [post update] : Bundle [<map.value>] : String | SensitiveCommunication.java:137:26:137:31 | bundle : Bundle [<map.value>] : String | provenance | |
|
||||
| SensitiveCommunication.java:136:33:136:38 | passwd : String | SensitiveCommunication.java:136:9:136:14 | bundle [post update] : Bundle [<map.value>] : String | provenance | MaD:6 |
|
||||
| SensitiveCommunication.java:137:9:137:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | SensitiveCommunication.java:140:54:140:59 | intent | provenance | Sink:MaD:2 Sink:MaD:2 |
|
||||
| SensitiveCommunication.java:137:26:137:31 | bundle : Bundle [<map.value>] : String | SensitiveCommunication.java:137:9:137:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | provenance | MaD:4 |
|
||||
| SensitiveCommunication.java:155:9:155:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | SensitiveCommunication.java:158:54:158:59 | intent | provenance | Sink:MaD:2 Sink:MaD:2 |
|
||||
| SensitiveCommunication.java:155:9:155:26 | getExtras(...) [post update] : Bundle [<map.value>] : String | SensitiveCommunication.java:155:9:155:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | provenance | |
|
||||
| SensitiveCommunication.java:155:45:155:52 | password : String | SensitiveCommunication.java:155:9:155:26 | getExtras(...) [post update] : Bundle [<map.value>] : String | provenance | MaD:6 |
|
||||
models
|
||||
| 1 | Sink: android.content; Context; true; sendBroadcast; ; ; Argument[0]; intent-redirection; manual |
|
||||
| 2 | Sink: android.content; Context; true; sendBroadcastWithMultiplePermissions; ; ; Argument[0]; intent-redirection; manual |
|
||||
| 3 | Summary: android.content; Intent; true; putExtra; ; ; Argument[1]; Argument[this].SyntheticField[android.content.Intent.extras].MapValue; value; manual |
|
||||
| 4 | Summary: android.content; Intent; true; putExtras; (Bundle); ; Argument[0].MapValue; Argument[this].SyntheticField[android.content.Intent.extras].MapValue; value; manual |
|
||||
| 5 | Summary: android.content; Intent; true; putStringArrayListExtra; ; ; Argument[1]; Argument[this].SyntheticField[android.content.Intent.extras].MapValue; value; manual |
|
||||
| 6 | Summary: android.os; BaseBundle; true; putString; ; ; Argument[1]; Argument[this].MapValue; value; manual |
|
||||
| 7 | Summary: java.util; Collection; true; add; ; ; Argument[0]; Argument[this].Element; value; manual |
|
||||
nodes
|
||||
| SensitiveCommunication.java:12:9:12:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | semmle.label | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String |
|
||||
| SensitiveCommunication.java:12:34:12:38 | token : String | semmle.label | token : String |
|
||||
| SensitiveCommunication.java:13:9:13:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | semmle.label | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String |
|
||||
| SensitiveCommunication.java:13:41:13:52 | refreshToken : String | semmle.label | refreshToken : String |
|
||||
| SensitiveCommunication.java:14:31:14:36 | intent | semmle.label | intent |
|
||||
| SensitiveCommunication.java:25:9:25:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | semmle.label | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String |
|
||||
| SensitiveCommunication.java:25:32:25:39 | password : String | semmle.label | password : String |
|
||||
| SensitiveCommunication.java:26:31:26:36 | intent | semmle.label | intent |
|
||||
| SensitiveCommunication.java:36:9:36:14 | bundle [post update] : Bundle [<map.value>] : String | semmle.label | bundle [post update] : Bundle [<map.value>] : String |
|
||||
| SensitiveCommunication.java:36:35:36:39 | email : String | semmle.label | email : String |
|
||||
| SensitiveCommunication.java:37:9:37:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | semmle.label | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String |
|
||||
| SensitiveCommunication.java:37:26:37:31 | bundle : Bundle [<map.value>] : String | semmle.label | bundle : Bundle [<map.value>] : String |
|
||||
| SensitiveCommunication.java:38:31:38:36 | intent | semmle.label | intent |
|
||||
| SensitiveCommunication.java:50:9:50:16 | userinfo [post update] : ArrayList [<element>] : String | semmle.label | userinfo [post update] : ArrayList [<element>] : String |
|
||||
| SensitiveCommunication.java:50:22:50:29 | password : String | semmle.label | password : String |
|
||||
| SensitiveCommunication.java:51:9:51:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>, <element>] : String | semmle.label | intent [post update] : Intent [android.content.Intent.extras, <map.value>, <element>] : String |
|
||||
| SensitiveCommunication.java:51:52:51:59 | userinfo : ArrayList [<element>] : String | semmle.label | userinfo : ArrayList [<element>] : String |
|
||||
| SensitiveCommunication.java:52:31:52:36 | intent | semmle.label | intent |
|
||||
| SensitiveCommunication.java:97:9:97:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | semmle.label | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String |
|
||||
| SensitiveCommunication.java:97:35:97:40 | ticket : String | semmle.label | ticket : String |
|
||||
| SensitiveCommunication.java:98:54:98:59 | intent | semmle.label | intent |
|
||||
| SensitiveCommunication.java:109:9:109:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | semmle.label | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String |
|
||||
| SensitiveCommunication.java:109:32:109:39 | passcode : String | semmle.label | passcode : String |
|
||||
| SensitiveCommunication.java:111:54:111:59 | intent | semmle.label | intent |
|
||||
| SensitiveCommunication.java:136:9:136:14 | bundle [post update] : Bundle [<map.value>] : String | semmle.label | bundle [post update] : Bundle [<map.value>] : String |
|
||||
| SensitiveCommunication.java:136:33:136:38 | passwd : String | semmle.label | passwd : String |
|
||||
| SensitiveCommunication.java:137:9:137:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | semmle.label | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String |
|
||||
| SensitiveCommunication.java:137:26:137:31 | bundle : Bundle [<map.value>] : String | semmle.label | bundle : Bundle [<map.value>] : String |
|
||||
| SensitiveCommunication.java:140:54:140:59 | intent | semmle.label | intent |
|
||||
| SensitiveCommunication.java:155:9:155:14 | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String | semmle.label | intent [post update] : Intent [android.content.Intent.extras, <map.value>] : String |
|
||||
| SensitiveCommunication.java:155:9:155:26 | getExtras(...) [post update] : Bundle [<map.value>] : String | semmle.label | getExtras(...) [post update] : Bundle [<map.value>] : String |
|
||||
| SensitiveCommunication.java:155:45:155:52 | password : String | semmle.label | password : String |
|
||||
| SensitiveCommunication.java:158:54:158:59 | intent | semmle.label | intent |
|
||||
subpaths
|
||||
@@ -9,9 +9,9 @@ class SensitiveBroadcast {
|
||||
public void sendBroadcast1(Context context, String token, String refreshToken) {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("token", token);
|
||||
intent.putExtra("refreshToken", refreshToken);
|
||||
context.sendBroadcast(intent); // $ hasTaintFlow
|
||||
intent.putExtra("token", token); // $ Source
|
||||
intent.putExtra("refreshToken", refreshToken); // $ Source
|
||||
context.sendBroadcast(intent); // $ Alert
|
||||
}
|
||||
|
||||
// BAD - Tests broadcast of sensitive user information with intent extra.
|
||||
@@ -22,41 +22,41 @@ class SensitiveBroadcast {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("name", userName);
|
||||
intent.putExtra("pwd", password);
|
||||
context.sendBroadcast(intent); // $ hasTaintFlow
|
||||
intent.putExtra("pwd", password); // $ Source
|
||||
context.sendBroadcast(intent); // $ Alert
|
||||
}
|
||||
|
||||
// BAD - Tests broadcast of email information with extra bundle.
|
||||
public void sendBroadcast3(Context context) {
|
||||
String email = "user123@example.com";
|
||||
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("email", email);
|
||||
bundle.putString("email", email); // $ Source
|
||||
intent.putExtras(bundle);
|
||||
context.sendBroadcast(intent); // $ hasTaintFlow
|
||||
}
|
||||
context.sendBroadcast(intent); // $ Alert
|
||||
}
|
||||
|
||||
// BAD - Tests broadcast of sensitive user information with null permission.
|
||||
public void sendBroadcast4(Context context) {
|
||||
String username = "test123";
|
||||
String password = "abc12345";
|
||||
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
ArrayList<String> userinfo = new ArrayList<String>();
|
||||
userinfo.add(username);
|
||||
userinfo.add(password);
|
||||
userinfo.add(password); // $ Source
|
||||
intent.putStringArrayListExtra("userinfo", userinfo);
|
||||
context.sendBroadcast(intent, null); // $ hasTaintFlow
|
||||
context.sendBroadcast(intent, null); // $ Alert
|
||||
}
|
||||
|
||||
// GOOD - Tests broadcast of sensitive user information with permission using string literal.
|
||||
public void sendBroadcast5(Context context) {
|
||||
String username = "test123";
|
||||
String password = "abc12345";
|
||||
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("name", username);
|
||||
@@ -67,106 +67,106 @@ class SensitiveBroadcast {
|
||||
// GOOD - Tests broadcast of access ticket with permission using string object.
|
||||
public void sendBroadcast6(Context context) {
|
||||
String ticket = "Tk9UIFNlY3VyZSBUaWNrZXQ=";
|
||||
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("ticket", ticket);
|
||||
String perm = "com.example.user_permission";
|
||||
context.sendBroadcast(intent, perm);
|
||||
context.sendBroadcast(intent, perm);
|
||||
}
|
||||
|
||||
// GOOD - Tests broadcast of sensitive user information to a specific application.
|
||||
public void sendBroadcast7(Context context) {
|
||||
String username = "test123";
|
||||
String password = "abc12345";
|
||||
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.setClassName("com.example2", "com.example2.UserInfoHandler");
|
||||
intent.putExtra("name", username);
|
||||
intent.putExtra("pwd", password);
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
|
||||
// BAD - Tests broadcast of access ticket with multiple permissions using direct empty array initialization.
|
||||
public void sendBroadcast8(Context context) {
|
||||
String ticket = "Tk9UIFNlY3VyZSBUaWNrZXQ=";
|
||||
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("ticket", ticket);
|
||||
context.sendBroadcastWithMultiplePermissions(intent, new String[]{}); // $ hasTaintFlow
|
||||
}
|
||||
intent.putExtra("ticket", ticket); // $ Source
|
||||
context.sendBroadcastWithMultiplePermissions(intent, new String[]{}); // $ Alert
|
||||
}
|
||||
|
||||
// BAD - Tests broadcast of sensitive user information with multiple permissions using empty array initialization through a variable.
|
||||
public void sendBroadcast9(Context context) {
|
||||
String username = "test123";
|
||||
String passcode = "abc12345";
|
||||
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("name", username);
|
||||
intent.putExtra("pwd", passcode);
|
||||
intent.putExtra("pwd", passcode); // $ Source
|
||||
String[] perms = new String[0];
|
||||
context.sendBroadcastWithMultiplePermissions(intent, perms); // $ hasTaintFlow
|
||||
}
|
||||
context.sendBroadcastWithMultiplePermissions(intent, perms); // $ Alert
|
||||
}
|
||||
|
||||
// GOOD - Tests broadcast of sensitive user information with multiple permissions.
|
||||
public void sendBroadcast10(Context context) {
|
||||
String username = "test123";
|
||||
String password = "abc12345";
|
||||
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("name", username);
|
||||
intent.putExtra("pwd", password);
|
||||
String[] perms = new String[]{"com.example.custom_action", "com.example.custom_action2"};
|
||||
context.sendBroadcastWithMultiplePermissions(intent, perms);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// BAD - Tests broadcast of sensitive user information with multiple permissions using empty array initialization through two variables and `intent.putExtras(bundle)`.
|
||||
public void sendBroadcast11(Context context) {
|
||||
String username = "test123";
|
||||
String passwd = "abc12345";
|
||||
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("name", username);
|
||||
bundle.putString("pwd", passwd);
|
||||
bundle.putString("pwd", passwd); // $ Source
|
||||
intent.putExtras(bundle);
|
||||
String[] perms = new String[0];
|
||||
String[] perms2 = perms;
|
||||
context.sendBroadcastWithMultiplePermissions(intent, perms2); // $ hasTaintFlow
|
||||
}
|
||||
context.sendBroadcastWithMultiplePermissions(intent, perms2); // $ Alert
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* BAD - Tests broadcast of sensitive user information with multiple permissions using empty array initialization through two variables and `intent.getExtras().putString()`.
|
||||
*/
|
||||
*/
|
||||
public void sendBroadcast12(Context context) {
|
||||
String username = "test123";
|
||||
String password = "abc12345";
|
||||
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
Bundle bundle = new Bundle();
|
||||
intent.putExtras(bundle);
|
||||
intent.getExtras().putString("name", username);
|
||||
intent.getExtras().putString("pwd", password);
|
||||
intent.getExtras().putString("pwd", password); // $ Source
|
||||
String[] perms = new String[0];
|
||||
String[] perms2 = perms;
|
||||
context.sendBroadcastWithMultiplePermissions(intent, perms2); // $ hasTaintFlow
|
||||
}
|
||||
context.sendBroadcastWithMultiplePermissions(intent, perms2); // $ Alert
|
||||
}
|
||||
|
||||
// GOOD - Tests broadcast of sensitive user information with ordered broadcast.
|
||||
public void sendBroadcast13(Context context) {
|
||||
String username = "test123";
|
||||
String password = "abc12345";
|
||||
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction("com.example.custom_action");
|
||||
intent.putExtra("name", username);
|
||||
intent.putExtra("pwd", password);
|
||||
context.sendOrderedBroadcast(intent, "com.example.USER_PERM");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
query: Security/CWE/CWE-927/SensitiveCommunication.ql
|
||||
postprocess:
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
@@ -0,0 +1 @@
|
||||
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/google-android-9.0.0
|
||||
Reference in New Issue
Block a user