mirror of
https://github.com/github/codeql.git
synced 2026-05-02 20:25:13 +02:00
Merge branch 'main' into atorralba/promote-ognl-injection
This commit is contained in:
@@ -1,2 +1,2 @@
|
||||
| BusyWaits.java:4:4:4:19 | stmt | Prefer wait/notify or java.util.concurrent to communicate between threads. |
|
||||
| BusyWaits.java:10:5:10:39 | stmt | Prefer wait/notify or java.util.concurrent to communicate between threads. |
|
||||
| BusyWaits.java:4:4:4:19 | <Expr>; | Prefer wait/notify or java.util.concurrent to communicate between threads. |
|
||||
| BusyWaits.java:10:5:10:39 | <Expr>; | Prefer wait/notify or java.util.concurrent to communicate between threads. |
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
| CloseReader.java:11:42:11:71 | new FileReader(...) | This FileReader is not always closed on method exit. |
|
||||
| CloseReader.java:44:6:44:40 | new FileInputStream(...) | This FileInputStream is not always closed on method exit. |
|
||||
| CloseReader.java:18:42:18:71 | new FileReader(...) | This FileReader is not always closed on method exit. |
|
||||
| CloseReader.java:23:20:23:50 | new FileInputStream(...) | This FileInputStream is not always closed on method exit. |
|
||||
| CloseReader.java:33:6:33:40 | new FileInputStream(...) | This FileInputStream is not always closed on method exit. |
|
||||
| CloseReader.java:43:21:43:43 | new ZipFile(...) | This ZipFile is not always closed on method exit. |
|
||||
|
||||
@@ -1,41 +1,30 @@
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.CharArrayReader;
|
||||
import java.io.Closeable;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
class CloseReader {
|
||||
|
||||
public static void test1() throws IOException {
|
||||
void test1() throws IOException {
|
||||
BufferedReader br = new BufferedReader(new FileReader("C:\\test.txt"));
|
||||
System.out.println(br.readLine());
|
||||
}
|
||||
|
||||
public static void test2() throws FileNotFoundException, IOException {
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader("C:\\test.txt"));
|
||||
System.out.println(br.readLine());
|
||||
}
|
||||
finally {
|
||||
if(br != null)
|
||||
br.close(); // 'br' is closed
|
||||
}
|
||||
void test2() throws IOException {
|
||||
InputStream in = new FileInputStream("file.bin");
|
||||
in.read();
|
||||
}
|
||||
|
||||
public static void test3() throws IOException {
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader("C:\\test.txt"));
|
||||
System.out.println(br.readLine());
|
||||
}
|
||||
finally {
|
||||
cleanup(br); // 'br' is closed within a helper method
|
||||
}
|
||||
}
|
||||
|
||||
public static void test4() throws IOException {
|
||||
void test3() throws IOException {
|
||||
InputStreamReader reader = null;
|
||||
try {
|
||||
// InputStreamReader may throw an exception, in which case the ...
|
||||
@@ -50,7 +39,35 @@ class CloseReader {
|
||||
}
|
||||
}
|
||||
|
||||
public static void test5() throws IOException {
|
||||
void test4() throws IOException {
|
||||
ZipFile zipFile = new ZipFile("file.zip");
|
||||
System.out.println(zipFile.getComment());
|
||||
}
|
||||
|
||||
void testCorrect1() throws IOException {
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader("C:\\test.txt"));
|
||||
System.out.println(br.readLine());
|
||||
}
|
||||
finally {
|
||||
if(br != null)
|
||||
br.close(); // 'br' is closed
|
||||
}
|
||||
}
|
||||
|
||||
void testCorrect2() throws IOException {
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader("C:\\test.txt"));
|
||||
System.out.println(br.readLine());
|
||||
}
|
||||
finally {
|
||||
cleanup(br); // 'br' is closed within a helper method
|
||||
}
|
||||
}
|
||||
|
||||
void testCorrect3() throws IOException {
|
||||
FileInputStream fis = null;
|
||||
InputStreamReader reader = null;
|
||||
try {
|
||||
@@ -66,7 +83,7 @@ class CloseReader {
|
||||
}
|
||||
}
|
||||
|
||||
public static void test6() throws IOException {
|
||||
void testCorrect4() throws IOException {
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader("C:\\test.txt"));
|
||||
@@ -77,15 +94,15 @@ class CloseReader {
|
||||
}
|
||||
}
|
||||
|
||||
public static void cleanup(java.io.Closeable... closeables) throws IOException {
|
||||
for (java.io.Closeable c : closeables) {
|
||||
void cleanup(Closeable... closeables) throws IOException {
|
||||
for (Closeable c : closeables) {
|
||||
if (c != null) {
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class LogFile {
|
||||
static class LogFile {
|
||||
private BufferedReader fileRd;
|
||||
LogFile(String path) {
|
||||
FileReader fr = null;
|
||||
@@ -100,9 +117,21 @@ class CloseReader {
|
||||
private void init(InputStreamReader reader) {
|
||||
fileRd = new BufferedReader(reader);
|
||||
}
|
||||
public void readStuff() throws java.io.IOException {
|
||||
public void readStuff() throws IOException {
|
||||
System.out.println(fileRd.readLine());
|
||||
fileRd.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Classes which should be ignored
|
||||
void testIgnore() throws IOException {
|
||||
Reader r1 = new CharArrayReader(new char[] {'a'});
|
||||
r1.read();
|
||||
|
||||
Reader r2 = new StringReader("a");
|
||||
r2.read();
|
||||
|
||||
InputStream i1 = new ByteArrayInputStream(new byte[] {1});
|
||||
i1.read();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
Likely Bugs/Resource Leaks/CloseReader.ql
|
||||
Likely Bugs/Resource Leaks/CloseReader.ql
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
| CloseWriter.java:17:42:17:71 | new FileWriter(...) | This FileWriter is not always closed on method exit. |
|
||||
| CloseWriter.java:22:22:22:53 | new FileOutputStream(...) | This FileOutputStream is not always closed on method exit. |
|
||||
| CloseWriter.java:32:6:32:41 | new FileOutputStream(...) | This FileOutputStream is not always closed on method exit. |
|
||||
@@ -0,0 +1,131 @@
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.CharArrayWriter;
|
||||
import java.io.Closeable;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
class CloseWriter {
|
||||
|
||||
void test1() throws IOException {
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\test.txt"));
|
||||
bw.write("test");
|
||||
}
|
||||
|
||||
void test2() throws IOException {
|
||||
OutputStream out = new FileOutputStream("test.bin");
|
||||
out.write(1);
|
||||
}
|
||||
|
||||
void test3() throws IOException {
|
||||
OutputStreamWriter writer = null;
|
||||
try {
|
||||
// OutputStreamWriter may throw an exception, in which case the ...
|
||||
writer = new OutputStreamWriter(
|
||||
// ... FileOutputStream is not closed by the finally block
|
||||
new FileOutputStream("C:\\test.txt"), "UTF-8");
|
||||
writer.write("test");
|
||||
}
|
||||
finally {
|
||||
if (writer != null)
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
void testCorrect1() throws IOException {
|
||||
BufferedWriter bw = null;
|
||||
try {
|
||||
bw = new BufferedWriter(new FileWriter("C:\\test.txt"));
|
||||
bw.write("test");
|
||||
}
|
||||
finally {
|
||||
if(bw != null)
|
||||
bw.close(); // 'bw' is closed
|
||||
}
|
||||
}
|
||||
|
||||
void testCorrect2() throws IOException {
|
||||
BufferedWriter bw = null;
|
||||
try {
|
||||
bw = new BufferedWriter(new FileWriter("C:\\test.txt"));
|
||||
bw.write("test");
|
||||
}
|
||||
finally {
|
||||
cleanup(bw); // 'bw' is closed within a helper method
|
||||
}
|
||||
}
|
||||
|
||||
void testCorrect3() throws IOException {
|
||||
FileOutputStream fos = null;
|
||||
OutputStreamWriter writer = null;
|
||||
try {
|
||||
fos = new FileOutputStream("C:\\test.txt");
|
||||
writer = new OutputStreamWriter(fos);
|
||||
writer.write("test");
|
||||
}
|
||||
finally {
|
||||
if (fos != null)
|
||||
fos.close(); // 'fos' is closed
|
||||
if (writer != null)
|
||||
writer.close(); // 'writer' is closed
|
||||
}
|
||||
}
|
||||
|
||||
void testCorrect4() throws IOException {
|
||||
BufferedWriter bw = null;
|
||||
try {
|
||||
bw = new BufferedWriter(new FileWriter("C:\\test.txt"));
|
||||
bw.write("test");
|
||||
}
|
||||
finally {
|
||||
cleanup(null, bw); // 'bw' is closed within a varargs helper method, invoked with multiple args
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup(Closeable... closeables) throws IOException {
|
||||
for (Closeable c : closeables) {
|
||||
if (c != null) {
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class LogFile {
|
||||
private BufferedWriter fileWr;
|
||||
LogFile(String path) {
|
||||
FileWriter fw = null;
|
||||
try {
|
||||
fw = new FileWriter(path);
|
||||
} catch (IOException e) {
|
||||
System.out.println("Error: File not readable: " + path);
|
||||
System.exit(1);
|
||||
}
|
||||
init(fw);
|
||||
}
|
||||
private void init(OutputStreamWriter writer) {
|
||||
fileWr = new BufferedWriter(writer);
|
||||
}
|
||||
public void writeStuff() throws IOException {
|
||||
fileWr.write("test");
|
||||
fileWr.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Classes which should be ignored
|
||||
void testIgnore() throws IOException {
|
||||
Writer w1 = new CharArrayWriter();
|
||||
w1.write("test");
|
||||
|
||||
Writer w2 = new StringWriter();
|
||||
w2.write("test");
|
||||
|
||||
OutputStream o1 = new ByteArrayOutputStream();
|
||||
o1.write(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Likely Bugs/Resource Leaks/CloseWriter.ql
|
||||
@@ -1,4 +1,4 @@
|
||||
| A.java:8:11:8:15 | !... | $@ might not terminate, as this loop condition is constant within the loop. | A.java:8:5:8:16 | stmt | Loop |
|
||||
| A.java:15:11:15:15 | ... > ... | $@ might not terminate, as this loop condition is constant within the loop. | A.java:14:5:14:19 | stmt | Loop |
|
||||
| A.java:29:20:29:32 | ... < ... | $@ might not terminate, as this loop condition is constant within the loop. | A.java:29:5:29:38 | stmt | Loop |
|
||||
| A.java:36:12:36:15 | cond | $@ might not terminate, as this loop condition is constant within the loop. | A.java:36:5:36:16 | stmt | Loop |
|
||||
| A.java:8:11:8:15 | !... | $@ might not terminate, as this loop condition is constant within the loop. | A.java:8:5:8:16 | while (...) | Loop |
|
||||
| A.java:15:11:15:15 | ... > ... | $@ might not terminate, as this loop condition is constant within the loop. | A.java:14:5:14:19 | for (...;...;...) | Loop |
|
||||
| A.java:29:20:29:32 | ... < ... | $@ might not terminate, as this loop condition is constant within the loop. | A.java:29:5:29:38 | for (...;...;...) | Loop |
|
||||
| A.java:36:12:36:15 | cond | $@ might not terminate, as this loop condition is constant within the loop. | A.java:36:5:36:16 | while (...) | Loop |
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
| A.java:14:9:14:17 | stmt | This 'continue' never re-runs the loop - the $@ is always false. | A.java:17:14:17:18 | false | loop condition |
|
||||
| A.java:54:11:54:19 | stmt | This 'continue' never re-runs the loop - the $@ is always false. | A.java:57:16:57:20 | false | loop condition |
|
||||
| A.java:79:9:79:17 | stmt | This 'continue' never re-runs the loop - the $@ is always false. | A.java:82:14:82:18 | false | loop condition |
|
||||
| A.java:14:9:14:17 | continue | This 'continue' never re-runs the loop - the $@ is always false. | A.java:17:14:17:18 | false | loop condition |
|
||||
| A.java:54:11:54:19 | continue | This 'continue' never re-runs the loop - the $@ is always false. | A.java:57:16:57:20 | false | loop condition |
|
||||
| A.java:79:9:79:17 | continue | This 'continue' never re-runs the loop - the $@ is always false. | A.java:82:14:82:18 | false | loop condition |
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
| Test.java:14:4:14:10 | stmt | Switch case may fall through to the next case. Use a break or return to terminate this case. |
|
||||
| Test.java:20:4:20:10 | stmt | Switch case may fall through to the next case. Use a break or return to terminate this case. |
|
||||
| Test.java:14:4:14:10 | case ... | Switch case may fall through to the next case. Use a break or return to terminate this case. |
|
||||
| Test.java:20:4:20:10 | case ... | Switch case may fall through to the next case. Use a break or return to terminate this case. |
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
| A.java:12:7:16:7 | stmt | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:9:18:9:19 | s1 | s1 |
|
||||
| A.java:40:7:45:7 | stmt | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:36:13:36:14 | b1 | b1 |
|
||||
| A.java:101:7:106:7 | stmt | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:98:26:98:27 | b5 | b5 |
|
||||
| A.java:12:7:16:7 | synchronized (...) | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:9:18:9:19 | s1 | s1 |
|
||||
| A.java:40:7:45:7 | synchronized (...) | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:36:13:36:14 | b1 | b1 |
|
||||
| A.java:101:7:106:7 | synchronized (...) | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:98:26:98:27 | b5 | b5 |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
| Finally.java:6:4:6:10 | stmt | Leaving a finally-block with this statement can cause exceptions to silently disappear. |
|
||||
| Finally.java:17:5:17:13 | stmt | Leaving a finally-block with this statement can cause exceptions to silently disappear. |
|
||||
| Finally.java:30:5:30:40 | stmt | Leaving a finally-block with this statement can cause exceptions to silently disappear. |
|
||||
| Finally.java:63:6:63:11 | stmt | Leaving a finally-block with this statement can cause exceptions to silently disappear. |
|
||||
| Finally.java:77:7:77:12 | stmt | Leaving a finally-block with this statement can cause exceptions to silently disappear. |
|
||||
| Finally.java:111:6:111:14 | stmt | Leaving a finally-block with this statement can cause exceptions to silently disappear. |
|
||||
| Finally.java:125:7:125:15 | stmt | Leaving a finally-block with this statement can cause exceptions to silently disappear. |
|
||||
| Finally.java:6:4:6:10 | return ... | Leaving a finally-block with this statement can cause exceptions to silently disappear. |
|
||||
| Finally.java:17:5:17:13 | return ... | Leaving a finally-block with this statement can cause exceptions to silently disappear. |
|
||||
| Finally.java:30:5:30:40 | throw ... | Leaving a finally-block with this statement can cause exceptions to silently disappear. |
|
||||
| Finally.java:63:6:63:11 | break | Leaving a finally-block with this statement can cause exceptions to silently disappear. |
|
||||
| Finally.java:77:7:77:12 | break | Leaving a finally-block with this statement can cause exceptions to silently disappear. |
|
||||
| Finally.java:111:6:111:14 | continue | Leaving a finally-block with this statement can cause exceptions to silently disappear. |
|
||||
| Finally.java:125:7:125:15 | continue | Leaving a finally-block with this statement can cause exceptions to silently disappear. |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
| MissedTernaryOpportunityTest.java:6:3:6:13 | stmt | Both branches of this 'if' statement return - consider using '?' to express intent better. |
|
||||
| MissedTernaryOpportunityTest.java:32:3:32:13 | stmt | Both branches of this 'if' statement write to the same variable - consider using '?' to express intent better. |
|
||||
| MissedTernaryOpportunityTest.java:74:9:74:19 | stmt | Both branches of this 'if' statement return - consider using '?' to express intent better. |
|
||||
| MissedTernaryOpportunityTest.java:133:9:133:18 | stmt | Both branches of this 'if' statement write to the same variable - consider using '?' to express intent better. |
|
||||
| MissedTernaryOpportunityTest.java:145:13:145:23 | stmt | Both branches of this 'if' statement return - consider using '?' to express intent better. |
|
||||
| MissedTernaryOpportunityTest.java:155:13:155:23 | stmt | Both branches of this 'if' statement return - consider using '?' to express intent better. |
|
||||
| MissedTernaryOpportunityTest.java:6:3:6:13 | if (...) | Both branches of this 'if' statement return - consider using '?' to express intent better. |
|
||||
| MissedTernaryOpportunityTest.java:32:3:32:13 | if (...) | Both branches of this 'if' statement write to the same variable - consider using '?' to express intent better. |
|
||||
| MissedTernaryOpportunityTest.java:74:9:74:19 | if (...) | Both branches of this 'if' statement return - consider using '?' to express intent better. |
|
||||
| MissedTernaryOpportunityTest.java:133:9:133:18 | if (...) | Both branches of this 'if' statement write to the same variable - consider using '?' to express intent better. |
|
||||
| MissedTernaryOpportunityTest.java:145:13:145:23 | if (...) | Both branches of this 'if' statement return - consider using '?' to express intent better. |
|
||||
| MissedTernaryOpportunityTest.java:155:13:155:23 | if (...) | Both branches of this 'if' statement return - consider using '?' to express intent better. |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
| PartiallyMaskedCatchTest.java:16:5:16:25 | stmt | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:12:5:12:24 | stmt | here for exceptions of type 'ExceptionB' |
|
||||
| PartiallyMaskedCatchTest.java:16:5:16:25 | stmt | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:14:5:14:24 | stmt | here for exceptions of type 'ExceptionA' |
|
||||
| PartiallyMaskedCatchTest.java:26:5:26:25 | stmt | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:22:5:22:47 | stmt | here for exceptions of type 'ExceptionB' |
|
||||
| PartiallyMaskedCatchTest.java:26:5:26:25 | stmt | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:24:5:24:43 | stmt | here for exceptions of type 'ExceptionA' |
|
||||
| PartiallyMaskedCatchTest.java:36:5:36:44 | stmt | This catch-clause is unreachable for type IOException; it is masked $@. | PartiallyMaskedCatchTest.java:32:5:32:47 | stmt | here for exceptions of type 'ExceptionB' |
|
||||
| PartiallyMaskedCatchTest.java:36:5:36:44 | stmt | This catch-clause is unreachable for type IOException; it is masked $@. | PartiallyMaskedCatchTest.java:34:5:34:51 | stmt | here for exceptions of type 'ExceptionA' |
|
||||
| PartiallyMaskedCatchTest.java:16:5:16:25 | catch (...) | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:12:5:12:24 | catch (...) | here for exceptions of type 'ExceptionB' |
|
||||
| PartiallyMaskedCatchTest.java:16:5:16:25 | catch (...) | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:14:5:14:24 | catch (...) | here for exceptions of type 'ExceptionA' |
|
||||
| PartiallyMaskedCatchTest.java:26:5:26:25 | catch (...) | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:22:5:22:47 | catch (...) | here for exceptions of type 'ExceptionB' |
|
||||
| PartiallyMaskedCatchTest.java:26:5:26:25 | catch (...) | This catch-clause is unreachable; it is masked $@. | PartiallyMaskedCatchTest.java:24:5:24:43 | catch (...) | here for exceptions of type 'ExceptionA' |
|
||||
| PartiallyMaskedCatchTest.java:36:5:36:44 | catch (...) | This catch-clause is unreachable for type IOException; it is masked $@. | PartiallyMaskedCatchTest.java:32:5:32:47 | catch (...) | here for exceptions of type 'ExceptionB' |
|
||||
| PartiallyMaskedCatchTest.java:36:5:36:44 | catch (...) | This catch-clause is unreachable for type IOException; it is masked $@. | PartiallyMaskedCatchTest.java:34:5:34:51 | catch (...) | here for exceptions of type 'ExceptionA' |
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
| UseBraces.java:28:4:28:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:29:4:29:7 | stmt | the next statement | UseBraces.java:27:3:27:10 | stmt | the control structure |
|
||||
| UseBraces.java:32:4:32:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:32:9:32:12 | stmt | the next statement | UseBraces.java:31:3:31:10 | stmt | the control structure |
|
||||
| UseBraces.java:58:4:58:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:59:4:59:7 | stmt | the next statement | UseBraces.java:53:3:53:10 | stmt | the control structure |
|
||||
| UseBraces.java:66:4:66:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:66:10:66:13 | stmt | the next statement | UseBraces.java:61:3:61:10 | stmt | the control structure |
|
||||
| UseBraces.java:82:4:82:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:83:4:83:7 | stmt | the next statement | UseBraces.java:81:3:81:14 | stmt | the control structure |
|
||||
| UseBraces.java:87:4:87:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:87:9:87:12 | stmt | the next statement | UseBraces.java:86:3:86:14 | stmt | the control structure |
|
||||
| UseBraces.java:112:4:112:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:113:4:113:7 | stmt | the next statement | UseBraces.java:111:3:111:25 | stmt | the control structure |
|
||||
| UseBraces.java:116:4:116:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:116:9:116:12 | stmt | the next statement | UseBraces.java:115:3:115:25 | stmt | the control structure |
|
||||
| UseBraces.java:132:4:132:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:133:4:133:7 | stmt | the next statement | UseBraces.java:131:3:131:24 | stmt | the control structure |
|
||||
| UseBraces.java:136:4:136:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:136:9:136:12 | stmt | the next statement | UseBraces.java:135:3:135:24 | stmt | the control structure |
|
||||
| UseBraces.java:145:4:145:12 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:147:4:147:7 | stmt | the next statement | UseBraces.java:144:3:144:12 | stmt | the control structure |
|
||||
| UseBraces.java:166:4:166:7 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:167:4:167:7 | stmt | the next statement | UseBraces.java:165:8:165:17 | stmt | the control structure |
|
||||
| UseBraces.java:176:4:176:15 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:178:4:178:7 | stmt | the next statement | UseBraces.java:175:3:175:11 | stmt | the control structure |
|
||||
| UseBraces.java:186:4:186:12 | stmt | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:188:4:188:7 | stmt | the next statement | UseBraces.java:185:3:185:14 | stmt | the control structure |
|
||||
| UseBraces.java:28:4:28:7 | <Expr>; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:29:4:29:7 | <Expr>; | the next statement | UseBraces.java:27:3:27:10 | if (...) | the control structure |
|
||||
| UseBraces.java:32:4:32:7 | <Expr>; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:32:9:32:12 | <Expr>; | the next statement | UseBraces.java:31:3:31:10 | if (...) | the control structure |
|
||||
| UseBraces.java:58:4:58:7 | <Expr>; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:59:4:59:7 | <Expr>; | the next statement | UseBraces.java:53:3:53:10 | if (...) | the control structure |
|
||||
| UseBraces.java:66:4:66:7 | <Expr>; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:66:10:66:13 | <Expr>; | the next statement | UseBraces.java:61:3:61:10 | if (...) | the control structure |
|
||||
| UseBraces.java:82:4:82:7 | <Expr>; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:83:4:83:7 | <Expr>; | the next statement | UseBraces.java:81:3:81:14 | while (...) | the control structure |
|
||||
| UseBraces.java:87:4:87:7 | <Expr>; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:87:9:87:12 | <Expr>; | the next statement | UseBraces.java:86:3:86:14 | while (...) | the control structure |
|
||||
| UseBraces.java:112:4:112:7 | <Expr>; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:113:4:113:7 | <Expr>; | the next statement | UseBraces.java:111:3:111:25 | for (...;...;...) | the control structure |
|
||||
| UseBraces.java:116:4:116:7 | <Expr>; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:116:9:116:12 | <Expr>; | the next statement | UseBraces.java:115:3:115:25 | for (...;...;...) | the control structure |
|
||||
| UseBraces.java:132:4:132:7 | <Expr>; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:133:4:133:7 | <Expr>; | the next statement | UseBraces.java:131:3:131:24 | for (... : ...) | the control structure |
|
||||
| UseBraces.java:136:4:136:7 | <Expr>; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:136:9:136:12 | <Expr>; | the next statement | UseBraces.java:135:3:135:24 | for (... : ...) | the control structure |
|
||||
| UseBraces.java:145:4:145:12 | if (...) | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:147:4:147:7 | <Expr>; | the next statement | UseBraces.java:144:3:144:12 | if (...) | the control structure |
|
||||
| UseBraces.java:166:4:166:7 | <Expr>; | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:167:4:167:7 | <Expr>; | the next statement | UseBraces.java:165:8:165:17 | if (...) | the control structure |
|
||||
| UseBraces.java:176:4:176:15 | while (...) | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:178:4:178:7 | <Expr>; | the next statement | UseBraces.java:175:3:175:11 | if (...) | the control structure |
|
||||
| UseBraces.java:186:4:186:12 | if (...) | Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation. | UseBraces.java:188:4:188:7 | <Expr>; | the next statement | UseBraces.java:185:3:185:14 | while (...) | the control structure |
|
||||
|
||||
@@ -1 +1 @@
|
||||
| Test.java:15:3:15:14 | stmt |
|
||||
| Test.java:15:3:15:14 | return ... |
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
edges
|
||||
| Test.java:6:35:6:44 | arg : String | Test.java:7:44:7:69 | ... + ... |
|
||||
| Test.java:6:35:6:44 | arg : String | Test.java:10:29:10:74 | new String[] |
|
||||
| Test.java:6:35:6:44 | arg : String | Test.java:18:29:18:31 | cmd |
|
||||
| Test.java:6:35:6:44 | arg : String | Test.java:16:13:16:25 | ... + ... : String |
|
||||
| Test.java:6:35:6:44 | arg : String | Test.java:24:29:24:32 | cmd1 |
|
||||
| Test.java:16:5:16:7 | cmd [post update] : List | Test.java:18:29:18:31 | cmd |
|
||||
| Test.java:16:13:16:25 | ... + ... : String | Test.java:16:5:16:7 | cmd [post update] : List |
|
||||
| Test.java:28:38:28:47 | arg : String | Test.java:29:44:29:64 | ... + ... |
|
||||
| Test.java:57:27:57:39 | args : String[] | Test.java:60:20:60:22 | arg : String |
|
||||
| Test.java:57:27:57:39 | args : String[] | Test.java:61:23:61:25 | arg : String |
|
||||
@@ -12,6 +14,8 @@ nodes
|
||||
| Test.java:6:35:6:44 | arg : String | semmle.label | arg : String |
|
||||
| Test.java:7:44:7:69 | ... + ... | semmle.label | ... + ... |
|
||||
| Test.java:10:29:10:74 | new String[] | semmle.label | new String[] |
|
||||
| Test.java:16:5:16:7 | cmd [post update] : List | semmle.label | cmd [post update] : List |
|
||||
| Test.java:16:13:16:25 | ... + ... : String | semmle.label | ... + ... : String |
|
||||
| Test.java:18:29:18:31 | cmd | semmle.label | cmd |
|
||||
| Test.java:24:29:24:32 | cmd1 | semmle.label | cmd1 |
|
||||
| Test.java:28:38:28:47 | arg : String | semmle.label | arg : String |
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
edges
|
||||
| XSS.java:23:21:23:48 | getParameter(...) : String | XSS.java:23:5:23:70 | ... + ... |
|
||||
| XSS.java:27:21:27:48 | getParameter(...) : String | XSS.java:27:5:27:70 | ... + ... |
|
||||
| XSS.java:38:67:38:87 | getPathInfo(...) : String | XSS.java:38:30:38:87 | ... + ... |
|
||||
| XSS.java:41:36:41:56 | getPathInfo(...) : String | XSS.java:41:36:41:67 | getBytes(...) |
|
||||
nodes
|
||||
| XSS.java:23:5:23:70 | ... + ... | semmle.label | ... + ... |
|
||||
| XSS.java:23:21:23:48 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| XSS.java:27:5:27:70 | ... + ... | semmle.label | ... + ... |
|
||||
| XSS.java:27:21:27:48 | getParameter(...) : String | semmle.label | getParameter(...) : String |
|
||||
| XSS.java:38:30:38:87 | ... + ... | semmle.label | ... + ... |
|
||||
| XSS.java:38:67:38:87 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String |
|
||||
| XSS.java:41:36:41:56 | getPathInfo(...) : String | semmle.label | getPathInfo(...) : String |
|
||||
| XSS.java:41:36:41:67 | getBytes(...) | semmle.label | getBytes(...) |
|
||||
#select
|
||||
| XSS.java:23:5:23:70 | ... + ... | XSS.java:23:21:23:48 | getParameter(...) : String | XSS.java:23:5:23:70 | ... + ... | Cross-site scripting vulnerability due to $@. | XSS.java:23:21:23:48 | getParameter(...) | user-provided value |
|
||||
| XSS.java:27:5:27:70 | ... + ... | XSS.java:27:21:27:48 | getParameter(...) : String | XSS.java:27:5:27:70 | ... + ... | Cross-site scripting vulnerability due to $@. | XSS.java:27:21:27:48 | getParameter(...) | user-provided value |
|
||||
| XSS.java:38:30:38:87 | ... + ... | XSS.java:38:67:38:87 | getPathInfo(...) : String | XSS.java:38:30:38:87 | ... + ... | Cross-site scripting vulnerability due to $@. | XSS.java:38:67:38:87 | getPathInfo(...) | user-provided value |
|
||||
| XSS.java:41:36:41:67 | getBytes(...) | XSS.java:41:36:41:56 | getPathInfo(...) : String | XSS.java:41:36:41:67 | getBytes(...) | Cross-site scripting vulnerability due to $@. | XSS.java:41:36:41:56 | getPathInfo(...) | user-provided value |
|
||||
|
||||
@@ -22,7 +22,7 @@ public class XSS extends HttpServlet {
|
||||
response.getWriter().print(
|
||||
"The page \"" + request.getParameter("page") + "\" was not found.");
|
||||
|
||||
// BAD: a request parameter is written directly to an error response page
|
||||
// GOOD: servlet API encodes the error message HTML for the HTML context
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND,
|
||||
"The page \"" + request.getParameter("page") + "\" was not found.");
|
||||
|
||||
@@ -30,7 +30,7 @@ public class XSS extends HttpServlet {
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND,
|
||||
"The page \"" + encodeForHtml(request.getParameter("page")) + "\" was not found.");
|
||||
|
||||
// FALSE NEGATIVE: passed through function that is not a secure check
|
||||
// GOOD: servlet API encodes the error message HTML for the HTML context
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND,
|
||||
"The page \"" + capitalizeName(request.getParameter("page")) + "\" was not found.");
|
||||
|
||||
|
||||
119
java/ql/test/query-tests/security/CWE-094/Jexl2Injection.java
Normal file
119
java/ql/test/query-tests/security/CWE-094/Jexl2Injection.java
Normal file
@@ -0,0 +1,119 @@
|
||||
import org.apache.commons.jexl2.*;
|
||||
|
||||
import java.io.StringWriter;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Jexl2Injection {
|
||||
|
||||
private static void runJexlExpression(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlEngine();
|
||||
Expression e = jexl.createExpression(jexlExpr);
|
||||
JexlContext jc = new MapContext();
|
||||
e.evaluate(jc); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void runJexlExpressionWithJexlInfo(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlEngine();
|
||||
Expression e = jexl.createExpression(jexlExpr, new DebugInfo("unknown", 0, 0));
|
||||
JexlContext jc = new MapContext();
|
||||
e.evaluate(jc); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void runJexlScript(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlEngine();
|
||||
Script script = jexl.createScript(jexlExpr);
|
||||
JexlContext jc = new MapContext();
|
||||
script.execute(jc); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void runJexlScriptViaCallable(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlEngine();
|
||||
Script script = jexl.createScript(jexlExpr);
|
||||
JexlContext jc = new MapContext();
|
||||
|
||||
try {
|
||||
script.callable(jc).call(); // $hasJexlInjection
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void runJexlExpressionViaGetProperty(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlEngine();
|
||||
jexl.getProperty(new Object(), jexlExpr); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void runJexlExpressionViaSetProperty(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlEngine();
|
||||
jexl.setProperty(new Object(), jexlExpr, new Object()); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void runJexlExpressionViaUnifiedJEXLParseAndEvaluate(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlEngine();
|
||||
UnifiedJEXL unifiedJEXL = new UnifiedJEXL(jexl);
|
||||
unifiedJEXL.parse(jexlExpr).evaluate(new MapContext()); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void runJexlExpressionViaUnifiedJEXLParseAndPrepare(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlEngine();
|
||||
UnifiedJEXL unifiedJEXL = new UnifiedJEXL(jexl);
|
||||
unifiedJEXL.parse(jexlExpr).prepare(new MapContext()); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void runJexlExpressionViaUnifiedJEXLTemplateEvaluate(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlEngine();
|
||||
UnifiedJEXL unifiedJEXL = new UnifiedJEXL(jexl);
|
||||
unifiedJEXL.createTemplate(jexlExpr).evaluate(new MapContext(), new StringWriter()); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void testWithSocket(Consumer<String> action) throws Exception {
|
||||
try (ServerSocket serverSocket = new ServerSocket(0)) {
|
||||
try (Socket socket = serverSocket.accept()) {
|
||||
byte[] bytes = new byte[1024];
|
||||
int n = socket.getInputStream().read(bytes);
|
||||
String jexlExpr = new String(bytes, 0, n);
|
||||
action.accept(jexlExpr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// below are tests for the query
|
||||
|
||||
public static void testWithJexlExpressionEvaluate() throws Exception {
|
||||
testWithSocket(Jexl2Injection::runJexlExpression);
|
||||
}
|
||||
|
||||
public static void testWithJexlExpressionEvaluateWithInfo() throws Exception {
|
||||
testWithSocket(Jexl2Injection::runJexlExpressionWithJexlInfo);
|
||||
}
|
||||
|
||||
public static void testWithJexlScriptExecute() throws Exception {
|
||||
testWithSocket(Jexl2Injection::runJexlScript);
|
||||
}
|
||||
|
||||
public static void testWithJexlScriptCallable() throws Exception {
|
||||
testWithSocket(Jexl2Injection::runJexlScriptViaCallable);
|
||||
}
|
||||
|
||||
public static void testWithJexlEngineGetProperty() throws Exception {
|
||||
testWithSocket(Jexl2Injection::runJexlExpressionViaGetProperty);
|
||||
}
|
||||
|
||||
public static void testWithJexlEngineSetProperty() throws Exception {
|
||||
testWithSocket(Jexl2Injection::runJexlExpressionViaSetProperty);
|
||||
}
|
||||
|
||||
public static void testWithUnifiedJEXLParseAndEvaluate() throws Exception {
|
||||
testWithSocket(Jexl2Injection::runJexlExpressionViaUnifiedJEXLParseAndEvaluate);
|
||||
}
|
||||
|
||||
public static void testWithUnifiedJEXLParseAndPrepare() throws Exception {
|
||||
testWithSocket(Jexl2Injection::runJexlExpressionViaUnifiedJEXLParseAndPrepare);
|
||||
}
|
||||
|
||||
public static void testWithUnifiedJEXLTemplateEvaluate() throws Exception {
|
||||
testWithSocket(Jexl2Injection::runJexlExpressionViaUnifiedJEXLTemplateEvaluate);
|
||||
}
|
||||
}
|
||||
194
java/ql/test/query-tests/security/CWE-094/Jexl3Injection.java
Normal file
194
java/ql/test/query-tests/security/CWE-094/Jexl3Injection.java
Normal file
@@ -0,0 +1,194 @@
|
||||
import java.io.StringWriter;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.apache.commons.jexl3.*;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
@Controller
|
||||
public class Jexl3Injection {
|
||||
|
||||
private static void runJexlExpression(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlBuilder().create();
|
||||
JexlExpression e = jexl.createExpression(jexlExpr);
|
||||
JexlContext jc = new MapContext();
|
||||
e.evaluate(jc); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void runJexlExpressionWithJexlInfo(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlBuilder().create();
|
||||
JexlExpression e = jexl.createExpression(new JexlInfo("unknown", 0, 0), jexlExpr);
|
||||
JexlContext jc = new MapContext();
|
||||
e.evaluate(jc); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void runJexlScript(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlBuilder().create();
|
||||
JexlScript script = jexl.createScript(jexlExpr);
|
||||
JexlContext jc = new MapContext();
|
||||
script.execute(jc); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void runJexlScriptViaCallable(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlBuilder().create();
|
||||
JexlScript script = jexl.createScript(jexlExpr);
|
||||
JexlContext jc = new MapContext();
|
||||
|
||||
try {
|
||||
script.callable(jc).call(); // $hasJexlInjection
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void runJexlExpressionViaGetProperty(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlBuilder().create();
|
||||
jexl.getProperty(new Object(), jexlExpr); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void runJexlExpressionViaSetProperty(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlBuilder().create();
|
||||
jexl.setProperty(new Object(), jexlExpr, new Object()); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void runJexlExpressionViaJxltEngineExpressionEvaluate(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlBuilder().create();
|
||||
JxltEngine jxlt = jexl.createJxltEngine();
|
||||
jxlt.createExpression(jexlExpr).evaluate(new MapContext()); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void runJexlExpressionViaJxltEngineExpressionPrepare(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlBuilder().create();
|
||||
JxltEngine jxlt = jexl.createJxltEngine();
|
||||
jxlt.createExpression(jexlExpr).prepare(new MapContext()); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void runJexlExpressionViaJxltEngineTemplateEvaluate(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlBuilder().create();
|
||||
JxltEngine jxlt = jexl.createJxltEngine();
|
||||
jxlt.createTemplate(jexlExpr).evaluate(new MapContext(), new StringWriter()); // $hasJexlInjection
|
||||
}
|
||||
|
||||
private static void runJexlExpressionViaCallable(String jexlExpr) {
|
||||
JexlEngine jexl = new JexlBuilder().create();
|
||||
JexlExpression e = jexl.createExpression(jexlExpr);
|
||||
JexlContext jc = new MapContext();
|
||||
|
||||
try {
|
||||
e.callable(jc).call(); // $hasJexlInjection
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testWithSocket(Consumer<String> action) throws Exception {
|
||||
try (ServerSocket serverSocket = new ServerSocket(0)) {
|
||||
try (Socket socket = serverSocket.accept()) {
|
||||
byte[] bytes = new byte[1024];
|
||||
int n = socket.getInputStream().read(bytes);
|
||||
String jexlExpr = new String(bytes, 0, n);
|
||||
action.accept(jexlExpr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// below are tests for the query
|
||||
|
||||
public static void testWithJexlExpressionEvaluate() throws Exception {
|
||||
testWithSocket(Jexl3Injection::runJexlExpression);
|
||||
}
|
||||
|
||||
public static void testWithJexlExpressionEvaluateWithInfo() throws Exception {
|
||||
testWithSocket(Jexl3Injection::runJexlExpressionWithJexlInfo);
|
||||
}
|
||||
|
||||
public static void testWithJexlScriptExecute() throws Exception {
|
||||
testWithSocket(Jexl3Injection::runJexlScript);
|
||||
}
|
||||
|
||||
public static void testWithJexlScriptCallable() throws Exception {
|
||||
testWithSocket(Jexl3Injection::runJexlScriptViaCallable);
|
||||
}
|
||||
|
||||
public static void testWithJexlEngineGetProperty() throws Exception {
|
||||
testWithSocket(Jexl3Injection::runJexlExpressionViaGetProperty);
|
||||
}
|
||||
|
||||
public static void testWithJexlEngineSetProperty() throws Exception {
|
||||
testWithSocket(Jexl3Injection::runJexlExpressionViaSetProperty);
|
||||
}
|
||||
|
||||
public static void testWithJxltEngineExpressionEvaluate() throws Exception {
|
||||
testWithSocket(Jexl3Injection::runJexlExpressionViaJxltEngineExpressionEvaluate);
|
||||
}
|
||||
|
||||
public static void testWithJxltEngineExpressionPrepare() throws Exception {
|
||||
testWithSocket(Jexl3Injection::runJexlExpressionViaJxltEngineExpressionPrepare);
|
||||
}
|
||||
|
||||
public static void testWithJxltEngineTemplateEvaluate() throws Exception {
|
||||
testWithSocket(Jexl3Injection::runJexlExpressionViaJxltEngineTemplateEvaluate);
|
||||
}
|
||||
|
||||
public static void testWithJexlExpressionCallable() throws Exception {
|
||||
testWithSocket(Jexl3Injection::runJexlExpressionViaCallable);
|
||||
}
|
||||
|
||||
@PostMapping("/request")
|
||||
public ResponseEntity testWithSpringControllerThatEvaluatesJexlFromPathVariable(@PathVariable String expr) {
|
||||
|
||||
runJexlExpression(expr);
|
||||
return ResponseEntity.ok(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping("/request")
|
||||
public ResponseEntity testWithSpringControllerThatEvaluatesJexlFromRequestBody(@RequestBody Data data) {
|
||||
|
||||
String expr = data.getExpr();
|
||||
runJexlExpression(expr);
|
||||
|
||||
return ResponseEntity.ok(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping("/request")
|
||||
public ResponseEntity testWithSpringControllerThatEvaluatesJexlFromRequestBodyWithNestedObjects(
|
||||
@RequestBody CustomRequest customRequest) {
|
||||
|
||||
String expr = customRequest.getData().getExpr();
|
||||
runJexlExpression(expr);
|
||||
|
||||
return ResponseEntity.ok(HttpStatus.OK);
|
||||
}
|
||||
|
||||
public static class CustomRequest {
|
||||
|
||||
private Data data;
|
||||
|
||||
CustomRequest(Data data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Data getData() {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Data {
|
||||
|
||||
private String expr;
|
||||
|
||||
Data(String expr) {
|
||||
this.expr = expr;
|
||||
}
|
||||
|
||||
public String getExpr() {
|
||||
return expr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import semmle.code.java.dataflow.FlowSteps
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
import semmle.code.java.security.JexlInjection
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "qltest:cwe:jexl-injection" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof JexlEvaluationSink }
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
any(JexlInjectionAdditionalTaintStep c).step(node1, node2)
|
||||
}
|
||||
}
|
||||
|
||||
class JexlInjectionTest extends InlineExpectationsTest {
|
||||
JexlInjectionTest() { this = "HasJexlInjectionTest" }
|
||||
|
||||
override string getARelevantTag() { result = "hasJexlInjection" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "hasJexlInjection" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink, Conf conf | conf.hasFlow(src, sink) |
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import org.apache.commons.jexl2.*;
|
||||
import org.apache.commons.jexl2.introspection.*;
|
||||
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class SandboxedJexl2 {
|
||||
|
||||
private static void runJexlExpressionWithSandbox(String jexlExpr) {
|
||||
Sandbox sandbox = new Sandbox();
|
||||
sandbox.white(SandboxedJexl2.class.getCanonicalName());
|
||||
Uberspect uberspect = new SandboxUberspectImpl(null, sandbox);
|
||||
JexlEngine jexl = new JexlEngine(uberspect, null, null, null);
|
||||
Expression e = jexl.createExpression(jexlExpr);
|
||||
JexlContext jc = new MapContext();
|
||||
e.evaluate(jc); // Safe
|
||||
}
|
||||
|
||||
private static void runJexlExpressionViaSandboxedUnifiedJexl(String jexlExpr) {
|
||||
Sandbox sandbox = new Sandbox();
|
||||
sandbox.white(SandboxedJexl2.class.getCanonicalName());
|
||||
Uberspect uberspect = new SandboxUberspectImpl(null, sandbox);
|
||||
JexlEngine jexl = new JexlEngine(uberspect, null, null, null);
|
||||
UnifiedJEXL unifiedJEXL = new UnifiedJEXL(jexl);
|
||||
unifiedJEXL.parse(jexlExpr).evaluate(new MapContext()); // Safe
|
||||
}
|
||||
|
||||
private static void simpleServer(Consumer<String> action) throws Exception {
|
||||
try (ServerSocket serverSocket = new ServerSocket(0)) {
|
||||
try (Socket socket = serverSocket.accept()) {
|
||||
byte[] bytes = new byte[1024];
|
||||
int n = socket.getInputStream().read(bytes);
|
||||
String jexlExpr = new String(bytes, 0, n);
|
||||
action.accept(jexlExpr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void saferJexlExpressionEvaluate() throws Exception {
|
||||
simpleServer(SandboxedJexl2::runJexlExpressionWithSandbox);
|
||||
}
|
||||
|
||||
public static void saferJexlExpressionEvaluateViaUnifiedJexl() throws Exception {
|
||||
simpleServer(SandboxedJexl2::runJexlExpressionViaSandboxedUnifiedJexl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.security.AccessControlException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.apache.commons.jexl3.*;
|
||||
import org.apache.commons.jexl3.introspection.*;
|
||||
|
||||
public class SandboxedJexl3 {
|
||||
|
||||
private static void runJexlExpressionWithSandbox(String jexlExpr) {
|
||||
JexlSandbox sandbox = new JexlSandbox(false);
|
||||
sandbox.white(SandboxedJexl3.class.getCanonicalName());
|
||||
JexlEngine jexl = new JexlBuilder().sandbox(sandbox).create();
|
||||
JexlExpression e = jexl.createExpression(jexlExpr); // Safe
|
||||
JexlContext jc = new MapContext();
|
||||
e.evaluate(jc); // Safe
|
||||
}
|
||||
|
||||
private static void runJexlExpressionWithUberspectSandbox(String jexlExpr) {
|
||||
JexlUberspect sandbox = new JexlUberspectSandbox();
|
||||
JexlEngine jexl = new JexlBuilder().uberspect(sandbox).create();
|
||||
JexlExpression e = jexl.createExpression(jexlExpr); // Safe
|
||||
JexlContext jc = new MapContext();
|
||||
e.evaluate(jc); // Safe
|
||||
}
|
||||
|
||||
private static JexlBuilder STATIC_JEXL_BUILDER;
|
||||
|
||||
static {
|
||||
JexlSandbox sandbox = new JexlSandbox(false);
|
||||
sandbox.white(SandboxedJexl3.class.getCanonicalName());
|
||||
STATIC_JEXL_BUILDER = new JexlBuilder().sandbox(sandbox);
|
||||
}
|
||||
|
||||
private static void runJexlExpressionViaJxltEngineWithSandbox(String jexlExpr) {
|
||||
JexlEngine jexl = STATIC_JEXL_BUILDER.create();
|
||||
JxltEngine jxlt = jexl.createJxltEngine();
|
||||
jxlt.createExpression(jexlExpr).evaluate(new MapContext()); // Safe
|
||||
}
|
||||
|
||||
private static class JexlUberspectSandbox implements JexlUberspect {
|
||||
|
||||
}
|
||||
|
||||
private static void withSocket(Consumer<String> action) throws Exception {
|
||||
try (ServerSocket serverSocket = new ServerSocket(0)) {
|
||||
try (Socket socket = serverSocket.accept()) {
|
||||
byte[] bytes = new byte[1024];
|
||||
int n = socket.getInputStream().read(bytes);
|
||||
String jexlExpr = new String(bytes, 0, n);
|
||||
action.accept(jexlExpr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// below are examples of safer Jexl usage
|
||||
|
||||
// with JexlSandbox
|
||||
public static void saferJexlExpressionInSandbox() throws Exception {
|
||||
withSocket(SandboxedJexl3::runJexlExpressionWithSandbox);
|
||||
}
|
||||
|
||||
// with a custom sandbox implemented with JexlUberspect
|
||||
public static void saferJexlExpressionInUberspectSandbox() throws Exception {
|
||||
withSocket(SandboxedJexl3::runJexlExpressionWithUberspectSandbox);
|
||||
}
|
||||
|
||||
// with JexlSandbox and JxltEngine
|
||||
public static void saferJxltExpressionInSandbox() throws Exception {
|
||||
withSocket(SandboxedJexl3::runJexlExpressionViaJxltEngineWithSandbox);
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/validation-api-2.0.1.Final
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/validation-api-2.0.1.Final:${testdir}/../../../stubs/springframework-5.2.3:${testdir}/../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../stubs/apache-commons-logging-1.2
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
edges
|
||||
| HttpsUrlsTest.java:23:23:23:31 | "http://" : String | HttpsUrlsTest.java:28:50:28:50 | u |
|
||||
| HttpsUrlsTest.java:36:23:36:28 | "http" : String | HttpsUrlsTest.java:41:50:41:50 | u |
|
||||
| HttpsUrlsTest.java:49:23:49:31 | "http://" : String | HttpsUrlsTest.java:55:50:55:50 | u |
|
||||
| HttpsUrlsTest.java:87:23:87:28 | "http" : String | HttpsUrlsTest.java:92:50:92:50 | u |
|
||||
nodes
|
||||
| HttpsUrlsTest.java:23:23:23:31 | "http://" : String | semmle.label | "http://" : String |
|
||||
| HttpsUrlsTest.java:28:50:28:50 | u | semmle.label | u |
|
||||
| HttpsUrlsTest.java:36:23:36:28 | "http" : String | semmle.label | "http" : String |
|
||||
| HttpsUrlsTest.java:41:50:41:50 | u | semmle.label | u |
|
||||
| HttpsUrlsTest.java:49:23:49:31 | "http://" : String | semmle.label | "http://" : String |
|
||||
| HttpsUrlsTest.java:55:50:55:50 | u | semmle.label | u |
|
||||
| HttpsUrlsTest.java:87:23:87:28 | "http" : String | semmle.label | "http" : String |
|
||||
| HttpsUrlsTest.java:92:50:92:50 | u | semmle.label | u |
|
||||
#select
|
||||
| HttpsUrlsTest.java:28:50:28:67 | openConnection(...) | HttpsUrlsTest.java:23:23:23:31 | "http://" : String | HttpsUrlsTest.java:28:50:28:50 | u | URL may have been constructed with HTTP protocol, using $@. | HttpsUrlsTest.java:23:23:23:31 | "http://" | this source |
|
||||
| HttpsUrlsTest.java:41:50:41:67 | openConnection(...) | HttpsUrlsTest.java:36:23:36:28 | "http" : String | HttpsUrlsTest.java:41:50:41:50 | u | URL may have been constructed with HTTP protocol, using $@. | HttpsUrlsTest.java:36:23:36:28 | "http" | this source |
|
||||
| HttpsUrlsTest.java:55:50:55:67 | openConnection(...) | HttpsUrlsTest.java:49:23:49:31 | "http://" : String | HttpsUrlsTest.java:55:50:55:50 | u | URL may have been constructed with HTTP protocol, using $@. | HttpsUrlsTest.java:49:23:49:31 | "http://" | this source |
|
||||
| HttpsUrlsTest.java:92:50:92:67 | openConnection(...) | HttpsUrlsTest.java:87:23:87:28 | "http" : String | HttpsUrlsTest.java:92:50:92:50 | u | URL may have been constructed with HTTP protocol, using $@. | HttpsUrlsTest.java:87:23:87:28 | "http" | this source |
|
||||
@@ -0,0 +1 @@
|
||||
Security/CWE/CWE-319/HttpsUrls.ql
|
||||
@@ -0,0 +1,119 @@
|
||||
// Semmle test case for CWE-319: Cleartext Transmission of Sensitive Data
|
||||
// http://cwe.mitre.org/data/definitions/319.html
|
||||
package test.cwe319.cwe.examples;
|
||||
|
||||
import java.net.URL;
|
||||
import java.io.*;
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
import java.rmi.registry.*;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.rmi.ssl.*;
|
||||
|
||||
interface Hello extends java.rmi.Remote {
|
||||
String sayHello() throws java.rmi.RemoteException;
|
||||
}
|
||||
|
||||
class HelloImpl implements Hello {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
// HttpsUrls
|
||||
{
|
||||
String protocol = "http://";
|
||||
URL u = new URL(protocol + "www.secret.example.org/");
|
||||
// using HttpsURLConnections to enforce SSL is desirable
|
||||
// BAD: this will give a ClassCastException at runtime, as the
|
||||
// http URL cannot be used to make an HttpsURLConnection
|
||||
HttpsURLConnection hu = (HttpsURLConnection) u.openConnection();
|
||||
hu.setRequestMethod("PUT");
|
||||
hu.connect();
|
||||
OutputStream os = hu.getOutputStream();
|
||||
hu.disconnect();
|
||||
}
|
||||
|
||||
{
|
||||
String protocol = "http";
|
||||
URL u = new URL(protocol, "www.secret.example.org", "foo");
|
||||
// using HttpsURLConnections to enforce SSL is desirable
|
||||
// BAD: this will give a ClassCastException at runtime, as the
|
||||
// http URL cannot be used to make an HttpsURLConnection
|
||||
HttpsURLConnection hu = (HttpsURLConnection) u.openConnection();
|
||||
hu.setRequestMethod("PUT");
|
||||
hu.connect();
|
||||
OutputStream os = hu.getOutputStream();
|
||||
hu.disconnect();
|
||||
}
|
||||
|
||||
{
|
||||
String protocol = "http://";
|
||||
// the second URL overwrites the first, as it has a protocol
|
||||
URL u = new URL(new URL("https://www.secret.example.org"), protocol + "www.secret.example.org");
|
||||
// using HttpsURLConnections to enforce SSL is desirable
|
||||
// BAD: this will give a ClassCastException at runtime, as the
|
||||
// http URL cannot be used to make an HttpsURLConnection
|
||||
HttpsURLConnection hu = (HttpsURLConnection) u.openConnection();
|
||||
hu.setRequestMethod("PUT");
|
||||
hu.connect();
|
||||
OutputStream os = hu.getOutputStream();
|
||||
hu.disconnect();
|
||||
}
|
||||
|
||||
{
|
||||
String protocol = "https://";
|
||||
URL u = new URL(protocol + "www.secret.example.org/");
|
||||
// using HttpsURLConnections to enforce SSL is desirable
|
||||
// GOOD: open connection to URL using HTTPS
|
||||
HttpsURLConnection hu = (HttpsURLConnection) u.openConnection();
|
||||
hu.setRequestMethod("PUT");
|
||||
hu.connect();
|
||||
OutputStream os = hu.getOutputStream();
|
||||
hu.disconnect();
|
||||
}
|
||||
|
||||
{
|
||||
String protocol = "https";
|
||||
URL u = new URL(protocol, "www.secret.example.org", "foo");
|
||||
// using HttpsURLConnections to enforce SSL is desirable
|
||||
// GOOD: open connection to URL using HTTPS
|
||||
HttpsURLConnection hu = (HttpsURLConnection) u.openConnection();
|
||||
hu.setRequestMethod("PUT");
|
||||
hu.connect();
|
||||
OutputStream os = hu.getOutputStream();
|
||||
hu.disconnect();
|
||||
}
|
||||
|
||||
{
|
||||
String protocol = "http";
|
||||
URL u = new URL(protocol, "internal-url", "foo");
|
||||
// FALSE POSITIVE: the query has no way of knowing whether the url will
|
||||
// resolve to somewhere outside the internal network, where there
|
||||
// are unlikely to be interception attempts
|
||||
HttpsURLConnection hu = (HttpsURLConnection) u.openConnection();
|
||||
hu.setRequestMethod("PUT");
|
||||
hu.connect();
|
||||
OutputStream os = hu.getOutputStream();
|
||||
hu.disconnect();
|
||||
}
|
||||
|
||||
{
|
||||
String input = "URL is: http://www.secret-example.org";
|
||||
String url = input.substring(8);
|
||||
URL u = new URL(url);
|
||||
// FALSE NEGATIVE: we cannot tell that the substring results in a url
|
||||
// string
|
||||
HttpsURLConnection hu = (HttpsURLConnection) u.openConnection();
|
||||
hu.setRequestMethod("PUT");
|
||||
hu.connect();
|
||||
OutputStream os = hu.getOutputStream();
|
||||
hu.disconnect();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// fail
|
||||
}
|
||||
}
|
||||
|
||||
public String sayHello() {
|
||||
return "Hello";
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
| Test.java:11:15:11:41 | getInputStream(...) | Stream using vulnerable non-SSL connection. |
|
||||
| UseSSLTest.java:11:15:11:41 | getInputStream(...) | Stream using vulnerable non-SSL connection. |
|
||||
|
||||
@@ -2,7 +2,7 @@ import java.net.HttpURLConnection;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.*;
|
||||
|
||||
class Test {
|
||||
class UseSSLTest {
|
||||
public void m1(HttpURLConnection connection) throws java.io.IOException {
|
||||
InputStream input;
|
||||
if (connection instanceof HttpsURLConnection) {
|
||||
@@ -1 +1 @@
|
||||
| InfiniteLoop.java:4:13:4:36 | stmt | Loop might not terminate, as termination depends in part on $@ being false but it is always true. | InfiniteLoop.java:4:27:4:30 | ... < ... | this test |
|
||||
| InfiniteLoop.java:4:13:4:36 | for (...;...;...) | Loop might not terminate, as termination depends in part on $@ being false but it is always true. | InfiniteLoop.java:4:27:4:30 | ... < ... | this test |
|
||||
|
||||
Reference in New Issue
Block a user