mirror of
https://github.com/github/codeql.git
synced 2026-05-14 19:29:28 +02:00
Introduce a new Models-as-Data sink sub-kind path-injection[read] for models that only read from or inspect a path. The general java/path-injection query and its PathInjectionSanitizer barrier continue to consider both path-injection and path-injection[read] sinks, so no alerts are lost. The java/zipslip query deliberately selects only path-injection sinks, since read-only accesses such as ClassLoader.getResource or FileInputStream are outside the archive extraction threat model. Addresses https://github.com/github/codeql/issues/21606 along the lines proposed on the issue thread: prefer path-injection[read] over a [create] sub-kind so that miscategorizing a sink causes a false positive (easy to spot) rather than a false negative. - shared/mad/codeql/mad/ModelValidation.qll: allow path-injection[...] as a valid sink kind. - java/ql/lib/ext/*.model.yml: relabel the models that PR #12916 migrated from the historical read-file kind (plus the newer ClassLoader resource-lookup variants that share the same read-only semantics). - java/ql/lib/semmle/code/java/security/TaintedPathQuery.qll and PathSanitizer.qll: select both path-injection and path-injection[read] sinks/barriers. - java/ql/lib/semmle/code/java/security/ZipSlipQuery.qll: keep only path-injection, with a comment explaining why path-injection[read] is excluded. - java/ql/test/query-tests/security/CWE-022/semmle/tests/ZipTest.java: add m7 regression covering the Dubbo-style classpath lookup from issue #21606 and assert no alert is produced. - Update TaintedPath.expected for the renamed kinds in the models list. - Add change-notes under java/ql/lib/change-notes and java/ql/src/change-notes.
170 lines
16 KiB
YAML
170 lines
16 KiB
YAML
extensions:
|
|
- addsTo:
|
|
pack: codeql/java-all
|
|
extensible: sinkModel
|
|
data:
|
|
- ["java.io", "File", True, "canExecute", "()", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "File", True, "canRead", "()", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "File", True, "canWrite", "()", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "File", True, "createNewFile", "()", "", "Argument[this]", "path-injection", "ai-manual"]
|
|
- ["java.io", "File", True, "createTempFile", "(String,String,File)", "", "Argument[2]", "path-injection", "ai-manual"]
|
|
- ["java.io", "File", True, "delete", "()", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "File", True, "deleteOnExit", "()", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "File", True, "exists", "()", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "File", True, "isDirectory", "()", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "File", True, "isFile", "()", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "File", True, "isHidden", "()", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "File", True, "mkdir", "()", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "File", True, "mkdirs", "()", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "File", True, "renameTo", "(File)", "", "Argument[0]", "path-injection", "ai-manual"]
|
|
- ["java.io", "File", True, "renameTo", "(File)", "", "Argument[this]", "path-injection", "ai-manual"]
|
|
- ["java.io", "File", True, "setExecutable", "", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "File", True, "setLastModified", "", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "File", True, "setReadable", "", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "File", True, "setReadOnly", "", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "File", True, "setWritable", "", "", "Argument[this]", "path-injection", "manual"]
|
|
- ["java.io", "FileInputStream", True, "FileInputStream", "(File)", "", "Argument[0]", "path-injection[read]", "ai-manual"]
|
|
- ["java.io", "FileInputStream", True, "FileInputStream", "(FileDescriptor)", "", "Argument[0]", "path-injection[read]", "manual"]
|
|
- ["java.io", "FileInputStream", True, "FileInputStream", "(String)", "", "Argument[0]", "path-injection[read]", "ai-manual"]
|
|
- ["java.io", "FileOutputStream", False, "FileOutputStream", "", "", "Argument[0]", "path-injection", "manual"]
|
|
- ["java.io", "FileOutputStream", False, "write", "", "", "Argument[0]", "file-content-store", "manual"]
|
|
- ["java.io", "FileReader", True, "FileReader", "(File)", "", "Argument[0]", "path-injection[read]", "ai-manual"]
|
|
- ["java.io", "FileReader", True, "FileReader", "(FileDescriptor)", "", "Argument[0]", "path-injection[read]", "manual"]
|
|
- ["java.io", "FileReader", True, "FileReader", "(File,Charset)", "", "Argument[0]", "path-injection[read]", "manual"]
|
|
- ["java.io", "FileReader", True, "FileReader", "(String)", "", "Argument[0]", "path-injection[read]", "ai-manual"]
|
|
- ["java.io", "FileReader", True, "FileReader", "(String,Charset)", "", "Argument[0]", "path-injection[read]", "manual"]
|
|
- ["java.io", "FileSystem", True, "createDirectory", "(File)", "", "Argument[0]", "path-injection", "ai-manual"]
|
|
- ["java.io", "FileWriter", False, "FileWriter", "", "", "Argument[0]", "path-injection", "manual"]
|
|
- ["java.io", "PrintStream", False, "PrintStream", "(File)", "", "Argument[0]", "path-injection", "manual"]
|
|
- ["java.io", "PrintStream", False, "PrintStream", "(File,Charset)", "", "Argument[0]", "path-injection", "manual"]
|
|
- ["java.io", "PrintStream", False, "PrintStream", "(File,String)", "", "Argument[0]", "path-injection", "manual"]
|
|
- ["java.io", "PrintStream", False, "PrintStream", "(String)", "", "Argument[0]", "path-injection", "manual"]
|
|
- ["java.io", "PrintStream", False, "PrintStream", "(String,Charset)", "", "Argument[0]", "path-injection", "manual"]
|
|
- ["java.io", "PrintStream", False, "PrintStream", "(String,String)", "", "Argument[0]", "path-injection", "manual"]
|
|
- ["java.io", "PrintStream", True, "append", "", "", "Argument[0]", "file-content-store", "manual"]
|
|
- ["java.io", "PrintStream", True, "format", "(Locale,String,Object[])", "", "Argument[1..2]", "file-content-store", "manual"]
|
|
- ["java.io", "PrintStream", True, "format", "(String,Object[])", "", "Argument[0..1]", "file-content-store", "manual"]
|
|
- ["java.io", "PrintStream", True, "print", "", "", "Argument[0]", "file-content-store", "manual"]
|
|
- ["java.io", "PrintStream", True, "printf", "(Locale,String,Object[])", "", "Argument[1..2]", "file-content-store", "manual"]
|
|
- ["java.io", "PrintStream", True, "printf", "(String,Object[])", "", "Argument[0..1]", "file-content-store", "manual"]
|
|
- ["java.io", "PrintStream", True, "println", "", "", "Argument[0]", "file-content-store", "manual"]
|
|
- ["java.io", "PrintStream", True, "write", "", "", "Argument[0]", "file-content-store", "manual"]
|
|
- ["java.io", "PrintStream", True, "writeBytes", "", "", "Argument[0]", "file-content-store", "manual"]
|
|
- ["java.io", "PrintWriter", False, "PrintWriter", "(File)", "", "Argument[0]", "path-injection", "manual"]
|
|
- ["java.io", "PrintWriter", False, "PrintWriter", "(File,Charset)", "", "Argument[0]", "path-injection", "manual"]
|
|
- ["java.io", "PrintWriter", False, "PrintWriter", "(File,String)", "", "Argument[0]", "path-injection", "manual"]
|
|
- ["java.io", "PrintWriter", False, "PrintWriter", "(String)", "", "Argument[0]", "path-injection", "manual"]
|
|
- ["java.io", "PrintWriter", False, "PrintWriter", "(String,Charset)", "", "Argument[0]", "path-injection", "manual"]
|
|
- ["java.io", "PrintWriter", False, "PrintWriter", "(String,String)", "", "Argument[0]", "path-injection", "manual"]
|
|
- ["java.io", "PrintWriter", False, "format", "(Locale,String,Object[])", "", "Argument[1..2]", "file-content-store", "manual"]
|
|
- ["java.io", "PrintWriter", False, "format", "(String,Object[])", "", "Argument[0..1]", "file-content-store", "manual"]
|
|
- ["java.io", "PrintWriter", False, "print", "", "", "Argument[0]", "file-content-store", "manual"]
|
|
- ["java.io", "PrintWriter", False, "printf", "(Locale,String,Object[])", "", "Argument[1..2]", "file-content-store", "manual"]
|
|
- ["java.io", "PrintWriter", False, "printf", "(String,Object[])", "", "Argument[0..1]", "file-content-store", "manual"]
|
|
- ["java.io", "PrintWriter", False, "println", "", "", "Argument[0]", "file-content-store", "manual"]
|
|
- ["java.io", "RandomAccessFile", False, "RandomAccessFile", "", "", "Argument[0]", "path-injection", "manual"]
|
|
- ["java.io", "RandomAccessFile", False, "write", "", "", "Argument[0]", "file-content-store", "manual"]
|
|
- ["java.io", "RandomAccessFile", False, "writeBytes", "", "", "Argument[0]", "file-content-store", "manual"]
|
|
- ["java.io", "RandomAccessFile", False, "writeChars", "", "", "Argument[0]", "file-content-store", "manual"]
|
|
- ["java.io", "RandomAccessFile", False, "writeUTF", "", "", "Argument[0]", "file-content-store", "manual"]
|
|
- ["java.io", "Writer", True, "append", "", "", "Argument[0]", "file-content-store", "manual"]
|
|
- ["java.io", "Writer", True, "write", "", "", "Argument[0]", "file-content-store", "manual"]
|
|
- addsTo:
|
|
pack: codeql/java-all
|
|
extensible: summaryModel
|
|
data:
|
|
- ["java.io", "BufferedInputStream", False, "BufferedInputStream", "", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "BufferedReader", False, "BufferedReader", "", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "BufferedReader", True, "readLine", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "ByteArrayInputStream", False, "ByteArrayInputStream", "", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "ByteArrayOutputStream", False, "toByteArray", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "ByteArrayOutputStream", False, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "ByteArrayOutputStream", False, "writeTo", "", "", "Argument[this]", "Argument[0]", "taint", "manual"]
|
|
- ["java.io", "CharArrayReader", False, "CharArrayReader", "", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "CharArrayWriter", True, "toCharArray", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "CharArrayWriter", True, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "DataInput", True, "readFully", "", "", "Argument[this]", "Argument[0]", "taint", "manual"]
|
|
- ["java.io", "DataInput", True, "readLine", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "DataInput", True, "readUTF", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "DataInputStream", False, "DataInputStream", "", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "File", False, "File", "", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
# We model this taint step in QL as `FileConstructorChildArgumentStep` in the `PathSanitizer` library
|
|
# since we need to sanitize the use of this argument but not later uses of the same SSA variable,
|
|
# which is not currently possible in Java with a standard sanitizer due to use-use flow.
|
|
# - ["java.io", "File", False, "File", "", "", "Argument[1]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "File", True, "getAbsoluteFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "File", True, "getAbsolutePath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "File", True, "getCanonicalFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "File", True, "getCanonicalPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "File", True, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "File", True, "getParent", "()", "", "Argument[this]", "ReturnValue", "taint", "df-manual"]
|
|
- ["java.io", "File", True, "getParentFile", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "File", True, "getPath", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "File", True, "toPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "File", True, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "File", True, "toURI", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "File", True, "toURL", "()", "", "Argument[this]", "ReturnValue", "taint", "df-manual"]
|
|
- ["java.io", "FileReader", True, "FileReader", "(File)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "FileReader", True, "FileReader", "(File,Charset)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "FileReader", True, "FileReader", "(FileDescriptor)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "FileReader", True, "FileReader", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "FileReader", True, "FileReader", "(String,Charset)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "FilterOutputStream", True, "FilterOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "InputStream", True, "read", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "InputStream", True, "read", "(byte[])", "", "Argument[this]", "Argument[0]", "taint", "manual"]
|
|
- ["java.io", "InputStream", True, "read", "(byte[],int,int)", "", "Argument[this]", "Argument[0]", "taint", "manual"]
|
|
- ["java.io", "InputStream", True, "readAllBytes", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "InputStream", True, "readNBytes", "(byte[],int,int)", "", "Argument[this]", "Argument[0]", "taint", "manual"]
|
|
- ["java.io", "InputStream", True, "readNBytes", "(int)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "InputStream", True, "transferTo", "(OutputStream)", "", "Argument[this]", "Argument[0]", "taint", "manual"]
|
|
- ["java.io", "InputStreamReader", False, "InputStreamReader", "", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "IOException", False, "IOException", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"]
|
|
- ["java.io", "ObjectInput", True, "read", "", "", "Argument[this]", "Argument[0]", "taint", "manual"]
|
|
- ["java.io", "ObjectInputStream", False, "ObjectInputStream", "", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "OutputStream", True, "write", "(byte[])", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "OutputStream", True, "write", "(byte[],int,int)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "OutputStream", True, "write", "(int)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "Reader", True, "read", "", "", "Argument[this]", "Argument[0]", "taint", "manual"]
|
|
- ["java.io", "StringReader", False, "StringReader", "", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- ["java.io", "StringWriter", False, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
|
- ["java.io", "UncheckedIOException", False, "UncheckedIOException", "(IOException)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "value", "manual"]
|
|
- ["java.io", "Writer", True, "write", "", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
|
- addsTo:
|
|
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"]
|
|
- ["java.io", "File", "exists", "()", "summary", "manual"]
|
|
- ["java.io", "File", "isFile", "()", "summary", "manual"]
|
|
- ["java.io", "File", "length", "()", "summary", "manual"]
|
|
- ["java.io", "File", "isDirectory", "()", "summary", "manual"]
|
|
- ["java.io", "File", "listFiles", "", "summary", "df-manual"]
|
|
- ["java.io", "File", "mkdirs", "()", "summary", "manual"]
|
|
- ["java.io", "FileInputStream", "FileInputStream", "(File)", "summary", "manual"]
|
|
- ["java.io", "FileInputStream", "FileInputStream", "(FileDescriptor)", "summary", "df-manual"]
|
|
- ["java.io", "FileInputStream", "FileInputStream", "(String)", "summary", "df-manual"]
|
|
- ["java.io", "InputStream", "close", "()", "summary", "manual"]
|
|
- ["java.io", "ObjectInput", "readObject", "()", "summary", "df-manual"] # this is a deserialization sink modeled in regular CodeQL
|
|
- ["java.io", "OutputStream", "flush", "()", "summary", "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.io", "DataInput", "readInt", "()", "summary", "manual"] # taint-numeric
|
|
- ["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", "hq-manual"]
|
|
- addsTo:
|
|
pack: codeql/java-all
|
|
extensible: sourceModel
|
|
data:
|
|
- ["java.io", "FileInputStream", True, "FileInputStream", "", "", "Argument[this]", "file", "manual"]
|
|
- addsTo:
|
|
pack: codeql/java-all
|
|
extensible: barrierModel
|
|
data:
|
|
- ["java.io", "File", True, "getName", "()", "", "ReturnValue", "path-injection", "manual"]
|