mirror of
https://github.com/github/codeql.git
synced 2026-07-13 15:28:16 +02:00
Merge branch 'main' into java/experimental/command-injection
This commit is contained in:
@@ -56,8 +56,8 @@ jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,94,55
|
||||
java.awt,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3
|
||||
java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
java.io,49,,45,,,22,,,,,,,,,,,,,,27,,,,,,,,,,,,,,,,,,,43,2
|
||||
java.lang,18,,92,,,,,,,,,,,,,,8,,,5,,,4,,,1,,,,,,,,,,,,,56,36
|
||||
java.net,13,3,20,,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,3,20,
|
||||
java.lang,31,,92,,13,,,,,,,,,,,,8,,,5,,,4,,,1,,,,,,,,,,,,,56,36
|
||||
java.net,13,3,21,,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,3,21,
|
||||
java.nio,47,,35,,,3,,,,,,,,,,,,,,44,,,,,,,,,,,,,,,,,,,35,
|
||||
java.sql,13,,2,,,,,,,,,,,,,,,,,,,,,,,,,,4,,9,,,,,,,,2,
|
||||
java.util,44,,484,,,,,,,,,,,,,,34,,,,,,,5,2,,1,2,,,,,,,,,,,44,440
|
||||
@@ -90,11 +90,13 @@ org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,
|
||||
org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783
|
||||
org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783
|
||||
org.apache.commons.compress.archivers.tar,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,
|
||||
org.apache.commons.exec,6,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.commons.httpclient.util,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
org.apache.commons.io,111,,560,,,2,,,,,,,,,,,,,,94,,,,,,,,,15,,,,,,,,,,546,14
|
||||
org.apache.commons.jelly,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,
|
||||
org.apache.commons.jexl2,15,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.commons.jexl3,15,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.commons.lang,,,765,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,594,171
|
||||
org.apache.commons.lang3,6,,424,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,293,131
|
||||
org.apache.commons.logging,6,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.commons.net,9,12,,,,,,,,,,,,,,,,,,3,,,,,,,,,6,,,,,,,,,12,,
|
||||
@@ -136,7 +138,7 @@ org.jenkins.ui.icon,,,42,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,41,1
|
||||
org.jenkins.ui.symbol,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,8
|
||||
org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,
|
||||
org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38
|
||||
org.kohsuke.stapler,3,,343,,,,,,,,,,,,,,,,,1,,,,,,,,,1,,,,1,,,,,,332,11
|
||||
org.kohsuke.stapler,20,24,343,,,,,,,2,,,,,,,,,,9,,,,,,,,,4,,,,5,,,,,24,332,11
|
||||
org.mvel2,16,,,,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.openjdk.jmh.runner.options,1,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,
|
||||
org.scijava.log,13,,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,,
|
||||
|
||||
|
@@ -18,10 +18,10 @@ Java framework & library support
|
||||
`Google Guava <https://guava.dev/>`_,``com.google.common.*``,,730,41,7,,,,,
|
||||
JBoss Logging,``org.jboss.logging``,,,324,,,,,,
|
||||
`JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,,
|
||||
Java Standard Library,``java.*``,3,682,184,76,,9,,,17
|
||||
Java Standard Library,``java.*``,3,683,197,76,,9,,,17
|
||||
Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,2,4,,1,1,2
|
||||
Kotlin Standard Library,``kotlin*``,,1847,16,14,,,,,2
|
||||
`Spring <https://spring.io/>`_,``org.springframework.*``,29,483,115,4,,28,14,,35
|
||||
Others,"``antlr``, ``cn.hutool.core.codec``, ``com.alibaba.druid.sql``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jenkins``, ``jodd.json``, ``net.sf.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.acegisecurity``, ``org.antlr.runtime``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.influxdb``, ``org.jdbi.v3.core``, ``org.jenkins.ui.icon``, ``org.jenkins.ui.symbol``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``org.yaml.snakeyaml``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",102,4467,554,81,4,18,18,,197
|
||||
Totals,,259,12766,2023,278,14,122,33,1,387
|
||||
Others,"``antlr``, ``cn.hutool.core.codec``, ``com.alibaba.druid.sql``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jenkins``, ``jodd.json``, ``net.sf.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.acegisecurity``, ``org.antlr.runtime``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.exec``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.lang``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.influxdb``, ``org.jdbi.v3.core``, ``org.jenkins.ui.icon``, ``org.jenkins.ui.symbol``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``org.yaml.snakeyaml``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",126,5232,577,89,6,18,18,,200
|
||||
Totals,,283,13532,2059,286,16,122,33,1,390
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Remove ENUM_ENTRIES
|
||||
compatibility: full
|
||||
@@ -2,3 +2,4 @@ name: codeql/java-downgrades
|
||||
groups: java
|
||||
downgrades: .
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -133,30 +133,6 @@ def find_sources(path):
|
||||
return glob.glob(path + '/**/*.kt', recursive=True) + glob.glob(path + '/**/*.java', recursive=True)
|
||||
|
||||
|
||||
def get_kotlin_lib_folder():
|
||||
x = run_process([kotlinc, '-version', '-verbose'], capture_output=True)
|
||||
output = x.stderr.decode(encoding='UTF-8', errors='strict')
|
||||
m = re.match(
|
||||
r'.*\nlogging: using Kotlin home directory ([^\n]+)\n.*', output)
|
||||
if m is None:
|
||||
raise Exception('Cannot determine kotlinc home directory')
|
||||
kotlin_home = m.group(1)
|
||||
print("Kotlin home directory: " + kotlin_home)
|
||||
return kotlin_home + '/lib'
|
||||
|
||||
|
||||
def get_gradle_lib_folder():
|
||||
x = run_process(['gradle', 'getHomeDir'], capture_output=True)
|
||||
output = x.stdout.decode(encoding='UTF-8', errors='strict')
|
||||
m = re.search(r'(?m)^> Task :getHomeDir\n([^\n]+)$', output)
|
||||
if m is None:
|
||||
print("gradle getHomeDir output:\n" + output, file=sys.stderr)
|
||||
raise Exception('Cannot determine gradle home directory')
|
||||
gradle_home = m.group(1)
|
||||
print("Gradle home directory: " + gradle_home)
|
||||
return gradle_home + '/lib'
|
||||
|
||||
|
||||
def find_jar(path, base):
|
||||
fn = path + '/' + base + '.jar'
|
||||
if not os.path.isfile(fn):
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.util.ArrayList
|
||||
import java.util.HashSet
|
||||
import java.util.zip.GZIPOutputStream
|
||||
|
||||
class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: String, val sourceFilePath: String, val primitiveTypeMapping: PrimitiveTypeMapping, val pluginContext: IrPluginContext, val globalExtensionState: KotlinExtractorGlobalState, val diagnosticTrapWriter: TrapWriter) {
|
||||
class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: String, val sourceFilePath: String, val primitiveTypeMapping: PrimitiveTypeMapping, val pluginContext: IrPluginContext, val globalExtensionState: KotlinExtractorGlobalState, val diagnosticTrapWriter: DiagnosticTrapWriter) {
|
||||
|
||||
val declBinaryNames = HashMap<IrDeclaration, String>()
|
||||
val externalDeclsDone = HashSet<Pair<String, String>>()
|
||||
@@ -95,8 +95,8 @@ class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: Stri
|
||||
val binaryPath = getIrClassBinaryPath(containingClass)
|
||||
|
||||
// We want our comments to be the first thing in the file,
|
||||
// so start off with a mere TrapWriter
|
||||
val tw = TrapWriter(logger.loggerBase, TrapLabelManager(), trapFileBW, diagnosticTrapWriter)
|
||||
// so start off with a PlainTrapWriter
|
||||
val tw = PlainTrapWriter(logger.loggerBase, TrapLabelManager(), trapFileBW, diagnosticTrapWriter)
|
||||
tw.writeComment("Generated by the CodeQL Kotlin extractor for external dependencies")
|
||||
tw.writeComment("Part of invocation $invocationTrapFile")
|
||||
if (signature != possiblyLongSignature) {
|
||||
|
||||
@@ -127,7 +127,7 @@ class KotlinExtractorExtension(
|
||||
val lm = TrapLabelManager()
|
||||
val logCounter = LogCounter()
|
||||
val loggerBase = LoggerBase(logCounter)
|
||||
val tw = TrapWriter(loggerBase, lm, invocationTrapFileBW, null)
|
||||
val tw = DiagnosticTrapWriter(loggerBase, lm, invocationTrapFileBW)
|
||||
// The interceptor has already defined #compilation = *
|
||||
val compilation: Label<DbCompilation> = StringLabel("compilation")
|
||||
tw.writeCompilation_started(compilation)
|
||||
@@ -324,13 +324,13 @@ private fun doFile(
|
||||
trapFileWriter.getTempWriter().use { trapFileBW ->
|
||||
// We want our comments to be the first thing in the file,
|
||||
// so start off with a mere TrapWriter
|
||||
val tw = TrapWriter(loggerBase, TrapLabelManager(), trapFileBW, fileTrapWriter)
|
||||
val tw = PlainTrapWriter(loggerBase, TrapLabelManager(), trapFileBW, fileTrapWriter.getDiagnosticTrapWriter())
|
||||
tw.writeComment("Generated by the CodeQL Kotlin extractor for kotlin source code")
|
||||
tw.writeComment("Part of invocation $invocationTrapFile")
|
||||
// Now elevate to a SourceFileTrapWriter, and populate the
|
||||
// file information
|
||||
val sftw = tw.makeSourceFileTrapWriter(srcFile, true)
|
||||
val externalDeclExtractor = ExternalDeclExtractor(logger, invocationTrapFile, srcFilePath, primitiveTypeMapping, pluginContext, globalExtensionState, fileTrapWriter)
|
||||
val externalDeclExtractor = ExternalDeclExtractor(logger, invocationTrapFile, srcFilePath, primitiveTypeMapping, pluginContext, globalExtensionState, fileTrapWriter.getDiagnosticTrapWriter())
|
||||
val linesOfCode = LinesOfCode(logger, sftw, srcFile)
|
||||
val fileExtractor = KotlinFileExtractor(logger, sftw, linesOfCode, srcFilePath, null, externalDeclExtractor, primitiveTypeMapping, pluginContext, KotlinFileExtractor.DeclarationStack(), globalExtensionState)
|
||||
|
||||
|
||||
@@ -157,21 +157,10 @@ open class KotlinFileExtractor(
|
||||
else -> false
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
private fun isFake(d: IrDeclarationWithVisibility): Boolean {
|
||||
val hasFakeVisibility = d.visibility.let { it is DelegatedDescriptorVisibility && it.delegate == Visibilities.InvisibleFake } || d.isFakeOverride
|
||||
if (hasFakeVisibility && !isJavaBinaryObjectMethodRedeclaration(d))
|
||||
return true
|
||||
try {
|
||||
if ((d as? IrFunction)?.descriptor?.isHiddenToOvercomeSignatureClash == true) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
catch (e: NotImplementedError) {
|
||||
// `org.jetbrains.kotlin.ir.descriptors.IrBasedClassConstructorDescriptor.isHiddenToOvercomeSignatureClash` throws the exception
|
||||
logger.warnElement("Couldn't query if element is fake, deciding it's not.", d, e)
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1559,7 +1548,7 @@ open class KotlinFileExtractor(
|
||||
val setter = p.setter
|
||||
|
||||
if (getter == null) {
|
||||
if (p.modality != Modality.FINAL || !isExternalDeclaration(p)) {
|
||||
if (!isExternalDeclaration(p)) {
|
||||
logger.warnElement("IrProperty without a getter", p)
|
||||
}
|
||||
} else if (shouldExtractDecl(getter, extractPrivateMembers)) {
|
||||
@@ -1701,12 +1690,13 @@ open class KotlinFileExtractor(
|
||||
|
||||
private fun extractSyntheticBody(b: IrSyntheticBody, callable: Label<out DbCallable>) {
|
||||
with("synthetic body", b) {
|
||||
when (b.kind) {
|
||||
IrSyntheticBodyKind.ENUM_VALUES -> tw.writeKtSyntheticBody(callable, 1)
|
||||
IrSyntheticBodyKind.ENUM_VALUEOF -> tw.writeKtSyntheticBody(callable, 2)
|
||||
val kind = b.kind
|
||||
when {
|
||||
kind == IrSyntheticBodyKind.ENUM_VALUES -> tw.writeKtSyntheticBody(callable, 1)
|
||||
kind == IrSyntheticBodyKind.ENUM_VALUEOF -> tw.writeKtSyntheticBody(callable, 2)
|
||||
kind == kind_ENUM_ENTRIES -> tw.writeKtSyntheticBody(callable, 3)
|
||||
else -> {
|
||||
// TODO: Support IrSyntheticBodyKind.ENUM_ENTRIES
|
||||
logger.errorElement("Unhandled synthetic body kind " + b.kind.javaClass, b)
|
||||
logger.errorElement("Unhandled synthetic body kind " + kind, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5316,7 +5306,10 @@ open class KotlinFileExtractor(
|
||||
private fun extractTypeAccessRecursive(t: IrType, location: Label<out DbLocation>, parent: Label<out DbExprparent>, idx: Int, typeContext: TypeContext = TypeContext.OTHER): Label<out DbExpr> {
|
||||
val typeAccessId = extractTypeAccess(useType(t, typeContext), location, parent, idx)
|
||||
if (t is IrSimpleType) {
|
||||
t.arguments.forEachIndexed { argIdx, arg ->
|
||||
// From 1.9, the list might change when we call erase,
|
||||
// so we make a copy that it is safe to iterate over.
|
||||
val argumentsCopy = t.arguments.toList()
|
||||
argumentsCopy.forEachIndexed { argIdx, arg ->
|
||||
extractWildcardTypeAccessRecursive(arg, location, typeAccessId, argIdx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,13 +139,13 @@ open class KotlinUsesExtractor(
|
||||
if (clsFile == null || isExternalDeclaration(cls)) {
|
||||
val filePath = getIrClassBinaryPath(cls)
|
||||
val newTrapWriter = tw.makeFileTrapWriter(filePath, true)
|
||||
val newLoggerTrapWriter = logger.tw.makeFileTrapWriter(filePath, false)
|
||||
val newLoggerTrapWriter = logger.dtw.makeFileTrapWriter(filePath, false)
|
||||
val newLogger = FileLogger(logger.loggerBase, newLoggerTrapWriter)
|
||||
return KotlinFileExtractor(newLogger, newTrapWriter, null, filePath, dependencyCollector, externalClassExtractor, primitiveTypeMapping, pluginContext, newDeclarationStack, globalExtensionState)
|
||||
}
|
||||
|
||||
val newTrapWriter = tw.makeSourceFileTrapWriter(clsFile, true)
|
||||
val newLoggerTrapWriter = logger.tw.makeSourceFileTrapWriter(clsFile, false)
|
||||
val newLoggerTrapWriter = logger.dtw.makeSourceFileTrapWriter(clsFile, false)
|
||||
val newLogger = FileLogger(logger.loggerBase, newLoggerTrapWriter)
|
||||
return KotlinFileExtractor(newLogger, newTrapWriter, null, clsFile.path, dependencyCollector, externalClassExtractor, primitiveTypeMapping, pluginContext, newDeclarationStack, globalExtensionState)
|
||||
}
|
||||
|
||||
@@ -57,7 +57,9 @@ class TrapLabelManager {
|
||||
* share the same `TrapLabelManager` and `BufferedWriter`.
|
||||
*/
|
||||
// TODO lm was `protected` before anonymousTypeMapping and locallyVisibleFunctionLabelMapping moved into it. Should we re-protect it and provide accessors?
|
||||
open class TrapWriter (protected val loggerBase: LoggerBase, val lm: TrapLabelManager, private val bw: BufferedWriter, val diagnosticTrapWriter: TrapWriter?) {
|
||||
abstract class TrapWriter (protected val loggerBase: LoggerBase, val lm: TrapLabelManager, private val bw: BufferedWriter) {
|
||||
abstract fun getDiagnosticTrapWriter(): DiagnosticTrapWriter
|
||||
|
||||
/**
|
||||
* Returns the label that is defined to be the given key, if such
|
||||
* a label exists, and `null` otherwise. Most users will want to use
|
||||
@@ -223,7 +225,7 @@ open class TrapWriter (protected val loggerBase: LoggerBase, val lm: TrapLabelMa
|
||||
val len = str.length
|
||||
val newLen = UTF8Util.encodablePrefixLength(str, MAX_STRLEN)
|
||||
if (newLen < len) {
|
||||
loggerBase.warn(diagnosticTrapWriter ?: this,
|
||||
loggerBase.warn(this.getDiagnosticTrapWriter(),
|
||||
"Truncated string of length $len",
|
||||
"Truncated string of length $len, starting '${str.take(100)}', ending '${str.takeLast(100)}'")
|
||||
return str.take(newLen)
|
||||
@@ -237,14 +239,43 @@ open class TrapWriter (protected val loggerBase: LoggerBase, val lm: TrapLabelMa
|
||||
* writer etc), but using the given `filePath` for locations.
|
||||
*/
|
||||
fun makeFileTrapWriter(filePath: String, populateFileTables: Boolean) =
|
||||
FileTrapWriter(loggerBase, lm, bw, diagnosticTrapWriter, filePath, populateFileTables)
|
||||
FileTrapWriter(loggerBase, lm, bw, this.getDiagnosticTrapWriter(), filePath, populateFileTables)
|
||||
|
||||
/**
|
||||
* Gets a FileTrapWriter like this one (using the same label manager,
|
||||
* writer etc), but using the given `IrFile` for locations.
|
||||
*/
|
||||
fun makeSourceFileTrapWriter(file: IrFile, populateFileTables: Boolean) =
|
||||
SourceFileTrapWriter(loggerBase, lm, bw, diagnosticTrapWriter, file, populateFileTables)
|
||||
SourceFileTrapWriter(loggerBase, lm, bw, this.getDiagnosticTrapWriter(), file, populateFileTables)
|
||||
}
|
||||
|
||||
/**
|
||||
* A `PlainTrapWriter` has no additional context of its own.
|
||||
*/
|
||||
class PlainTrapWriter (
|
||||
loggerBase: LoggerBase,
|
||||
lm: TrapLabelManager,
|
||||
bw: BufferedWriter,
|
||||
val dtw: DiagnosticTrapWriter
|
||||
): TrapWriter (loggerBase, lm, bw) {
|
||||
override fun getDiagnosticTrapWriter(): DiagnosticTrapWriter {
|
||||
return dtw
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A `DiagnosticTrapWriter` is a TrapWriter that diagnostics can be
|
||||
* written to; i.e. it has the #compilation label defined. In practice,
|
||||
* this means that it is a TrapWriter for the invocation TRAP file.
|
||||
*/
|
||||
class DiagnosticTrapWriter (
|
||||
loggerBase: LoggerBase,
|
||||
lm: TrapLabelManager,
|
||||
bw: BufferedWriter
|
||||
): TrapWriter (loggerBase, lm, bw) {
|
||||
override fun getDiagnosticTrapWriter(): DiagnosticTrapWriter {
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,16 +290,20 @@ open class FileTrapWriter (
|
||||
loggerBase: LoggerBase,
|
||||
lm: TrapLabelManager,
|
||||
bw: BufferedWriter,
|
||||
diagnosticTrapWriter: TrapWriter?,
|
||||
val dtw: DiagnosticTrapWriter,
|
||||
val filePath: String,
|
||||
populateFileTables: Boolean
|
||||
): TrapWriter (loggerBase, lm, bw, diagnosticTrapWriter) {
|
||||
): TrapWriter (loggerBase, lm, bw) {
|
||||
|
||||
/**
|
||||
* The ID for the file that we are extracting from.
|
||||
*/
|
||||
val fileId = mkFileId(filePath, populateFileTables)
|
||||
|
||||
override fun getDiagnosticTrapWriter(): DiagnosticTrapWriter {
|
||||
return dtw
|
||||
}
|
||||
|
||||
private fun offsetMinOf(default: Int, vararg options: Int?): Int {
|
||||
if (default == UNDEFINED_OFFSET || default == SYNTHETIC_OFFSET) {
|
||||
return default
|
||||
@@ -349,10 +384,10 @@ class SourceFileTrapWriter (
|
||||
loggerBase: LoggerBase,
|
||||
lm: TrapLabelManager,
|
||||
bw: BufferedWriter,
|
||||
diagnosticTrapWriter: TrapWriter?,
|
||||
dtw: DiagnosticTrapWriter,
|
||||
val irFile: IrFile,
|
||||
populateFileTables: Boolean) :
|
||||
FileTrapWriter(loggerBase, lm, bw, diagnosticTrapWriter, irFile.path, populateFileTables) {
|
||||
FileTrapWriter(loggerBase, lm, bw, dtw, irFile.path, populateFileTables) {
|
||||
|
||||
/**
|
||||
* The file entry for the file that we are extracting from.
|
||||
@@ -363,14 +398,14 @@ class SourceFileTrapWriter (
|
||||
override fun getLocation(startOffset: Int, endOffset: Int): Label<DbLocation> {
|
||||
if (startOffset == UNDEFINED_OFFSET || endOffset == UNDEFINED_OFFSET) {
|
||||
if (startOffset != endOffset) {
|
||||
loggerBase.warn(this, "Location with inconsistent offsets (start $startOffset, end $endOffset)", null)
|
||||
loggerBase.warn(dtw, "Location with inconsistent offsets (start $startOffset, end $endOffset)", null)
|
||||
}
|
||||
return getWholeFileLocation()
|
||||
}
|
||||
|
||||
if (startOffset == SYNTHETIC_OFFSET || endOffset == SYNTHETIC_OFFSET) {
|
||||
if (startOffset != endOffset) {
|
||||
loggerBase.warn(this, "Location with inconsistent offsets (start $startOffset, end $endOffset)", null)
|
||||
loggerBase.warn(dtw, "Location with inconsistent offsets (start $startOffset, end $endOffset)", null)
|
||||
}
|
||||
return getWholeFileLocation()
|
||||
}
|
||||
@@ -390,14 +425,14 @@ class SourceFileTrapWriter (
|
||||
override fun getLocationString(e: IrElement): String {
|
||||
if (e.startOffset == UNDEFINED_OFFSET || e.endOffset == UNDEFINED_OFFSET) {
|
||||
if (e.startOffset != e.endOffset) {
|
||||
loggerBase.warn(this, "Location with inconsistent offsets (start ${e.startOffset}, end ${e.endOffset})", null)
|
||||
loggerBase.warn(dtw, "Location with inconsistent offsets (start ${e.startOffset}, end ${e.endOffset})", null)
|
||||
}
|
||||
return "<unknown location while processing $filePath>"
|
||||
}
|
||||
|
||||
if (e.startOffset == SYNTHETIC_OFFSET || e.endOffset == SYNTHETIC_OFFSET) {
|
||||
if (e.startOffset != e.endOffset) {
|
||||
loggerBase.warn(this, "Location with inconsistent offsets (start ${e.startOffset}, end ${e.endOffset})", null)
|
||||
loggerBase.warn(dtw, "Location with inconsistent offsets (start ${e.startOffset}, end ${e.endOffset})", null)
|
||||
}
|
||||
return "<synthetic location while processing $filePath>"
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ open class LoggerBase(val logCounter: LogCounter) {
|
||||
file_number_diagnostic_number = 0
|
||||
}
|
||||
|
||||
fun diagnostic(tw: TrapWriter, severity: Severity, msg: String, extraInfo: String?, locationString: String? = null, mkLocationId: () -> Label<DbLocation> = { tw.unknownLocation }) {
|
||||
fun diagnostic(dtw: DiagnosticTrapWriter, severity: Severity, msg: String, extraInfo: String?, locationString: String? = null, mkLocationId: () -> Label<DbLocation> = { dtw.unknownLocation }) {
|
||||
val diagnosticLoc = getDiagnosticLocation()
|
||||
val diagnosticLocStr = if(diagnosticLoc == null) "<unknown location>" else diagnosticLoc
|
||||
val suffix =
|
||||
@@ -121,7 +121,7 @@ open class LoggerBase(val logCounter: LogCounter) {
|
||||
// counting machinery
|
||||
if (verbosity >= 1) {
|
||||
val message = "Severity mismatch ($severity vs ${oldInfo.first}) at $diagnosticLoc"
|
||||
emitDiagnostic(tw, Severity.Error, "Inconsistency", message, message)
|
||||
emitDiagnostic(dtw, Severity.Error, "Inconsistency", message, message)
|
||||
}
|
||||
}
|
||||
val newCount = oldInfo.second + 1
|
||||
@@ -149,18 +149,18 @@ open class LoggerBase(val logCounter: LogCounter) {
|
||||
fullMsgBuilder.append(suffix)
|
||||
|
||||
val fullMsg = fullMsgBuilder.toString()
|
||||
emitDiagnostic(tw, severity, diagnosticLocStr, msg, fullMsg, locationString, mkLocationId)
|
||||
emitDiagnostic(dtw, severity, diagnosticLocStr, msg, fullMsg, locationString, mkLocationId)
|
||||
}
|
||||
|
||||
private fun emitDiagnostic(tw: TrapWriter, severity: Severity, diagnosticLocStr: String, msg: String, fullMsg: String, locationString: String? = null, mkLocationId: () -> Label<DbLocation> = { tw.unknownLocation }) {
|
||||
private fun emitDiagnostic(dtw: DiagnosticTrapWriter, severity: Severity, diagnosticLocStr: String, msg: String, fullMsg: String, locationString: String? = null, mkLocationId: () -> Label<DbLocation> = { dtw.unknownLocation }) {
|
||||
val locStr = if (locationString == null) "" else "At " + locationString + ": "
|
||||
val kind = if (severity <= Severity.WarnHigh) "WARN" else "ERROR"
|
||||
val logMessage = LogMessage(kind, "Diagnostic($diagnosticLocStr): $locStr$fullMsg")
|
||||
// We don't actually make the location until after the `return` above
|
||||
val locationId = mkLocationId()
|
||||
val diagLabel = tw.getFreshIdLabel<DbDiagnostic>()
|
||||
tw.writeDiagnostics(diagLabel, "CodeQL Kotlin extractor", severity.sev, "", msg, "${logMessage.timestamp} $fullMsg", locationId)
|
||||
tw.writeDiagnostic_for(diagLabel, StringLabel("compilation"), file_number, file_number_diagnostic_number++)
|
||||
val diagLabel = dtw.getFreshIdLabel<DbDiagnostic>()
|
||||
dtw.writeDiagnostics(diagLabel, "CodeQL Kotlin extractor", severity.sev, "", msg, "${logMessage.timestamp} $fullMsg", locationId)
|
||||
dtw.writeDiagnostic_for(diagLabel, StringLabel("compilation"), file_number, file_number_diagnostic_number++)
|
||||
logStream.write(logMessage.toJsonLine())
|
||||
}
|
||||
|
||||
@@ -188,28 +188,25 @@ open class LoggerBase(val logCounter: LogCounter) {
|
||||
}
|
||||
}
|
||||
|
||||
fun warn(tw: TrapWriter, msg: String, extraInfo: String?) {
|
||||
fun warn(dtw: DiagnosticTrapWriter, msg: String, extraInfo: String?) {
|
||||
if (verbosity >= 2) {
|
||||
diagnostic(tw, Severity.Warn, msg, extraInfo)
|
||||
diagnostic(dtw, Severity.Warn, msg, extraInfo)
|
||||
}
|
||||
}
|
||||
fun error(tw: TrapWriter, msg: String, extraInfo: String?) {
|
||||
fun error(dtw: DiagnosticTrapWriter, msg: String, extraInfo: String?) {
|
||||
if (verbosity >= 1) {
|
||||
diagnostic(tw, Severity.Error, msg, extraInfo)
|
||||
diagnostic(dtw, Severity.Error, msg, extraInfo)
|
||||
}
|
||||
}
|
||||
|
||||
fun printLimitedDiagnosticCounts(tw: TrapWriter) {
|
||||
fun printLimitedDiagnosticCounts(dtw: DiagnosticTrapWriter) {
|
||||
for((caller, info) in logCounter.diagnosticInfo) {
|
||||
val severity = info.first
|
||||
val count = info.second
|
||||
if(count >= logCounter.diagnosticLimit) {
|
||||
// We don't know if this location relates to an error
|
||||
// or a warning, so we just declare hitting the limit
|
||||
// to be an error regardless.
|
||||
val message = "Total of $count diagnostics (reached limit of ${logCounter.diagnosticLimit}) from $caller."
|
||||
if (verbosity >= 1) {
|
||||
emitDiagnostic(tw, severity, "Limit", message, message)
|
||||
emitDiagnostic(dtw, severity, "Limit", message, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,28 +221,28 @@ open class LoggerBase(val logCounter: LogCounter) {
|
||||
}
|
||||
}
|
||||
|
||||
open class Logger(val loggerBase: LoggerBase, open val tw: TrapWriter) {
|
||||
open class Logger(val loggerBase: LoggerBase, open val dtw: DiagnosticTrapWriter) {
|
||||
fun flush() {
|
||||
tw.flush()
|
||||
dtw.flush()
|
||||
loggerBase.flush()
|
||||
}
|
||||
|
||||
fun trace(msg: String) {
|
||||
loggerBase.trace(tw, msg)
|
||||
loggerBase.trace(dtw, msg)
|
||||
}
|
||||
fun trace(msg: String, exn: Throwable) {
|
||||
trace(msg + "\n" + exn.stackTraceToString())
|
||||
}
|
||||
fun debug(msg: String) {
|
||||
loggerBase.debug(tw, msg)
|
||||
loggerBase.debug(dtw, msg)
|
||||
}
|
||||
|
||||
fun info(msg: String) {
|
||||
loggerBase.info(tw, msg)
|
||||
loggerBase.info(dtw, msg)
|
||||
}
|
||||
|
||||
private fun warn(msg: String, extraInfo: String?) {
|
||||
loggerBase.warn(tw, msg, extraInfo)
|
||||
loggerBase.warn(dtw, msg, extraInfo)
|
||||
}
|
||||
fun warn(msg: String, exn: Throwable) {
|
||||
warn(msg, exn.stackTraceToString())
|
||||
@@ -255,7 +252,7 @@ open class Logger(val loggerBase: LoggerBase, open val tw: TrapWriter) {
|
||||
}
|
||||
|
||||
private fun error(msg: String, extraInfo: String?) {
|
||||
loggerBase.error(tw, msg, extraInfo)
|
||||
loggerBase.error(dtw, msg, extraInfo)
|
||||
}
|
||||
fun error(msg: String) {
|
||||
error(msg, null)
|
||||
@@ -265,16 +262,16 @@ open class Logger(val loggerBase: LoggerBase, open val tw: TrapWriter) {
|
||||
}
|
||||
}
|
||||
|
||||
class FileLogger(loggerBase: LoggerBase, override val tw: FileTrapWriter): Logger(loggerBase, tw) {
|
||||
class FileLogger(loggerBase: LoggerBase, val ftw: FileTrapWriter): Logger(loggerBase, ftw.getDiagnosticTrapWriter()) {
|
||||
fun warnElement(msg: String, element: IrElement, exn: Throwable? = null) {
|
||||
val locationString = tw.getLocationString(element)
|
||||
val mkLocationId = { tw.getLocation(element) }
|
||||
loggerBase.diagnostic(tw, Severity.Warn, msg, exn?.stackTraceToString(), locationString, mkLocationId)
|
||||
val locationString = ftw.getLocationString(element)
|
||||
val mkLocationId = { ftw.getLocation(element) }
|
||||
loggerBase.diagnostic(ftw.getDiagnosticTrapWriter(), Severity.Warn, msg, exn?.stackTraceToString(), locationString, mkLocationId)
|
||||
}
|
||||
|
||||
fun errorElement(msg: String, element: IrElement, exn: Throwable? = null) {
|
||||
val locationString = tw.getLocationString(element)
|
||||
val mkLocationId = { tw.getLocation(element) }
|
||||
loggerBase.diagnostic(tw, Severity.Error, msg, exn?.stackTraceToString(), locationString, mkLocationId)
|
||||
val locationString = ftw.getLocationString(element)
|
||||
val mkLocationId = { ftw.getLocation(element) }
|
||||
loggerBase.diagnostic(ftw.getDiagnosticTrapWriter(), Severity.Error, msg, exn?.stackTraceToString(), locationString, mkLocationId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind
|
||||
|
||||
val kind_ENUM_ENTRIES: IrSyntheticBodyKind? = null
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind
|
||||
|
||||
val kind_ENUM_ENTRIES: IrSyntheticBodyKind? = IrSyntheticBodyKind.ENUM_ENTRIES
|
||||
|
||||
@@ -2,3 +2,4 @@ name: codeql-java-consistency-queries
|
||||
version: 0.0.0
|
||||
dependencies:
|
||||
codeql/java-all: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -4,3 +4,4 @@ groups:
|
||||
- examples
|
||||
dependencies:
|
||||
codeql/java-all: ${workspace}
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -54,6 +54,9 @@ android {
|
||||
versionName = "1.0"
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable("Instantiatable")
|
||||
}
|
||||
}
|
||||
|
||||
androidComponents {
|
||||
|
||||
@@ -13,6 +13,7 @@ xmlFiles
|
||||
| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseResources/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml |
|
||||
| project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml:0:0:0:0 | project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml |
|
||||
| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml |
|
||||
|
||||
@@ -54,6 +54,9 @@ android {
|
||||
versionName = "1.0"
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable("Instantiatable")
|
||||
}
|
||||
}
|
||||
|
||||
androidComponents {
|
||||
|
||||
@@ -13,6 +13,7 @@ xmlFiles
|
||||
| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseResources/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml |
|
||||
| project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml:0:0:0:0 | project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml |
|
||||
| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml |
|
||||
|
||||
@@ -55,4 +55,8 @@ android {
|
||||
}
|
||||
|
||||
variantFilter { variant -> if (variant.buildType.name == "debug") { setIgnore(true) } }
|
||||
|
||||
lintOptions {
|
||||
disable "Instantiatable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ xmlFiles
|
||||
| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseResources/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml |
|
||||
| project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml:0:0:0:0 | project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml |
|
||||
| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml |
|
||||
|
||||
@@ -55,4 +55,8 @@ android {
|
||||
}
|
||||
|
||||
variantFilter { variant -> if (variant.buildType.name == "debug") { setIgnore(true) } }
|
||||
|
||||
lintOptions {
|
||||
disable "Instantiatable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ xmlFiles
|
||||
| project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseJniLibFolders/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseResources/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseResources/merger.xml |
|
||||
| project/build/intermediates/incremental/mergeReleaseShaders/merger.xml:0:0:0:0 | project/build/intermediates/incremental/mergeReleaseShaders/merger.xml |
|
||||
| project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml:0:0:0:0 | project/build/intermediates/lint_vital_partial_results/release/out/lint-issues-release.xml |
|
||||
| project/build/intermediates/merged_manifest/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifest/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/merged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/merged_manifests/release/AndroidManifest.xml |
|
||||
| project/build/intermediates/packaged_manifests/release/AndroidManifest.xml:0:0:0:0 | project/build/intermediates/packaged_manifests/release/AndroidManifest.xml |
|
||||
|
||||
@@ -2,3 +2,4 @@ dependencies:
|
||||
codeql/java-all: '*'
|
||||
codeql/java-tests: '*'
|
||||
codeql/java-queries: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -5,3 +5,4 @@ dependencies:
|
||||
codeql/java-queries: '*'
|
||||
dataExtensions:
|
||||
ext/*.model.yml
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -5,3 +5,4 @@ dependencies:
|
||||
codeql/java-queries: '*'
|
||||
dataExtensions:
|
||||
ext/*.model.yml
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -3,3 +3,4 @@ dependencies:
|
||||
codeql/java-all: '*'
|
||||
codeql/java-tests: '*'
|
||||
codeql/java-queries: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -3,3 +3,4 @@ dependencies:
|
||||
codeql/java-all: '*'
|
||||
codeql/java-tests: '*'
|
||||
codeql/java-queries: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -3,3 +3,4 @@ dependencies:
|
||||
codeql/java-all: '*'
|
||||
codeql/java-tests: '*'
|
||||
codeql/java-queries: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -2,3 +2,4 @@ dependencies:
|
||||
codeql/java-all: '*'
|
||||
codeql/java-tests: '*'
|
||||
codeql/java-queries: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
name: integrationtest-custom-plugin
|
||||
dependencies:
|
||||
codeql/java-all: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
dependencies:
|
||||
codeql/java-all: '*'
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -2,4 +2,4 @@ dependencies:
|
||||
codeql/java-all: '*'
|
||||
codeql/java-tests: '*'
|
||||
codeql/java-queries: '*'
|
||||
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -1,3 +1,61 @@
|
||||
## 0.6.3
|
||||
|
||||
### New Features
|
||||
|
||||
* Kotlin versions up to 1.9.0 are now supported.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added flow through the block arguments of `kotlin.io.use` and `kotlin.with`.
|
||||
* Added models for the following packages:
|
||||
|
||||
* com.alibaba.druid.sql
|
||||
* com.fasterxml.jackson.databind
|
||||
* com.jcraft.jsch
|
||||
* io.netty.handler.ssl
|
||||
* okhttp3
|
||||
* org.antlr.runtime
|
||||
* org.fusesource.leveldbjni
|
||||
* org.influxdb
|
||||
* org.springframework.core.io
|
||||
* org.yaml.snakeyaml
|
||||
* Deleted the deprecated `getRHS` predicate from the `LValue` class, use `getRhs` instead.
|
||||
* Deleted the deprecated `getCFGNode` predicate from the `SsaVariable` class, use `getCfgNode` instead.
|
||||
* Deleted many deprecated predicates and classes with uppercase `XML`, `JSON`, `URL`, `API`, etc. in their names. Use the PascalCased versions instead.
|
||||
* Added models for the following packages:
|
||||
|
||||
* java.lang
|
||||
* java.nio.file
|
||||
* Added dataflow models for the Gson deserialization library.
|
||||
* Added models for the following packages:
|
||||
|
||||
* okhttp3
|
||||
* Added more dataflow models for the Play Framework.
|
||||
* Modified the models related to `java.nio.file.Files.copy` so that generic `[Input|Output]Stream` arguments are not considered file-related sinks.
|
||||
* Dataflow analysis has a new flow step through constructors of transitive subtypes of `java.io.InputStream` that wrap an underlying data source. Previously, the step only existed for direct subtypes of `java.io.InputStream`.
|
||||
* Path creation sinks modeled in `PathCreation.qll` have been added to the models-as-data sink kind `path-injection`.
|
||||
* Updated the regular expression in the `HostnameSanitizer` sanitizer in the `semmle.code.java.security.RequestForgery` library to better detect strings prefixed with a hostname.
|
||||
* Changed the `android-widget` Java source kind to `remote`. Any custom data extensions that use the `android-widget` source kind will need to be updated accordingly in order to continue working.
|
||||
* Updated the following Java sink kind names. Any custom data extensions will need to be updated accordingly in order to continue working.
|
||||
* `sql` to `sql-injection`
|
||||
* `url-redirect` to `url-redirection`
|
||||
* `xpath` to `xpath-injection`
|
||||
* `ssti` to `template-injection`
|
||||
* `logging` to `log-injection`
|
||||
* `groovy` to `groovy-injection`
|
||||
* `jexl` to `jexl-injection`
|
||||
* `mvel` to `mvel-injection`
|
||||
* `xslt` to `xslt-injection`
|
||||
* `ldap` to `ldap-injection`
|
||||
* `pending-intent-sent` to `pending-intents`
|
||||
* `intent-start` to `intent-redirection`
|
||||
* `set-hostname-verifier` to `hostname-verification`
|
||||
* `header-splitting` to `response-splitting`
|
||||
* `xss` to `html-injection` and `js-injection`
|
||||
* `write-file` to `file-system-store`
|
||||
* `create-file` and `read-file` to `path-injection`
|
||||
* `open-url` and `jdbc-url` to `request-forgery`
|
||||
|
||||
## 0.6.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* The `ExecCallable` class in `ExternalProcess.qll` has been deprecated.
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Updated the following Java sink kind names. Any custom data extensions will need to be updated accordingly in order to continue working.
|
||||
* `sql` to `sql-injection`
|
||||
* `url-redirect` to `url-redirection`
|
||||
* `xpath` to `xpath-injection`
|
||||
* `ssti` to `template-injection`
|
||||
* `logging` to `log-injection`
|
||||
* `groovy` to `groovy-injection`
|
||||
* `jexl` to `jexl-injection`
|
||||
* `mvel` to `mvel-injection`
|
||||
* `xslt` to `xslt-injection`
|
||||
* `ldap` to `ldap-injection`
|
||||
* `pending-intent-sent` to `pending-intents`
|
||||
* `intent-start` to `intent-redirection`
|
||||
* `set-hostname-verifier` to `hostname-verification`
|
||||
* `header-splitting` to `response-splitting`
|
||||
* `xss` to `html-injection` and `js-injection`
|
||||
* `write-file` to `file-system-store`
|
||||
* `create-file` and `read-file` to `path-injection`
|
||||
* `open-url` and `jdbc-url` to `request-forgery`
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Changed the `android-widget` Java source kind to `remote`. Any custom data extensions that use the `android-widget` source kind will need to be updated accordingly in order to continue working.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Updated the regular expression in the `HostnameSanitizer` sanitizer in the `semmle.code.java.security.RequestForgery` library to better detect strings prefixed with a hostname.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Path creation sinks modeled in `PathCreation.qll` have been added to the models-as-data sink kind `path-injection`.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Dataflow analysis has a new flow step through constructors of transitive subtypes of `java.io.InputStream` that wrap an underlying data source. Previously, the step only existed for direct subtypes of `java.io.InputStream`.
|
||||
4
java/ql/lib/change-notes/2023-05-22-stapler-models.md
Normal file
4
java/ql/lib/change-notes/2023-05-22-stapler-models.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added more models for the Stapler framework.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
Modified the models related to `java.nio.file.Files.copy` so that generic `[Input|Output]Stream` arguments are not considered file-related sinks.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Kotlin versions up to 1.9.0 are now supported.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added more dataflow models for the Play Framework.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added dataflow models for the Gson deserialization library.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added models for the following packages:
|
||||
|
||||
* okhttp3
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added models for the following packages:
|
||||
|
||||
* java.lang
|
||||
* java.nio.file
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Deleted the deprecated `getRHS` predicate from the `LValue` class, use `getRhs` instead.
|
||||
* Deleted the deprecated `getCFGNode` predicate from the `SsaVariable` class, use `getCfgNode` instead.
|
||||
* Deleted many deprecated predicates and classes with uppercase `XML`, `JSON`, `URL`, `API`, etc. in their names. Use the PascalCased versions instead.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added flow through the block arguments of `kotlin.io.use` and `kotlin.with`.
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added models for the following packages:
|
||||
|
||||
* com.alibaba.druid.sql
|
||||
* com.fasterxml.jackson.databind
|
||||
* com.jcraft.jsch
|
||||
* io.netty.handler.ssl
|
||||
* okhttp3
|
||||
* org.antlr.runtime
|
||||
* org.fusesource.leveldbjni
|
||||
* org.influxdb
|
||||
* org.springframework.core.io
|
||||
* org.yaml.snakeyaml
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added a missing summary model for the method `java.net.URL.toString`.
|
||||
57
java/ql/lib/change-notes/released/0.6.3.md
Normal file
57
java/ql/lib/change-notes/released/0.6.3.md
Normal file
@@ -0,0 +1,57 @@
|
||||
## 0.6.3
|
||||
|
||||
### New Features
|
||||
|
||||
* Kotlin versions up to 1.9.0 are now supported.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added flow through the block arguments of `kotlin.io.use` and `kotlin.with`.
|
||||
* Added models for the following packages:
|
||||
|
||||
* com.alibaba.druid.sql
|
||||
* com.fasterxml.jackson.databind
|
||||
* com.jcraft.jsch
|
||||
* io.netty.handler.ssl
|
||||
* okhttp3
|
||||
* org.antlr.runtime
|
||||
* org.fusesource.leveldbjni
|
||||
* org.influxdb
|
||||
* org.springframework.core.io
|
||||
* org.yaml.snakeyaml
|
||||
* Deleted the deprecated `getRHS` predicate from the `LValue` class, use `getRhs` instead.
|
||||
* Deleted the deprecated `getCFGNode` predicate from the `SsaVariable` class, use `getCfgNode` instead.
|
||||
* Deleted many deprecated predicates and classes with uppercase `XML`, `JSON`, `URL`, `API`, etc. in their names. Use the PascalCased versions instead.
|
||||
* Added models for the following packages:
|
||||
|
||||
* java.lang
|
||||
* java.nio.file
|
||||
* Added dataflow models for the Gson deserialization library.
|
||||
* Added models for the following packages:
|
||||
|
||||
* okhttp3
|
||||
* Added more dataflow models for the Play Framework.
|
||||
* Modified the models related to `java.nio.file.Files.copy` so that generic `[Input|Output]Stream` arguments are not considered file-related sinks.
|
||||
* Dataflow analysis has a new flow step through constructors of transitive subtypes of `java.io.InputStream` that wrap an underlying data source. Previously, the step only existed for direct subtypes of `java.io.InputStream`.
|
||||
* Path creation sinks modeled in `PathCreation.qll` have been added to the models-as-data sink kind `path-injection`.
|
||||
* Updated the regular expression in the `HostnameSanitizer` sanitizer in the `semmle.code.java.security.RequestForgery` library to better detect strings prefixed with a hostname.
|
||||
* Changed the `android-widget` Java source kind to `remote`. Any custom data extensions that use the `android-widget` source kind will need to be updated accordingly in order to continue working.
|
||||
* Updated the following Java sink kind names. Any custom data extensions will need to be updated accordingly in order to continue working.
|
||||
* `sql` to `sql-injection`
|
||||
* `url-redirect` to `url-redirection`
|
||||
* `xpath` to `xpath-injection`
|
||||
* `ssti` to `template-injection`
|
||||
* `logging` to `log-injection`
|
||||
* `groovy` to `groovy-injection`
|
||||
* `jexl` to `jexl-injection`
|
||||
* `mvel` to `mvel-injection`
|
||||
* `xslt` to `xslt-injection`
|
||||
* `ldap` to `ldap-injection`
|
||||
* `pending-intent-sent` to `pending-intents`
|
||||
* `intent-start` to `intent-redirection`
|
||||
* `set-hostname-verifier` to `hostname-verification`
|
||||
* `header-splitting` to `response-splitting`
|
||||
* `xss` to `html-injection` and `js-injection`
|
||||
* `write-file` to `file-system-store`
|
||||
* `create-file` and `read-file` to `path-injection`
|
||||
* `open-url` and `jdbc-url` to `request-forgery`
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.2
|
||||
lastReleaseVersion: 0.6.3
|
||||
|
||||
@@ -1219,6 +1219,7 @@ ktSyntheticBody(
|
||||
int kind: int ref
|
||||
// 1: ENUM_VALUES
|
||||
// 2: ENUM_VALUEOF
|
||||
// 3: ENUM_ENTRIES
|
||||
)
|
||||
|
||||
ktLocalFunction(
|
||||
|
||||
6
java/ql/lib/ext/experimental/com.jcraft.jsch.model.yml
Normal file
6
java/ql/lib/ext/experimental/com.jcraft.jsch.model.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: experimentalSinkModel
|
||||
data:
|
||||
- ["com.jcraft.jsch", "ChannelExec", True, "setCommand", "", "", "Argument[0]", "command-injection", "manual", "jsch-os-injection"]
|
||||
1695
java/ql/lib/ext/generated/org.apache.commons.lang.model.yml
Normal file
1695
java/ql/lib/ext/generated/org.apache.commons.lang.model.yml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -8,30 +8,30 @@ extensions:
|
||||
- ["java.lang", "ClassLoader", True, "getSystemResource", "(String)", "", "Argument[0]", "path-injection", "ai-manual"]
|
||||
- ["java.lang", "ClassLoader", True, "getSystemResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"]
|
||||
- ["java.lang", "Module", True, "getResourceAsStream", "(String)", "", "Argument[0]", "path-injection", "ai-manual"]
|
||||
- ["java.lang", "ProcessBuilder", False, "command", "(List)", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["java.lang", "ProcessBuilder", False, "command", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "ProcessBuilder", False, "directory", "(File)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "ProcessBuilder", False, "ProcessBuilder", "(List)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "ProcessBuilder", False, "ProcessBuilder", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String[],String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String[],String[],File)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String[],String[],File)", "", "Argument[2]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String,String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String,String[],File)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "Runtime", True, "exec", "(String,String[],File)", "", "Argument[2]", "command-injection", "ai-manual"]
|
||||
# These are potential vulnerabilities, but not for command-injection. No query for this kind of vulnerability currently exists.
|
||||
# - ["java.lang", "Runtime", False, "load", "(String)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", False, "loadLibrary", "(String)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# These are modeled in plain CodeQL. TODO: migrate them.
|
||||
# - ["java.lang", "ProcessBuilder", False, "command", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "ProcessBuilder", False, "directory", "(File)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "ProcessBuilder", False, "ProcessBuilder", "(List)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "ProcessBuilder", False, "ProcessBuilder", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String,String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String[],String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String,String[],File)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String,String[],File)", "", "Argument[2]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String[],String[],File)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String[],String[],File)", "", "Argument[2]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "Runtime", True, "exec", "(String[])", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "String", False, "matches", "(String)", "", "Argument[0]", "regex-use[f-1]", "manual"]
|
||||
- ["java.lang", "String", False, "replaceAll", "(String,String)", "", "Argument[0]", "regex-use[-1]", "manual"]
|
||||
- ["java.lang", "String", False, "replaceFirst", "(String,String)", "", "Argument[0]", "regex-use[-1]", "manual"]
|
||||
- ["java.lang", "String", False, "split", "(String)", "", "Argument[0]", "regex-use[-1]", "manual"]
|
||||
- ["java.lang", "String", False, "split", "(String,int)", "", "Argument[0]", "regex-use[-1]", "manual"]
|
||||
# These are modeled in plain CodeQL. TODO: migrate them.
|
||||
# - ["java.lang", "System", False, "load", "(String)", "", "Argument[0]", "command-injection", "ai-manual"] # This is actually injecting a library.
|
||||
# - ["java.lang", "System", False, "loadLibrary", "(String)", "", "Argument[0]", "command-injection", "ai-manual"] # This is actually injecting a library.
|
||||
# These are potential vulnerabilities, but not for command-injection. No query for this kind of vulnerability currently exists.
|
||||
# - ["java.lang", "System", False, "load", "(String)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
# - ["java.lang", "System", False, "loadLibrary", "(String)", "", "Argument[0]", "command-injection", "ai-manual"]
|
||||
- ["java.lang", "System$Logger", True, "log", "(Level,Object)", "", "Argument[1]", "log-injection", "manual"]
|
||||
- ["java.lang", "System$Logger", True, "log", "(Level,ResourceBundle,String,Object[])", "", "Argument[2..3]", "log-injection", "manual"]
|
||||
- ["java.lang", "System$Logger", True, "log", "(Level,ResourceBundle,String,Throwable)", "", "Argument[2]", "log-injection", "manual"]
|
||||
|
||||
@@ -45,7 +45,8 @@ extensions:
|
||||
- ["java.net", "URI", False, "toURL", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["java.net", "URL", False, "URL", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["java.net", "URL", False, "URL", "(URL,String)", "", "Argument[0]", "Argument[this]", "taint", "ai-manual"]
|
||||
- ["java.net", "URL", False, "URL", "(URL,String)", "", "Argument[1]", "Argument[this]", "taint", "ai-manual"] # @atorralba: review for consistency
|
||||
- ["java.net", "URL", False, "URL", "(URL,String)", "", "Argument[1]", "Argument[this]", "taint", "ai-manual"]
|
||||
- ["java.net", "URL", False, "toExternalForm", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["java.net", "URL", False, "toURI", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["java.net", "URL", False, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
|
||||
- ["java.net", "URLDecoder", False, "decode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
|
||||
11
java/ql/lib/ext/org.apache.commons.exec.model.yml
Normal file
11
java/ql/lib/ext/org.apache.commons.exec.model.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["org.apache.commons.exec", "CommandLine", True, "parse", "(String)", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["org.apache.commons.exec", "CommandLine", True, "parse", "(String,Map)", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["org.apache.commons.exec", "CommandLine", True, "addArguments", "(String)", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["org.apache.commons.exec", "CommandLine", True, "addArguments", "(String,boolean)", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["org.apache.commons.exec", "CommandLine", True, "addArguments", "(String[])", "", "Argument[0]", "command-injection", "manual"]
|
||||
- ["org.apache.commons.exec", "CommandLine", True, "addArguments", "(String[],boolean)", "", "Argument[0]", "command-injection", "manual"]
|
||||
6
java/ql/lib/ext/org.kohsuke.stapler.bind.model.yml
Normal file
6
java/ql/lib/ext/org.kohsuke.stapler.bind.model.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["org.kohsuke.stapler.bind", "JavaScriptMethod", True, "", "", "Annotated", "Parameter", "remote", "manual"]
|
||||
7
java/ql/lib/ext/org.kohsuke.stapler.json.model.yml
Normal file
7
java/ql/lib/ext/org.kohsuke.stapler.json.model.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["org.kohsuke.stapler.json", "SubmittedForm", True, "", "", "Annotated", "Parameter", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler.json", "JsonBody", True, "", "", "Annotated", "Parameter", "remote", "manual"]
|
||||
@@ -4,4 +4,46 @@ extensions:
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["org.kohsuke.stapler", "HttpResponses", True, "redirectTo", "(String)", "", "Argument[0]", "url-redirection", "ai-manual"]
|
||||
- ["org.kohsuke.stapler", "HttpResponses", True, "redirectTo", "(int,String)", "", "Argument[1]", "url-redirection", "manual"]
|
||||
- ["org.kohsuke.stapler", "HttpResponses", True, "staticResource", "(URL)", "", "Argument[0]", "request-forgery", "ai-manual"]
|
||||
- ["org.kohsuke.stapler", "HttpResponses", True, "staticResource", "(URL,long)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- ["org.kohsuke.stapler", "HttpResponses", True, "html", "(String)", "", "Argument[0]", "html-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "HttpResponses", True, "literalHtml", "(String)", "", "Argument[0]", "html-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "forward", "(Object,String,StaplerRequest)", "", "Argument[1]", "request-forgery", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "sendRedirect2", "(String)", "", "Argument[0]", "url-redirection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "sendRedirect", "(int,String)", "", "Argument[1]", "url-redirection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "sendRedirect", "(String)", "", "Argument[0]", "url-redirection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,URL)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,URL,long)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveLocalizedFile", "(StaplerRequest,URL)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveLocalizedFile", "(StaplerRequest,URL,long)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,InputStream,long,long,long,String)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,InputStream,long,long,int,String)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,InputStream,long,long,String)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "serveFile", "(StaplerRequest,InputStream,long,int,String)", "", "Argument[1]", "path-injection", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerResponse", True, "reverseProxyTo", "(URL,StaplerRequest)", "", "Argument[0]", "request-forgery", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/java-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getRequestURIWithQueryString", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getRequestURLWithQueryString", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getReferer", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getOriginalRequestURI", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getSubmittedForm", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getFileItem", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "bindParametersToList", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "bindParameters", "", "", "Argument[0]", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "bindParameters", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "bindJSON", "", "", "Argument[0]", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "bindJSON", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "bindJSONToList", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getParameter", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getParameterMap", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getParameterNames", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getParameterValues", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "StaplerRequest", True, "getRestOfPath", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "QueryParameter", True, "", "", "Annotated", "Parameter", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "Header", True, "", "", "Annotated", "Parameter", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "DataBoundConstructor", True, "", "", "Annotated", "Parameter", "remote", "manual"]
|
||||
- ["org.kohsuke.stapler", "DataBoundSetter", True, "", "", "Annotated", "Parameter", "remote", "manual"]
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
name: codeql/java-all
|
||||
version: 0.6.3-dev
|
||||
version: 0.6.4-dev
|
||||
groups: java
|
||||
dbscheme: config/semmlecode.dbscheme
|
||||
extractor: java
|
||||
library: true
|
||||
upgrades: upgrades
|
||||
dependencies:
|
||||
codeql/mad: ${workspace}
|
||||
codeql/regex: ${workspace}
|
||||
codeql/tutorial: ${workspace}
|
||||
codeql/typetracking: ${workspace}
|
||||
|
||||
@@ -199,18 +199,18 @@ class TypeFile extends Class {
|
||||
|
||||
// --- Standard methods ---
|
||||
/**
|
||||
* Any constructor of class `java.lang.ProcessBuilder`.
|
||||
* DEPRECATED: Any constructor of class `java.lang.ProcessBuilder`.
|
||||
*/
|
||||
class ProcessBuilderConstructor extends Constructor, ExecCallable {
|
||||
deprecated class ProcessBuilderConstructor extends Constructor, ExecCallable {
|
||||
ProcessBuilderConstructor() { this.getDeclaringType() instanceof TypeProcessBuilder }
|
||||
|
||||
override int getAnExecutedArgument() { result = 0 }
|
||||
}
|
||||
|
||||
/**
|
||||
* Any of the methods named `command` on class `java.lang.ProcessBuilder`.
|
||||
* DEPRECATED: Any of the methods named `command` on class `java.lang.ProcessBuilder`.
|
||||
*/
|
||||
class MethodProcessBuilderCommand extends Method, ExecCallable {
|
||||
deprecated class MethodProcessBuilderCommand extends Method, ExecCallable {
|
||||
MethodProcessBuilderCommand() {
|
||||
this.hasName("command") and
|
||||
this.getDeclaringType() instanceof TypeProcessBuilder
|
||||
@@ -220,9 +220,9 @@ class MethodProcessBuilderCommand extends Method, ExecCallable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Any method named `exec` on class `java.lang.Runtime`.
|
||||
* DEPRECATED: Any method named `exec` on class `java.lang.Runtime`.
|
||||
*/
|
||||
class MethodRuntimeExec extends Method, ExecCallable {
|
||||
deprecated class MethodRuntimeExec extends Method, ExecCallable {
|
||||
MethodRuntimeExec() {
|
||||
this.hasName("exec") and
|
||||
this.getDeclaringType() instanceof TypeRuntime
|
||||
|
||||
@@ -87,6 +87,7 @@ private import internal.FlowSummaryImplSpecific as FlowSummaryImplSpecific
|
||||
private import internal.AccessPathSyntax
|
||||
private import ExternalFlowExtensions as Extensions
|
||||
private import FlowSummary
|
||||
private import codeql.mad.ModelValidation as SharedModelVal
|
||||
|
||||
/**
|
||||
* A class for activating additional model rows.
|
||||
@@ -265,86 +266,17 @@ module ModelValidation {
|
||||
)
|
||||
}
|
||||
|
||||
private class OutdatedSinkKind extends string {
|
||||
OutdatedSinkKind() {
|
||||
this =
|
||||
[
|
||||
"sql", "url-redirect", "xpath", "ssti", "logging", "groovy", "jexl", "mvel", "xslt",
|
||||
"ldap", "pending-intent-sent", "intent-start", "set-hostname-verifier",
|
||||
"header-splitting", "xss", "write-file", "create-file", "read-file", "open-url",
|
||||
"jdbc-url"
|
||||
]
|
||||
}
|
||||
private module KindValConfig implements SharedModelVal::KindValidationConfigSig {
|
||||
predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) }
|
||||
|
||||
private string replacementKind() {
|
||||
this = ["sql", "xpath", "groovy", "jexl", "mvel", "xslt", "ldap"] and
|
||||
result = this + "-injection"
|
||||
or
|
||||
this = "url-redirect" and result = "url-redirection"
|
||||
or
|
||||
this = "ssti" and result = "template-injection"
|
||||
or
|
||||
this = "logging" and result = "log-injection"
|
||||
or
|
||||
this = "pending-intent-sent" and result = "pending-intents"
|
||||
or
|
||||
this = "intent-start" and result = "intent-redirection"
|
||||
or
|
||||
this = "set-hostname-verifier" and result = "hostname-verification"
|
||||
or
|
||||
this = "header-splitting" and result = "response-splitting"
|
||||
or
|
||||
this = "xss" and result = "html-injection\" or \"js-injection"
|
||||
or
|
||||
this = "write-file" and result = "file-content-store"
|
||||
or
|
||||
this = ["create-file", "read-file"] and result = "path-injection"
|
||||
or
|
||||
this = ["open-url", "jdbc-url"] and result = "request-forgery"
|
||||
}
|
||||
predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) }
|
||||
|
||||
string outdatedMessage() {
|
||||
result =
|
||||
"The kind \"" + this + "\" is outdated. Use \"" + this.replacementKind() + "\" instead."
|
||||
}
|
||||
predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) }
|
||||
|
||||
predicate neutralKind(string kind) { neutralModel(_, _, _, _, kind, _) }
|
||||
}
|
||||
|
||||
private string getInvalidModelKind() {
|
||||
exists(string kind | summaryModel(_, _, _, _, _, _, _, _, kind, _) |
|
||||
not kind = ["taint", "value"] and
|
||||
result = "Invalid kind \"" + kind + "\" in summary model."
|
||||
)
|
||||
or
|
||||
exists(string kind, string msg | sinkModel(_, _, _, _, _, _, _, kind, _) |
|
||||
not kind =
|
||||
[
|
||||
"request-forgery", "jndi-injection", "ldap-injection", "sql-injection", "log-injection",
|
||||
"mvel-injection", "xpath-injection", "groovy-injection", "html-injection", "js-injection",
|
||||
"ognl-injection", "intent-redirection", "pending-intents", "url-redirection",
|
||||
"path-injection", "file-content-store", "hostname-verification", "response-splitting",
|
||||
"information-leak", "xslt-injection", "jexl-injection", "bean-validation",
|
||||
"template-injection", "fragment-injection", "command-injection"
|
||||
] and
|
||||
not kind.matches("regex-use%") and
|
||||
not kind.matches("qltest%") and
|
||||
msg = "Invalid kind \"" + kind + "\" in sink model." and
|
||||
// The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024.
|
||||
if kind instanceof OutdatedSinkKind
|
||||
then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage()
|
||||
else result = msg
|
||||
)
|
||||
or
|
||||
exists(string kind | sourceModel(_, _, _, _, _, _, _, kind, _) |
|
||||
not kind = ["remote", "contentprovider", "android-external-storage-dir"] and
|
||||
not kind.matches("qltest%") and
|
||||
result = "Invalid kind \"" + kind + "\" in source model."
|
||||
)
|
||||
or
|
||||
exists(string kind | neutralModel(_, _, _, _, kind, _) |
|
||||
not kind = ["summary", "source", "sink"] and
|
||||
result = "Invalid kind \"" + kind + "\" in neutral model."
|
||||
)
|
||||
}
|
||||
private module KindVal = SharedModelVal::KindValidation<KindValConfig>;
|
||||
|
||||
private string getInvalidModelSignature() {
|
||||
exists(
|
||||
@@ -387,7 +319,7 @@ module ModelValidation {
|
||||
msg =
|
||||
[
|
||||
getInvalidModelSignature(), getInvalidModelInput(), getInvalidModelOutput(),
|
||||
getInvalidModelKind()
|
||||
KindVal::getInvalidModelKind()
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ abstract class RemoteFlowSource extends DataFlow::Node {
|
||||
*/
|
||||
private module FlowSources {
|
||||
private import semmle.code.java.frameworks.hudson.Hudson
|
||||
private import semmle.code.java.frameworks.stapler.Stapler
|
||||
}
|
||||
|
||||
private class ExternalRemoteFlowSource extends RemoteFlowSource {
|
||||
|
||||
@@ -23,6 +23,7 @@ private module Frameworks {
|
||||
private import semmle.code.java.frameworks.Properties
|
||||
private import semmle.code.java.frameworks.Protobuf
|
||||
private import semmle.code.java.frameworks.ratpack.RatpackExec
|
||||
private import semmle.code.java.frameworks.stapler.Stapler
|
||||
private import semmle.code.java.JDK
|
||||
}
|
||||
|
||||
|
||||
@@ -2021,7 +2021,8 @@ module Impl<FullStateConfigSig Config> {
|
||||
FlowCheckNode() {
|
||||
castNode(this.asNode()) or
|
||||
clearsContentCached(this.asNode(), _) or
|
||||
expectsContentCached(this.asNode(), _)
|
||||
expectsContentCached(this.asNode(), _) or
|
||||
neverSkipInPathGraph(this.asNode())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -242,6 +242,12 @@ class CastNode extends ExprNode {
|
||||
CastNode() { this.getExpr() instanceof CastingExpr }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `n` should never be skipped over in the `PathGraph` and in path
|
||||
* explanations.
|
||||
*/
|
||||
predicate neverSkipInPathGraph(Node n) { none() }
|
||||
|
||||
private newtype TDataFlowCallable =
|
||||
TSrcCallable(Callable c) or
|
||||
TSummarizedCallable(SummarizedCallable c) or
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/** Definitions related to the Apache Commons Exec library. */
|
||||
|
||||
import semmle.code.java.Type
|
||||
import semmle.code.java.security.ExternalProcess
|
||||
|
||||
/** The class `org.apache.commons.exec.CommandLine`. */
|
||||
private class TypeCommandLine extends Class {
|
||||
TypeCommandLine() { this.hasQualifiedName("org.apache.commons.exec", "CommandLine") }
|
||||
}
|
||||
|
||||
/** The `parse()` method of the class `org.apache.commons.exec.CommandLine`. */
|
||||
private class MethodCommandLineParse extends Method, ExecCallable {
|
||||
MethodCommandLineParse() {
|
||||
this.getDeclaringType() instanceof TypeCommandLine and
|
||||
this.hasName("parse")
|
||||
}
|
||||
|
||||
override int getAnExecutedArgument() { result = 0 }
|
||||
}
|
||||
|
||||
/** The `addArguments()` method of the class `org.apache.commons.exec.CommandLine`. */
|
||||
private class MethodCommandLineAddArguments extends Method, ExecCallable {
|
||||
MethodCommandLineAddArguments() {
|
||||
this.getDeclaringType() instanceof TypeCommandLine and
|
||||
this.hasName("addArguments")
|
||||
}
|
||||
|
||||
override int getAnExecutedArgument() { result = 0 }
|
||||
}
|
||||
@@ -2,8 +2,17 @@
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.FlowSources
|
||||
private import semmle.code.java.frameworks.stapler.Stapler
|
||||
private import semmle.code.java.security.XSS
|
||||
|
||||
/** A method declared in a subtype of `hudson.model.Descriptor` that returns an `HttpResponse`. */
|
||||
class HudsonWebMethod extends Method {
|
||||
HudsonWebMethod() {
|
||||
this.getReturnType().(RefType).getASourceSupertype*() instanceof HttpResponse and
|
||||
this.getDeclaringType().getASourceSupertype*().hasQualifiedName("hudson.model", "Descriptor")
|
||||
}
|
||||
}
|
||||
|
||||
private class FilePathRead extends LocalUserInput {
|
||||
FilePathRead() {
|
||||
this.asExpr()
|
||||
|
||||
124
java/ql/lib/semmle/code/java/frameworks/stapler/Stapler.qll
Normal file
124
java/ql/lib/semmle/code/java/frameworks/stapler/Stapler.qll
Normal file
@@ -0,0 +1,124 @@
|
||||
/** Provides classes and predicates related to the Stapler framework. */
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.DataFlow
|
||||
private import semmle.code.java.dataflow.FlowSources
|
||||
private import semmle.code.java.dataflow.FlowSteps
|
||||
private import semmle.code.java.dataflow.TypeFlow
|
||||
private import semmle.code.java.frameworks.hudson.Hudson
|
||||
private import semmle.code.java.frameworks.JavaxAnnotations
|
||||
|
||||
/**
|
||||
* A callable annotated with a Stapler `DataBound` annotation,
|
||||
* or that has the `@stapler-constructor` Javadoc annotation.
|
||||
*/
|
||||
class DataBoundAnnotated extends Callable {
|
||||
DataBoundAnnotated() {
|
||||
exists(Annotation an |
|
||||
an.getType()
|
||||
.hasQualifiedName("org.kohsuke.stapler", ["DataBoundConstructor", "DataBoundSetter"])
|
||||
|
|
||||
this = an.getAnnotatedElement()
|
||||
)
|
||||
or
|
||||
exists(Javadoc doc | doc.getAChild().getText().matches("%@stapler-constructor%") |
|
||||
doc.getCommentedElement() = this
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** The interface `org.kohsuke.stapler.HttpResponse`. */
|
||||
class HttpResponse extends Interface {
|
||||
HttpResponse() { this.hasQualifiedName("org.kohsuke.stapler", "HttpResponse") }
|
||||
}
|
||||
|
||||
/**
|
||||
* A remote flow source for parameters annotated with an annotation
|
||||
* that is itself annotated with `InjectedParameter`.
|
||||
*
|
||||
* Such parameters are populated with user-provided data by Stapler.
|
||||
*/
|
||||
private class InjectedParameterSource extends RemoteFlowSource {
|
||||
InjectedParameterSource() {
|
||||
this.asParameter().getAnAnnotation().getType() instanceof InjectedParameterAnnotatedType
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "Stapler injected parameter" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A dataflow step from the `HttpResponse` return value of a `HudsonWebMethod`
|
||||
* to the instance parameter of the `generateResponse` method of the appropriate subtype of `HttpResponse`.
|
||||
*
|
||||
* This models the rendering process of an `HttpResponse` by Stapler.
|
||||
*/
|
||||
private class HttpResponseGetDescriptionStep extends AdditionalValueStep {
|
||||
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(ReturnStmt s, GenerateResponseMethod m |
|
||||
s.getEnclosingCallable() instanceof HudsonWebMethod and
|
||||
boundOrStaticType(s.getResult(), m.getDeclaringType().getADescendant())
|
||||
|
|
||||
n1.asExpr() = s.getResult() and
|
||||
n2.(DataFlow::InstanceParameterNode).getCallable() = m
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A dataflow step from the post-update node of an instance access in a `DataBoundAnnotated` method
|
||||
* to the instance parameter of a `PostConstruct` method of the same type.
|
||||
*
|
||||
* This models the construction process of a `DataBound` object in Stapler.
|
||||
*/
|
||||
private class PostConstructDataBoundAdditionalStep extends AdditionalValueStep {
|
||||
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(PostConstructDataBoundMethod postConstruct, DataBoundAnnotated input |
|
||||
postConstruct.getDeclaringType() = input.getDeclaringType()
|
||||
|
|
||||
n1.(DataFlow::PostUpdateNode)
|
||||
.getPreUpdateNode()
|
||||
.(DataFlow::InstanceAccessNode)
|
||||
.getEnclosingCallable() = input and
|
||||
n2.(DataFlow::InstanceParameterNode).getCallable() = postConstruct
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** An annotation type annotated with the `InjectedParameter` annotation. */
|
||||
private class InjectedParameterAnnotatedType extends AnnotationType {
|
||||
InjectedParameterAnnotatedType() {
|
||||
this.getAnAnnotation().getType().hasQualifiedName("org.kohsuke.stapler", "InjectedParameter")
|
||||
}
|
||||
}
|
||||
|
||||
/** The `generateResponse` method of `org.kohsuke.stapler.HttpResponse` or its subtypes. */
|
||||
private class GenerateResponseMethod extends Method {
|
||||
GenerateResponseMethod() {
|
||||
this.getDeclaringType().getASourceSupertype*() instanceof HttpResponse and
|
||||
this.hasName("generateResponse")
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if `t` is the static type of `e`, or an upper bound of the runtime type of `e`. */
|
||||
private predicate boundOrStaticType(Expr e, RefType t) {
|
||||
exprTypeFlow(e, t, false)
|
||||
or
|
||||
t = e.getType()
|
||||
}
|
||||
|
||||
/**
|
||||
* A method called after the construction of a `DataBound` object.
|
||||
*
|
||||
* That is, either the `bindResolve` method of a subtype of `org.kohsuke.stapler.DataBoundResolvable`,
|
||||
* or a method annotated with `javax.annotation.PostConstruct`.
|
||||
*/
|
||||
private class PostConstructDataBoundMethod extends Method {
|
||||
PostConstructDataBoundMethod() {
|
||||
this.getDeclaringType()
|
||||
.getASourceSupertype*()
|
||||
.hasQualifiedName("org.kohsuke.stapler", "DataBoundResolvable") and
|
||||
this.hasName("bindResolve")
|
||||
or
|
||||
this.getAnAnnotation() instanceof PostConstructAnnotation
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,8 @@
|
||||
import java
|
||||
private import semmle.code.java.dataflow.FlowSources
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
private import semmle.code.java.security.ExternalProcess
|
||||
private import semmle.code.java.security.CommandArguments
|
||||
private import semmle.code.java.security.ExternalProcess
|
||||
|
||||
/** A sink for command injection vulnerabilities. */
|
||||
abstract class CommandInjectionSink extends DataFlow::Node { }
|
||||
@@ -33,9 +33,7 @@ class CommandInjectionAdditionalTaintStep extends Unit {
|
||||
}
|
||||
|
||||
private class DefaultCommandInjectionSink extends CommandInjectionSink {
|
||||
DefaultCommandInjectionSink() {
|
||||
this.asExpr() instanceof ArgumentToExec or sinkNode(this, "command-injection")
|
||||
}
|
||||
DefaultCommandInjectionSink() { sinkNode(this, "command-injection") }
|
||||
}
|
||||
|
||||
private class DefaultCommandInjectionSanitizer extends CommandInjectionSanitizer {
|
||||
@@ -100,7 +98,7 @@ predicate execIsTainted(
|
||||
RemoteUserInputToArgumentToExecFlow::PathNode sink, Expr execArg
|
||||
) {
|
||||
RemoteUserInputToArgumentToExecFlow::flowPath(source, sink) and
|
||||
sink.getNode().asExpr() = execArg
|
||||
argumentToExec(execArg, sink.getNode())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,7 +110,7 @@ predicate execIsTainted(
|
||||
*/
|
||||
deprecated predicate execTainted(DataFlow::PathNode source, DataFlow::PathNode sink, Expr execArg) {
|
||||
exists(RemoteUserInputToArgumentToExecFlowConfig conf |
|
||||
conf.hasFlowPath(source, sink) and sink.getNode().asExpr() = execArg
|
||||
conf.hasFlowPath(source, sink) and argumentToExec(execArg, sink.getNode())
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
/** Definitions related to external processes. */
|
||||
|
||||
import semmle.code.java.Member
|
||||
|
||||
private module Instances {
|
||||
private import semmle.code.java.JDK
|
||||
private import semmle.code.java.frameworks.apache.Exec
|
||||
}
|
||||
private import semmle.code.java.dataflow.DataFlow
|
||||
private import semmle.code.java.security.CommandLineQuery
|
||||
|
||||
/**
|
||||
* A callable that executes a command.
|
||||
* DEPRECATED: A callable that executes a command.
|
||||
*/
|
||||
abstract class ExecCallable extends Callable {
|
||||
abstract deprecated class ExecCallable extends Callable {
|
||||
/**
|
||||
* Gets the index of an argument that will be part of the command that is executed.
|
||||
*/
|
||||
@@ -23,13 +20,19 @@ abstract class ExecCallable extends Callable {
|
||||
* to be executed.
|
||||
*/
|
||||
class ArgumentToExec extends Expr {
|
||||
ArgumentToExec() {
|
||||
exists(Call execCall, ExecCallable execCallable, int i |
|
||||
execCall.getArgument(pragma[only_bind_into](i)) = this and
|
||||
execCallable = execCall.getCallee() and
|
||||
i = execCallable.getAnExecutedArgument()
|
||||
)
|
||||
}
|
||||
ArgumentToExec() { argumentToExec(this, _) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `e` is an expression used as an argument to a call that executes an external command.
|
||||
* For calls to varargs method calls, this only includes the first argument, which will be the command
|
||||
* to be executed.
|
||||
*/
|
||||
predicate argumentToExec(Expr e, CommandInjectionSink s) {
|
||||
s.asExpr() = e
|
||||
or
|
||||
e.(Argument).isNthVararg(0) and
|
||||
s.(DataFlow::ImplicitVarargsArray).getCall() = e.(Argument).getCall()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,6 @@ private import semmle.code.java.dataflow.ExternalFlow
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.security.SensitiveActions
|
||||
import semmle.code.java.frameworks.android.Compose
|
||||
import DataFlow
|
||||
|
||||
/** A variable that may hold sensitive information, judging by its name. */
|
||||
class CredentialExpr extends Expr {
|
||||
@@ -45,7 +44,7 @@ deprecated class SensitiveLoggerConfiguration extends TaintTracking::Configurati
|
||||
sanitizer.getType() instanceof TypeType
|
||||
}
|
||||
|
||||
override predicate isSanitizerIn(Node node) { this.isSource(node) }
|
||||
override predicate isSanitizerIn(DataFlow::Node node) { this.isSource(node) }
|
||||
}
|
||||
|
||||
/** A data-flow configuration for identifying potentially-sensitive data flowing to a log output. */
|
||||
@@ -62,7 +61,7 @@ module SensitiveLoggerConfig implements DataFlow::ConfigSig {
|
||||
sanitizer.getType() instanceof TypeType
|
||||
}
|
||||
|
||||
predicate isBarrierIn(Node node) { isSource(node) }
|
||||
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
|
||||
}
|
||||
|
||||
module SensitiveLoggerFlow = TaintTracking::Global<SensitiveLoggerConfig>;
|
||||
|
||||
@@ -28,6 +28,20 @@ private class ObjectInputStreamReadObjectMethod extends Method {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A type extending `ObjectInputStream` that makes it safe to deserialize untrusted data.
|
||||
*
|
||||
* * See https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/serialization/ValidatingObjectInputStream.html
|
||||
* * See https://github.com/ikkisoft/SerialKiller
|
||||
*/
|
||||
private class SafeObjectInputStreamType extends RefType {
|
||||
SafeObjectInputStreamType() {
|
||||
this.getASourceSupertype*()
|
||||
.hasQualifiedName("org.apache.commons.io.serialization", "ValidatingObjectInputStream") or
|
||||
this.getASourceSupertype*().hasQualifiedName("org.nibblesec.tools", "SerialKiller")
|
||||
}
|
||||
}
|
||||
|
||||
private class XmlDecoderReadObjectMethod extends Method {
|
||||
XmlDecoderReadObjectMethod() {
|
||||
this.getDeclaringType().hasQualifiedName("java.beans", "XMLDecoder") and
|
||||
@@ -135,9 +149,7 @@ predicate unsafeDeserialization(MethodAccess ma, Expr sink) {
|
||||
sink = ma.getQualifier() and
|
||||
not exists(DataFlow::ExprNode node |
|
||||
node.getExpr() = sink and
|
||||
node.getTypeBound()
|
||||
.(RefType)
|
||||
.hasQualifiedName("org.apache.commons.io.serialization", "ValidatingObjectInputStream")
|
||||
node.getTypeBound() instanceof SafeObjectInputStreamType
|
||||
)
|
||||
or
|
||||
m instanceof XmlDecoderReadObjectMethod and
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add ENUM_ENTRIES
|
||||
compatibility: full
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.6.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `java/summary/lines-of-code` query now only counts lines of Java code. The new `java/summary/lines-of-code-kotlin` counts lines of Kotlin code.
|
||||
|
||||
## 0.6.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -3,17 +3,15 @@
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>Extracting files from a malicious zip archive (or another archive format)
|
||||
without validating that the destination file path
|
||||
is within the destination directory can cause files outside the destination directory to be
|
||||
overwritten, due to the possible presence of directory traversal elements (<code>..</code>) in
|
||||
archive paths.</p>
|
||||
<p>Extracting files from a malicious zip file, or similar type of archive,
|
||||
is at risk of directory traversal attacks if filenames from the archive are
|
||||
not properly validated.</p>
|
||||
|
||||
<p>Zip archives contain archive entries representing each file in the archive. These entries
|
||||
include a file path for the entry, but these file paths are not restricted and may contain
|
||||
unexpected special elements such as the directory traversal element (<code>..</code>). If these
|
||||
file paths are used to determine an output file to write the contents of the archive item to, then
|
||||
the file may be written to an unexpected location. This can result in sensitive information being
|
||||
file paths are used to create a filesystem path, then a file operation may happen in an
|
||||
unexpected location. This can result in sensitive information being
|
||||
revealed or deleted, or an attacker being able to influence behavior by modifying unexpected
|
||||
files.</p>
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @name Arbitrary file write during archive extraction ("Zip Slip")
|
||||
* @description Extracting files from a malicious archive without validating that the
|
||||
* destination file path is within the destination directory can cause files outside
|
||||
* the destination directory to be overwritten.
|
||||
* @name Arbitrary file access during archive extraction ("Zip Slip")
|
||||
* @description Extracting files from a malicious ZIP file, or similar type of archive, without
|
||||
* validating that the destination file path is within the destination directory
|
||||
* can allow an attacker to unexpectedly gain access to resources.
|
||||
* @kind path-problem
|
||||
* @id java/zipslip
|
||||
* @problem.severity error
|
||||
|
||||
@@ -14,11 +14,14 @@
|
||||
|
||||
import java
|
||||
import semmle.code.java.security.CommandLineQuery
|
||||
import semmle.code.java.security.ExternalProcess
|
||||
import LocalUserInputToArgumentToExecFlow::PathGraph
|
||||
|
||||
from
|
||||
LocalUserInputToArgumentToExecFlow::PathNode source,
|
||||
LocalUserInputToArgumentToExecFlow::PathNode sink
|
||||
where LocalUserInputToArgumentToExecFlow::flowPath(source, sink)
|
||||
select sink.getNode().asExpr(), source, sink, "This command line depends on a $@.",
|
||||
source.getNode(), "user-provided value"
|
||||
LocalUserInputToArgumentToExecFlow::PathNode sink, Expr e
|
||||
where
|
||||
LocalUserInputToArgumentToExecFlow::flowPath(source, sink) and
|
||||
argumentToExec(e, sink.getNode())
|
||||
select e, source, sink, "This command line depends on a $@.", source.getNode(),
|
||||
"user-provided value"
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
import java
|
||||
import semmle.code.java.security.CommandLineQuery
|
||||
import semmle.code.java.security.ExternalProcess
|
||||
|
||||
/**
|
||||
* Strings that are known to be sane by some simple local analysis. Such strings
|
||||
|
||||
@@ -59,13 +59,13 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
|
||||
e.getType() instanceof NumberType
|
||||
)
|
||||
or
|
||||
t instanceof AutomodelEndpointTypes::TaintedPathSinkType and
|
||||
t instanceof AutomodelEndpointTypes::PathInjectionSinkType and
|
||||
e instanceof PathSanitizer::PathInjectionSanitizer
|
||||
}
|
||||
|
||||
RelatedLocation asLocation(Endpoint e) { result = e.asExpr() }
|
||||
|
||||
predicate isKnownKind = AutomodelJavaUtil::isKnownKind/3;
|
||||
predicate isKnownKind = AutomodelJavaUtil::isKnownKind/2;
|
||||
|
||||
predicate isSink(Endpoint e, string kind) {
|
||||
exists(string package, string type, string name, string signature, string ext, string input |
|
||||
@@ -79,7 +79,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
|
||||
predicate isNeutral(Endpoint e) {
|
||||
exists(string package, string type, string name, string signature |
|
||||
sinkSpec(e, package, type, name, signature, _, _) and
|
||||
ExternalFlow::neutralModel(package, type, name, [signature, ""], _, _)
|
||||
ExternalFlow::neutralModel(package, type, name, [signature, ""], "sink", _)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -40,18 +40,18 @@ class NegativeSinkType extends SinkType {
|
||||
}
|
||||
|
||||
/** A sink relevant to the SQL injection query */
|
||||
class SqlSinkType extends SinkType {
|
||||
SqlSinkType() { this = "sql" }
|
||||
class SqlInjectionSinkType extends SinkType {
|
||||
SqlInjectionSinkType() { this = "sql-injection" }
|
||||
}
|
||||
|
||||
/** A sink relevant to the tainted path injection query. */
|
||||
class TaintedPathSinkType extends SinkType {
|
||||
TaintedPathSinkType() { this = "tainted-path" }
|
||||
class PathInjectionSinkType extends SinkType {
|
||||
PathInjectionSinkType() { this = "path-injection" }
|
||||
}
|
||||
|
||||
/** A sink relevant to the SSRF query. */
|
||||
class RequestForgerySinkType extends SinkType {
|
||||
RequestForgerySinkType() { this = "ssrf" }
|
||||
RequestForgerySinkType() { this = "request-forgery" }
|
||||
}
|
||||
|
||||
/** A sink relevant to the command injection query. */
|
||||
|
||||
@@ -48,7 +48,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig {
|
||||
|
||||
RelatedLocation asLocation(Endpoint e) { result = e.asParameter() }
|
||||
|
||||
predicate isKnownKind = AutomodelJavaUtil::isKnownKind/3;
|
||||
predicate isKnownKind = AutomodelJavaUtil::isKnownKind/2;
|
||||
|
||||
predicate isSink(Endpoint e, string kind) {
|
||||
exists(string package, string type, string name, string signature, string ext, string input |
|
||||
@@ -60,7 +60,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig {
|
||||
predicate isNeutral(Endpoint e) {
|
||||
exists(string package, string type, string name, string signature |
|
||||
sinkSpec(e, package, type, name, signature, _, _) and
|
||||
ExternalFlow::neutralModel(package, type, name, [signature, ""], _, _)
|
||||
ExternalFlow::neutralModel(package, type, name, [signature, ""], "sink", _)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -27,31 +27,17 @@ class DollarAtString extends string {
|
||||
* Holds for all combinations of MaD kinds (`kind`) and their human readable
|
||||
* descriptions.
|
||||
*/
|
||||
predicate isKnownKind(
|
||||
string kind, string humanReadableKind, AutomodelEndpointTypes::EndpointType type
|
||||
) {
|
||||
kind = "read-file" and
|
||||
humanReadableKind = "read file" and
|
||||
type instanceof AutomodelEndpointTypes::TaintedPathSinkType
|
||||
predicate isKnownKind(string kind, AutomodelEndpointTypes::EndpointType type) {
|
||||
kind = "path-injection" and
|
||||
type instanceof AutomodelEndpointTypes::PathInjectionSinkType
|
||||
or
|
||||
kind = "create-file" and
|
||||
humanReadableKind = "create file" and
|
||||
type instanceof AutomodelEndpointTypes::TaintedPathSinkType
|
||||
kind = "sql-injection" and
|
||||
type instanceof AutomodelEndpointTypes::SqlInjectionSinkType
|
||||
or
|
||||
kind = "sql" and
|
||||
humanReadableKind = "mad modeled sql" and
|
||||
type instanceof AutomodelEndpointTypes::SqlSinkType
|
||||
or
|
||||
kind = "open-url" and
|
||||
humanReadableKind = "open url" and
|
||||
type instanceof AutomodelEndpointTypes::RequestForgerySinkType
|
||||
or
|
||||
kind = "jdbc-url" and
|
||||
humanReadableKind = "jdbc url" and
|
||||
kind = "request-forgery" and
|
||||
type instanceof AutomodelEndpointTypes::RequestForgerySinkType
|
||||
or
|
||||
kind = "command-injection" and
|
||||
humanReadableKind = "command injection" and
|
||||
type instanceof AutomodelEndpointTypes::CommandInjectionSinkType
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ signature module CandidateSig {
|
||||
/**
|
||||
* Defines what MaD kinds are known, and what endpoint type they correspond to.
|
||||
*/
|
||||
predicate isKnownKind(string kind, string humanReadableLabel, EndpointType type);
|
||||
predicate isKnownKind(string kind, EndpointType type);
|
||||
|
||||
/**
|
||||
* Holds if `e` is a flow sanitizer, and has type `t`.
|
||||
@@ -276,7 +276,11 @@ module SharedCharacteristics<CandidateSig Candidate> {
|
||||
string madKind;
|
||||
Candidate::EndpointType endpointType;
|
||||
|
||||
KnownSinkCharacteristic() { Candidate::isKnownKind(madKind, this, endpointType) }
|
||||
KnownSinkCharacteristic() {
|
||||
Candidate::isKnownKind(madKind, endpointType) and
|
||||
// bind "this" to a unique string differing from that of the SinkType classes
|
||||
this = madKind + "-characteristic"
|
||||
}
|
||||
|
||||
override predicate appliesToEndpoint(Candidate::Endpoint e) { Candidate::isSink(e, madKind) }
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The query `java/unsafe-deserialization` has been updated to take into account `SerialKiller`, a library used to prevent deserialization of arbitrary classes.
|
||||
4
java/ql/src/change-notes/2023-06-16-zipslip-rename.md
Normal file
4
java/ql/src/change-notes/2023-06-16-zipslip-rename.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* The query "Arbitrary file write during archive extraction ("Zip Slip")" (`java/zipslip`) has been renamed to "Arbitrary file access during archive extraction ("Zip Slip")."
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* New models have been added for `org.apache.commons.lang`.
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
## 0.6.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `java/summary/lines-of-code` query now only counts lines of Java code. The new `java/summary/lines-of-code-kotlin` counts lines of Kotlin code.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.2
|
||||
lastReleaseVersion: 0.6.3
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
import java
|
||||
import semmle.code.java.security.CommandLineQuery
|
||||
import RemoteUserInputToArgumentToExecFlow::PathGraph
|
||||
import JSchOSInjection
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
|
||||
private class ActivateModels extends ActiveExperimentalModels {
|
||||
ActivateModels() { this = "jsch-os-injection" }
|
||||
}
|
||||
|
||||
// This is a clone of query `java/command-line-injection` that also includes experimental sinks.
|
||||
from
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* Provides classes for JSch OS command injection detection
|
||||
*/
|
||||
|
||||
import java
|
||||
|
||||
/** The class `com.jcraft.jsch.ChannelExec`. */
|
||||
private class JSchChannelExec extends RefType {
|
||||
JSchChannelExec() { this.hasQualifiedName("com.jcraft.jsch", "ChannelExec") }
|
||||
}
|
||||
|
||||
/** A method to set an OS Command for the execution. */
|
||||
private class ChannelExecSetCommandMethod extends Method, ExecCallable {
|
||||
ChannelExecSetCommandMethod() {
|
||||
this.hasName("setCommand") and
|
||||
this.getDeclaringType() instanceof JSchChannelExec
|
||||
}
|
||||
|
||||
override int getAnExecutedArgument() { result = 0 }
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/java-queries
|
||||
version: 0.6.3-dev
|
||||
version: 0.6.4-dev
|
||||
groups:
|
||||
- java
|
||||
- queries
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
import java
|
||||
import TestUtilities.InlineFlowTest
|
||||
import DefaultFlowTest
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user