From 65dd7eb8e77178d91d9b5a05d0a43311ead5f18b Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Thu, 11 May 2023 15:48:36 -0400 Subject: [PATCH 1/6] Java: add neutral models discovered with path-inj and ssrf heuristics --- java/ql/lib/ext/java.io.model.yml | 5 +++++ java/ql/lib/ext/java.nio.file.model.yml | 18 ++++++++++++++++++ java/ql/lib/ext/java.nio.file.spi.model.yml | 7 +++++++ java/ql/lib/ext/java.text.model.yml | 4 ++++ java/ql/lib/ext/java.util.prefs.model.yml | 7 +++++++ ...g.apache.hc.client5.http.protocol.model.yml | 6 ++++++ 6 files changed, 47 insertions(+) create mode 100644 java/ql/lib/ext/java.nio.file.spi.model.yml create mode 100644 java/ql/lib/ext/java.util.prefs.model.yml create mode 100644 java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index 2db99b7027e8..e3a48d4138d3 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -100,6 +100,7 @@ extensions: pack: codeql/java-all extensible: neutralModel data: + # summary neutrals - ["java.io", "Closeable", "close", "()", "summary", "manual"] - ["java.io", "DataOutput", "writeBoolean", "(boolean)", "summary", "manual"] - ["java.io", "File", "delete", "()", "summary", "manual"] @@ -117,3 +118,7 @@ extensions: - ["java.io", "DataInput", "readLong", "()", "summary", "manual"] # taint-numeric - ["java.io", "DataOutput", "writeInt", "(int)", "summary", "manual"] # taint-numeric - ["java.io", "DataOutput", "writeLong", "(long)", "summary", "manual"] # taint-numeric + + # sink neutrals + - ["java.io", "File", "compareTo", "", "sink", "manual"] + - ["java.io", "File", "exists", "()", "sink", "manual"] diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index 42ae8b9052ba..c178f6289804 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -81,4 +81,22 @@ extensions: pack: codeql/java-all extensible: neutralModel data: + # summary neutrals - ["java.nio.file", "Files", "exists", "(Path,LinkOption[])", "summary", "manual"] + + # sink neutrals + - ["java.nio.file", "Files" "exists", "", "sink", "manual"] + - ["java.nio.file", "Files" "getLastModifiedTime", "", "sink", "manual"] + - ["java.nio.file", "Files" "getOwner", "", "sink", "manual"] + - ["java.nio.file", "Files" "getPosixFilePermissions", "", "sink", "manual"] + - ["java.nio.file", "Files" "isDirectory", "", "sink", "manual"] + - ["java.nio.file", "Files" "isExecutable", "", "sink", "manual"] + - ["java.nio.file", "Files" "isHidden", "", "sink", "manual"] + - ["java.nio.file", "Files" "isReadable", "", "sink", "manual"] + - ["java.nio.file", "Files" "isRegularFile", "", "sink", "manual"] + - ["java.nio.file", "Files" "isSameFile", "", "sink", "manual"] + - ["java.nio.file", "Files" "isSymbolicLink", "", "sink", "manual"] + - ["java.nio.file", "Files" "isWritable", "", "sink", "manual"] + - ["java.nio.file", "Files" "notExists", "", "sink", "manual"] + - ["java.nio.file", "Files" "setLastModifiedTime", "", "sink", "manual"] + - ["java.nio.file", "Files" "size", "", "sink", "manual"] diff --git a/java/ql/lib/ext/java.nio.file.spi.model.yml b/java/ql/lib/ext/java.nio.file.spi.model.yml new file mode 100644 index 000000000000..a833c453eb3f --- /dev/null +++ b/java/ql/lib/ext/java.nio.file.spi.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["java.nio.file.spi", "FileSystemProvider" "isHidden", "", "manual"] + - ["java.nio.file.spi", "FileSystemProvider" "isSameFile", "", "manual"] diff --git a/java/ql/lib/ext/java.text.model.yml b/java/ql/lib/ext/java.text.model.yml index 728ed4fa6b4c..13b286b04387 100644 --- a/java/ql/lib/ext/java.text.model.yml +++ b/java/ql/lib/ext/java.text.model.yml @@ -3,6 +3,10 @@ extensions: pack: codeql/java-all extensible: neutralModel data: + - ["java.text", "Collator" "compare", "", "manual"] + - ["java.text", "Collator" "equals", "", "manual"] + - ["java.text", "RuleBasedCollator", "compare", "", "manual"] + # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - ["java.text", "DateFormat", "format", "(Date)", "summary", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.util.prefs.model.yml b/java/ql/lib/ext/java.util.prefs.model.yml new file mode 100644 index 000000000000..c27ba79029b2 --- /dev/null +++ b/java/ql/lib/ext/java.util.prefs.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["java.util.prefs", "AbstractPreferences", "nodeExists", "", "manual"] + - ["java.util.prefs", "Preferences", "nodeExists", "", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml b/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml new file mode 100644 index 000000000000..eb92d7b4334e --- /dev/null +++ b/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["org.apache.hc.client5.http.protocol", "RedirectLocations", "contains", "", "manual"] From 60b07083c3b54f5da0c8845d3bea39d6174d7eb1 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Thu, 11 May 2023 17:47:31 -0400 Subject: [PATCH 2/6] Java: add 'sink' kind --- java/ql/lib/ext/java.nio.file.spi.model.yml | 5 +++-- java/ql/lib/ext/java.text.model.yml | 10 ++++++---- java/ql/lib/ext/java.util.prefs.model.yml | 5 +++-- .../ext/org.apache.hc.client5.http.protocol.model.yml | 3 ++- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/java/ql/lib/ext/java.nio.file.spi.model.yml b/java/ql/lib/ext/java.nio.file.spi.model.yml index a833c453eb3f..0a7396a482cf 100644 --- a/java/ql/lib/ext/java.nio.file.spi.model.yml +++ b/java/ql/lib/ext/java.nio.file.spi.model.yml @@ -3,5 +3,6 @@ extensions: pack: codeql/java-all extensible: neutralModel data: - - ["java.nio.file.spi", "FileSystemProvider" "isHidden", "", "manual"] - - ["java.nio.file.spi", "FileSystemProvider" "isSameFile", "", "manual"] + # sink neutrals + - ["java.nio.file.spi", "FileSystemProvider" "isHidden", "", "sink", "manual"] + - ["java.nio.file.spi", "FileSystemProvider" "isSameFile", "", "sink", "manual"] diff --git a/java/ql/lib/ext/java.text.model.yml b/java/ql/lib/ext/java.text.model.yml index 13b286b04387..d4704c2ab976 100644 --- a/java/ql/lib/ext/java.text.model.yml +++ b/java/ql/lib/ext/java.text.model.yml @@ -3,12 +3,14 @@ extensions: pack: codeql/java-all extensible: neutralModel data: - - ["java.text", "Collator" "compare", "", "manual"] - - ["java.text", "Collator" "equals", "", "manual"] - - ["java.text", "RuleBasedCollator", "compare", "", "manual"] - + # summary neutrals # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - ["java.text", "DateFormat", "format", "(Date)", "summary", "manual"] # taint-numeric - ["java.text", "DateFormat", "parse", "(String)", "summary", "manual"] # taint-numeric - ["java.text", "SimpleDateFormat", "SimpleDateFormat", "(String)", "summary", "manual"] # taint-numeric + + # sink neutrals + - ["java.text", "Collator" "compare", "", "sink", "manual"] + - ["java.text", "Collator" "equals", "", "sink", "manual"] + - ["java.text", "RuleBasedCollator", "compare", "", "sink", "manual"] diff --git a/java/ql/lib/ext/java.util.prefs.model.yml b/java/ql/lib/ext/java.util.prefs.model.yml index c27ba79029b2..412730c38074 100644 --- a/java/ql/lib/ext/java.util.prefs.model.yml +++ b/java/ql/lib/ext/java.util.prefs.model.yml @@ -3,5 +3,6 @@ extensions: pack: codeql/java-all extensible: neutralModel data: - - ["java.util.prefs", "AbstractPreferences", "nodeExists", "", "manual"] - - ["java.util.prefs", "Preferences", "nodeExists", "", "manual"] + # sink neutrals + - ["java.util.prefs", "AbstractPreferences", "nodeExists", "", "sink", "manual"] + - ["java.util.prefs", "Preferences", "nodeExists", "", "sink", "manual"] diff --git a/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml b/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml index eb92d7b4334e..eb30b29a50ad 100644 --- a/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml +++ b/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml @@ -3,4 +3,5 @@ extensions: pack: codeql/java-all extensible: neutralModel data: - - ["org.apache.hc.client5.http.protocol", "RedirectLocations", "contains", "", "manual"] + # sink neutrals + - ["org.apache.hc.client5.http.protocol", "RedirectLocations", "contains", "", "sink", "manual"] From 7e6913af620e9d6d7127e8cee67d6e9a31dc6dec Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Thu, 11 May 2023 17:51:53 -0400 Subject: [PATCH 3/6] Java: update provenance to 'hq-manual' --- java/ql/lib/ext/java.io.model.yml | 4 +-- java/ql/lib/ext/java.nio.file.model.yml | 30 +++++++++---------- java/ql/lib/ext/java.nio.file.spi.model.yml | 4 +-- java/ql/lib/ext/java.text.model.yml | 6 ++-- java/ql/lib/ext/java.util.prefs.model.yml | 4 +-- ....apache.hc.client5.http.protocol.model.yml | 2 +- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index e3a48d4138d3..44d079c1474c 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -120,5 +120,5 @@ extensions: - ["java.io", "DataOutput", "writeLong", "(long)", "summary", "manual"] # taint-numeric # sink neutrals - - ["java.io", "File", "compareTo", "", "sink", "manual"] - - ["java.io", "File", "exists", "()", "sink", "manual"] + - ["java.io", "File", "compareTo", "", "sink", "hq-manual"] + - ["java.io", "File", "exists", "()", "sink", "hq-manual"] diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index c178f6289804..243f6a528a13 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -85,18 +85,18 @@ extensions: - ["java.nio.file", "Files", "exists", "(Path,LinkOption[])", "summary", "manual"] # sink neutrals - - ["java.nio.file", "Files" "exists", "", "sink", "manual"] - - ["java.nio.file", "Files" "getLastModifiedTime", "", "sink", "manual"] - - ["java.nio.file", "Files" "getOwner", "", "sink", "manual"] - - ["java.nio.file", "Files" "getPosixFilePermissions", "", "sink", "manual"] - - ["java.nio.file", "Files" "isDirectory", "", "sink", "manual"] - - ["java.nio.file", "Files" "isExecutable", "", "sink", "manual"] - - ["java.nio.file", "Files" "isHidden", "", "sink", "manual"] - - ["java.nio.file", "Files" "isReadable", "", "sink", "manual"] - - ["java.nio.file", "Files" "isRegularFile", "", "sink", "manual"] - - ["java.nio.file", "Files" "isSameFile", "", "sink", "manual"] - - ["java.nio.file", "Files" "isSymbolicLink", "", "sink", "manual"] - - ["java.nio.file", "Files" "isWritable", "", "sink", "manual"] - - ["java.nio.file", "Files" "notExists", "", "sink", "manual"] - - ["java.nio.file", "Files" "setLastModifiedTime", "", "sink", "manual"] - - ["java.nio.file", "Files" "size", "", "sink", "manual"] + - ["java.nio.file", "Files" "exists", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "getLastModifiedTime", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "getOwner", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "getPosixFilePermissions", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isDirectory", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isExecutable", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isHidden", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isReadable", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isRegularFile", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isSameFile", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isSymbolicLink", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "isWritable", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "notExists", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "setLastModifiedTime", "", "sink", "hq-manual"] + - ["java.nio.file", "Files" "size", "", "sink", "hq-manual"] diff --git a/java/ql/lib/ext/java.nio.file.spi.model.yml b/java/ql/lib/ext/java.nio.file.spi.model.yml index 0a7396a482cf..0b6d1d89988e 100644 --- a/java/ql/lib/ext/java.nio.file.spi.model.yml +++ b/java/ql/lib/ext/java.nio.file.spi.model.yml @@ -4,5 +4,5 @@ extensions: extensible: neutralModel data: # sink neutrals - - ["java.nio.file.spi", "FileSystemProvider" "isHidden", "", "sink", "manual"] - - ["java.nio.file.spi", "FileSystemProvider" "isSameFile", "", "sink", "manual"] + - ["java.nio.file.spi", "FileSystemProvider" "isHidden", "", "sink", "hq-manual"] + - ["java.nio.file.spi", "FileSystemProvider" "isSameFile", "", "sink", "hq-manual"] diff --git a/java/ql/lib/ext/java.text.model.yml b/java/ql/lib/ext/java.text.model.yml index d4704c2ab976..02e0eac74074 100644 --- a/java/ql/lib/ext/java.text.model.yml +++ b/java/ql/lib/ext/java.text.model.yml @@ -11,6 +11,6 @@ extensions: - ["java.text", "SimpleDateFormat", "SimpleDateFormat", "(String)", "summary", "manual"] # taint-numeric # sink neutrals - - ["java.text", "Collator" "compare", "", "sink", "manual"] - - ["java.text", "Collator" "equals", "", "sink", "manual"] - - ["java.text", "RuleBasedCollator", "compare", "", "sink", "manual"] + - ["java.text", "Collator" "compare", "", "sink", "hq-manual"] + - ["java.text", "Collator" "equals", "", "sink", "hq-manual"] + - ["java.text", "RuleBasedCollator", "compare", "", "sink", "hq-manual"] diff --git a/java/ql/lib/ext/java.util.prefs.model.yml b/java/ql/lib/ext/java.util.prefs.model.yml index 412730c38074..a2a7c16bc5d0 100644 --- a/java/ql/lib/ext/java.util.prefs.model.yml +++ b/java/ql/lib/ext/java.util.prefs.model.yml @@ -4,5 +4,5 @@ extensions: extensible: neutralModel data: # sink neutrals - - ["java.util.prefs", "AbstractPreferences", "nodeExists", "", "sink", "manual"] - - ["java.util.prefs", "Preferences", "nodeExists", "", "sink", "manual"] + - ["java.util.prefs", "AbstractPreferences", "nodeExists", "", "sink", "hq-manual"] + - ["java.util.prefs", "Preferences", "nodeExists", "", "sink", "hq-manual"] diff --git a/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml b/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml index eb30b29a50ad..b5f46643f2f0 100644 --- a/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml +++ b/java/ql/lib/ext/org.apache.hc.client5.http.protocol.model.yml @@ -4,4 +4,4 @@ extensions: extensible: neutralModel data: # sink neutrals - - ["org.apache.hc.client5.http.protocol", "RedirectLocations", "contains", "", "sink", "manual"] + - ["org.apache.hc.client5.http.protocol", "RedirectLocations", "contains", "", "sink", "hq-manual"] From f255b6acb805a5122bb7bdad47f023a6f557dcfd Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Mon, 22 May 2023 08:55:54 -0400 Subject: [PATCH 4/6] Java: fix typos --- java/ql/lib/ext/java.nio.file.model.yml | 30 ++++++++++----------- java/ql/lib/ext/java.nio.file.spi.model.yml | 4 +-- java/ql/lib/ext/java.text.model.yml | 4 +-- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index 243f6a528a13..6b08117d74fc 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -85,18 +85,18 @@ extensions: - ["java.nio.file", "Files", "exists", "(Path,LinkOption[])", "summary", "manual"] # sink neutrals - - ["java.nio.file", "Files" "exists", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "getLastModifiedTime", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "getOwner", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "getPosixFilePermissions", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isDirectory", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isExecutable", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isHidden", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isReadable", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isRegularFile", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isSameFile", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isSymbolicLink", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "isWritable", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "notExists", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "setLastModifiedTime", "", "sink", "hq-manual"] - - ["java.nio.file", "Files" "size", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "exists", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "getLastModifiedTime", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "getOwner", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "getPosixFilePermissions", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isDirectory", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isExecutable", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isHidden", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isReadable", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isRegularFile", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isSameFile", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isSymbolicLink", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "isWritable", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "notExists", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "setLastModifiedTime", "", "sink", "hq-manual"] + - ["java.nio.file", "Files", "size", "", "sink", "hq-manual"] diff --git a/java/ql/lib/ext/java.nio.file.spi.model.yml b/java/ql/lib/ext/java.nio.file.spi.model.yml index 0b6d1d89988e..91e465af1057 100644 --- a/java/ql/lib/ext/java.nio.file.spi.model.yml +++ b/java/ql/lib/ext/java.nio.file.spi.model.yml @@ -4,5 +4,5 @@ extensions: extensible: neutralModel data: # sink neutrals - - ["java.nio.file.spi", "FileSystemProvider" "isHidden", "", "sink", "hq-manual"] - - ["java.nio.file.spi", "FileSystemProvider" "isSameFile", "", "sink", "hq-manual"] + - ["java.nio.file.spi", "FileSystemProvider", "isHidden", "", "sink", "hq-manual"] + - ["java.nio.file.spi", "FileSystemProvider", "isSameFile", "", "sink", "hq-manual"] diff --git a/java/ql/lib/ext/java.text.model.yml b/java/ql/lib/ext/java.text.model.yml index 02e0eac74074..5b315e9986dd 100644 --- a/java/ql/lib/ext/java.text.model.yml +++ b/java/ql/lib/ext/java.text.model.yml @@ -11,6 +11,6 @@ extensions: - ["java.text", "SimpleDateFormat", "SimpleDateFormat", "(String)", "summary", "manual"] # taint-numeric # sink neutrals - - ["java.text", "Collator" "compare", "", "sink", "hq-manual"] - - ["java.text", "Collator" "equals", "", "sink", "hq-manual"] + - ["java.text", "Collator", "compare", "", "sink", "hq-manual"] + - ["java.text", "Collator", "equals", "", "sink", "hq-manual"] - ["java.text", "RuleBasedCollator", "compare", "", "sink", "hq-manual"] From 24fc4ba2d4e056f9d0838efad8ee76bd0912240f Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Fri, 26 May 2023 18:53:55 -0400 Subject: [PATCH 5/6] Java: add tests --- .../neutralsinks/NeutralSinksTest.expected | 0 .../neutrals/neutralsinks/NeutralSinksTest.ql | 20 ++++ .../neutrals/neutralsinks/Test.java | 61 ++++++++++ .../neutrals/neutralsinks/options | 1 + .../http/protocol/RedirectLocations.java | 111 ++++++++++++++++++ 5 files changed, 193 insertions(+) create mode 100644 java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.expected create mode 100644 java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql create mode 100644 java/ql/test/library-tests/neutrals/neutralsinks/Test.java create mode 100644 java/ql/test/library-tests/neutrals/neutralsinks/options create mode 100644 java/ql/test/stubs/apache-http-5/org/apache/hc/client5/http/protocol/RedirectLocations.java diff --git a/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.expected b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.expected new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql new file mode 100644 index 000000000000..422508f57117 --- /dev/null +++ b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql @@ -0,0 +1,20 @@ +import java +import TestUtilities.InlineExpectationsTest +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.ExternalFlow + +class NeutralSinksTest extends InlineExpectationsTest { + NeutralSinksTest() { this = "NeutralSinksTest" } + + override string getARelevantTag() { result = "isSink" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "isSink" and + exists(DataFlow::Node sink | + sinkNode(sink, _) and + sink.getLocation() = location and + element = sink.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/library-tests/neutrals/neutralsinks/Test.java b/java/ql/test/library-tests/neutrals/neutralsinks/Test.java new file mode 100644 index 000000000000..fee2cbbb7dd9 --- /dev/null +++ b/java/ql/test/library-tests/neutrals/neutralsinks/Test.java @@ -0,0 +1,61 @@ +import java.io.File; +import java.nio.file.Files; +import java.nio.file.spi.FileSystemProvider; +import java.nio.file.LinkOption; +import java.text.Collator; +import java.text.RuleBasedCollator; +import java.util.prefs.AbstractPreferences; +import java.util.prefs.Preferences; +import org.apache.hc.client5.http.protocol.RedirectLocations; + +public class Test { + + public void test() throws Exception { + + // java.io + File file = null; + file.exists(); // Neutral Sink + file.compareTo(null); // Neutral Sink + + // java.nio.file + Files.exists(null, (LinkOption[])null); // Neutral Sink + Files.getLastModifiedTime(null, (LinkOption[])null); // Neutral Sink + Files.getOwner(null, (LinkOption[])null); // Neutral Sink + Files.getPosixFilePermissions(null, (LinkOption[])null); // Neutral Sink + Files.isDirectory(null, (LinkOption[])null); // Neutral Sink + Files.isExecutable(null); // Neutral Sink + Files.isHidden(null); // Neutral Sink + Files.isReadable(null); // Neutral Sink + Files.isRegularFile(null, (LinkOption[])null); // Neutral Sink + Files.isSameFile(null, null); // Neutral Sink + Files.isSymbolicLink(null); // Neutral Sink + Files.isWritable(null); // Neutral Sink + Files.notExists(null, (LinkOption[])null); // Neutral Sink + Files.setLastModifiedTime(null, null); // Neutral Sink + Files.size(null); // Neutral Sink + + // java.nio.file.spi + FileSystemProvider fsp = null; + fsp.isHidden(null); // Neutral Sink + fsp.isSameFile(null, null); // Neutral Sink + + // java.text + Collator c = null; + c.compare(null, null); // Neutral Sink + c.equals(null); // Neutral Sink + c.equals(null, null); // Neutral Sink + RuleBasedCollator rbc = null; + rbc.compare(null, null); // Neutral Sink + + // java.util.prefs + AbstractPreferences ap = null; + ap.nodeExists(null); // Neutral Sink + Preferences p = null; + p.nodeExists(null); // Neutral Sink + + // org.apache.hc.client5.http.protocol + RedirectLocations rl = null; + rl.contains(null); // Neutral Sink + } + +} diff --git a/java/ql/test/library-tests/neutrals/neutralsinks/options b/java/ql/test/library-tests/neutrals/neutralsinks/options new file mode 100644 index 000000000000..6de6bb952855 --- /dev/null +++ b/java/ql/test/library-tests/neutrals/neutralsinks/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -source 11 -target 11 -cp ${testdir}/../../../stubs/apache-http-5 diff --git a/java/ql/test/stubs/apache-http-5/org/apache/hc/client5/http/protocol/RedirectLocations.java b/java/ql/test/stubs/apache-http-5/org/apache/hc/client5/http/protocol/RedirectLocations.java new file mode 100644 index 000000000000..ca717c54ebd4 --- /dev/null +++ b/java/ql/test/stubs/apache-http-5/org/apache/hc/client5/http/protocol/RedirectLocations.java @@ -0,0 +1,111 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + + package org.apache.hc.client5.http.protocol; + + import java.net.URI; + import java.util.ArrayList; + import java.util.HashSet; + import java.util.List; + import java.util.Set; + + /** + * This class represents a collection of {@link java.net.URI}s used + * as redirect locations. + * + * @since 4.0 + */ + public final class RedirectLocations { + + private final Set unique; + private final List all; + + public RedirectLocations() { + super(); + this.unique = new HashSet<>(); + this.all = new ArrayList<>(); + } + + /** + * Test if the URI is present in the collection. + */ + public boolean contains(final URI uri) { + return this.unique.contains(uri); + } + + /** + * Adds a new URI to the collection. + */ + public void add(final URI uri) { + this.unique.add(uri); + this.all.add(uri); + } + + /** + * Returns all redirect {@link URI}s in the order they were added to the collection. + * + * @return list of all URIs + * + * @since 4.1 + */ + public List getAll() { + return new ArrayList<>(this.all); + } + + /** + * Returns the URI at the specified position in this list. + * + * @param index + * index of the location to return + * @return the URI at the specified position in this list + * @throws IndexOutOfBoundsException + * if the index is out of range ( + * {@code index < 0 || index >= size()}) + * @since 4.3 + */ + public URI get(final int index) { + return this.all.get(index); + } + + /** + * Returns the number of elements in this list. If this list contains more + * than {@code Integer.MAX_VALUE} elements, returns + * {@code Integer.MAX_VALUE}. + * + * @return the number of elements in this list + * @since 4.3 + */ + public int size() { + return this.all.size(); + } + + public void clear() { + unique.clear(); + all.clear(); + } + + } From 82f208ca7a113ebd04276a1011ec6336307b6882 Mon Sep 17 00:00:00 2001 From: Jami Cogswell Date: Wed, 31 May 2023 17:47:36 -0400 Subject: [PATCH 6/6] Java: add isNeutralSink test case --- .../neutrals/neutralsinks/NeutralSinksTest.ql | 24 ++++++++- .../neutrals/neutralsinks/Test.java | 52 +++++++++---------- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql index 422508f57117..224b03ea51c3 100644 --- a/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql +++ b/java/ql/test/library-tests/neutrals/neutralsinks/NeutralSinksTest.ql @@ -2,9 +2,10 @@ import java import TestUtilities.InlineExpectationsTest import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.ExternalFlow +import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl -class NeutralSinksTest extends InlineExpectationsTest { - NeutralSinksTest() { this = "NeutralSinksTest" } +class SinkTest extends InlineExpectationsTest { + SinkTest() { this = "SinkTest" } override string getARelevantTag() { result = "isSink" } @@ -18,3 +19,22 @@ class NeutralSinksTest extends InlineExpectationsTest { ) } } + +class NeutralSinkTest extends InlineExpectationsTest { + NeutralSinkTest() { this = "NeutralSinkTest" } + + override string getARelevantTag() { result = "isNeutralSink" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "isNeutralSink" and + exists(Call call, Callable callable | + call.getCallee() = callable and + neutralModel(callable.getDeclaringType().getCompilationUnit().getPackage().getName(), + callable.getDeclaringType().getSourceDeclaration().nestedName(), callable.getName(), + [paramsString(callable), ""], "sink", _) and + call.getLocation() = location and + element = call.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/library-tests/neutrals/neutralsinks/Test.java b/java/ql/test/library-tests/neutrals/neutralsinks/Test.java index fee2cbbb7dd9..a234132226f9 100644 --- a/java/ql/test/library-tests/neutrals/neutralsinks/Test.java +++ b/java/ql/test/library-tests/neutrals/neutralsinks/Test.java @@ -14,48 +14,48 @@ public void test() throws Exception { // java.io File file = null; - file.exists(); // Neutral Sink - file.compareTo(null); // Neutral Sink + file.exists(); // $ isNeutralSink + file.compareTo(null); // $ isNeutralSink // java.nio.file - Files.exists(null, (LinkOption[])null); // Neutral Sink - Files.getLastModifiedTime(null, (LinkOption[])null); // Neutral Sink - Files.getOwner(null, (LinkOption[])null); // Neutral Sink - Files.getPosixFilePermissions(null, (LinkOption[])null); // Neutral Sink - Files.isDirectory(null, (LinkOption[])null); // Neutral Sink - Files.isExecutable(null); // Neutral Sink - Files.isHidden(null); // Neutral Sink - Files.isReadable(null); // Neutral Sink - Files.isRegularFile(null, (LinkOption[])null); // Neutral Sink - Files.isSameFile(null, null); // Neutral Sink - Files.isSymbolicLink(null); // Neutral Sink - Files.isWritable(null); // Neutral Sink - Files.notExists(null, (LinkOption[])null); // Neutral Sink - Files.setLastModifiedTime(null, null); // Neutral Sink - Files.size(null); // Neutral Sink + Files.exists(null, (LinkOption[])null); // $ isNeutralSink + Files.getLastModifiedTime(null, (LinkOption[])null); // $ isNeutralSink + Files.getOwner(null, (LinkOption[])null); // $ isNeutralSink + Files.getPosixFilePermissions(null, (LinkOption[])null); // $ isNeutralSink + Files.isDirectory(null, (LinkOption[])null); // $ isNeutralSink + Files.isExecutable(null); // $ isNeutralSink + Files.isHidden(null); // $ isNeutralSink + Files.isReadable(null); // $ isNeutralSink + Files.isRegularFile(null, (LinkOption[])null); // $ isNeutralSink + Files.isSameFile(null, null); // $ isNeutralSink + Files.isSymbolicLink(null); // $ isNeutralSink + Files.isWritable(null); // $ isNeutralSink + Files.notExists(null, (LinkOption[])null); // $ isNeutralSink + Files.setLastModifiedTime(null, null); // $ isNeutralSink + Files.size(null); // $ isNeutralSink // java.nio.file.spi FileSystemProvider fsp = null; - fsp.isHidden(null); // Neutral Sink - fsp.isSameFile(null, null); // Neutral Sink + fsp.isHidden(null); // $ isNeutralSink + fsp.isSameFile(null, null); // $ isNeutralSink // java.text Collator c = null; - c.compare(null, null); // Neutral Sink - c.equals(null); // Neutral Sink - c.equals(null, null); // Neutral Sink + c.compare(null, null); // $ isNeutralSink + c.equals(null); // $ isNeutralSink + c.equals(null, null); // $ isNeutralSink RuleBasedCollator rbc = null; - rbc.compare(null, null); // Neutral Sink + rbc.compare(null, null); // $ isNeutralSink // java.util.prefs AbstractPreferences ap = null; - ap.nodeExists(null); // Neutral Sink + ap.nodeExists(null); // $ isNeutralSink Preferences p = null; - p.nodeExists(null); // Neutral Sink + p.nodeExists(null); // $ isNeutralSink // org.apache.hc.client5.http.protocol RedirectLocations rl = null; - rl.contains(null); // Neutral Sink + rl.contains(null); // $ isNeutralSink } }