mirror of
https://github.com/github/codeql.git
synced 2025-12-20 18:56:32 +01:00
Java: share getCallable interface between automodel extraction modes
This commit is contained in:
@@ -16,6 +16,7 @@ private import semmle.code.java.security.RequestForgery
|
||||
private import semmle.code.java.dataflow.internal.ModelExclusions as ModelExclusions
|
||||
private import AutomodelSharedUtil as AutomodelSharedUtil
|
||||
private import semmle.code.java.security.PathSanitizer as PathSanitizer
|
||||
private import AutomodelSharedGetCallable as AutomodelSharedGetCallable
|
||||
import AutomodelSharedCharacteristics as SharedCharacteristics
|
||||
import AutomodelEndpointTypes as AutomodelEndpointTypes
|
||||
|
||||
@@ -85,8 +86,8 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
|
||||
additional predicate sinkSpec(
|
||||
Endpoint e, string package, string type, string name, string signature, string ext, string input
|
||||
) {
|
||||
ApplicationCandidatesImpl::getCallable(e).hasQualifiedName(package, type, name) and
|
||||
signature = ExternalFlow::paramsString(getCallable(e)) and
|
||||
ApplicationModeGetCallable::getCallable(e).hasQualifiedName(package, type, name) and
|
||||
signature = ExternalFlow::paramsString(ApplicationModeGetCallable::getCallable(e)) and
|
||||
ext = "" and
|
||||
(
|
||||
exists(Call c, int argIdx |
|
||||
@@ -110,13 +111,19 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
|
||||
type = CallContext() and
|
||||
result = any(Call c | e.asExpr() = [c.getAnArgument(), c.getQualifier()])
|
||||
}
|
||||
}
|
||||
|
||||
private class JavaCallable = Callable;
|
||||
|
||||
private module ApplicationModeGetCallable implements AutomodelSharedGetCallable::GetCallableSig {
|
||||
class Callable = JavaCallable;
|
||||
|
||||
class Endpoint = ApplicationCandidatesImpl::Endpoint;
|
||||
|
||||
/**
|
||||
* Returns the API callable being modeled.
|
||||
*
|
||||
* Each Java mode should implement this predicate.
|
||||
*/
|
||||
additional Callable getCallable(Endpoint e) {
|
||||
Callable getCallable(Endpoint e) {
|
||||
exists(Call c |
|
||||
e.asExpr() = [c.getAnArgument(), c.getQualifier()] and
|
||||
result = c.getCallee()
|
||||
@@ -209,8 +216,8 @@ private class UnexploitableIsCharacteristic extends CharacteristicsImpl::NotASin
|
||||
|
||||
override predicate appliesToEndpoint(Endpoint e) {
|
||||
not ApplicationCandidatesImpl::isSink(e, _) and
|
||||
ApplicationCandidatesImpl::getCallable(e).getName().matches("is%") and
|
||||
ApplicationCandidatesImpl::getCallable(e).getReturnType() instanceof BooleanType
|
||||
ApplicationModeGetCallable::getCallable(e).getName().matches("is%") and
|
||||
ApplicationModeGetCallable::getCallable(e).getReturnType() instanceof BooleanType
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +235,7 @@ private class UnexploitableExistsCharacteristic extends CharacteristicsImpl::Not
|
||||
override predicate appliesToEndpoint(Endpoint e) {
|
||||
not ApplicationCandidatesImpl::isSink(e, _) and
|
||||
exists(Callable callable |
|
||||
callable = ApplicationCandidatesImpl::getCallable(e) and
|
||||
callable = ApplicationModeGetCallable::getCallable(e) and
|
||||
callable.getName().toLowerCase() = ["exists", "notexists"] and
|
||||
callable.getReturnType() instanceof BooleanType
|
||||
)
|
||||
@@ -242,7 +249,7 @@ private class ExceptionCharacteristic extends CharacteristicsImpl::NotASinkChara
|
||||
ExceptionCharacteristic() { this = "exception" }
|
||||
|
||||
override predicate appliesToEndpoint(Endpoint e) {
|
||||
ApplicationCandidatesImpl::getCallable(e).getDeclaringType().getASupertype*() instanceof
|
||||
ApplicationModeGetCallable::getCallable(e).getDeclaringType().getASupertype*() instanceof
|
||||
TypeThrowable
|
||||
}
|
||||
}
|
||||
@@ -291,7 +298,7 @@ private class ArgumentToLocalCall extends CharacteristicsImpl::UninterestingToMo
|
||||
ArgumentToLocalCall() { this = "argument to local call" }
|
||||
|
||||
override predicate appliesToEndpoint(Endpoint e) {
|
||||
ApplicationCandidatesImpl::getCallable(e).fromSource()
|
||||
ApplicationModeGetCallable::getCallable(e).fromSource()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,7 +309,7 @@ private class ExcludedFromModeling extends CharacteristicsImpl::UninterestingToM
|
||||
ExcludedFromModeling() { this = "excluded from modeling" }
|
||||
|
||||
override predicate appliesToEndpoint(Endpoint e) {
|
||||
ModelExclusions::isUninterestingForModels(ApplicationCandidatesImpl::getCallable(e)) or
|
||||
ModelExclusions::isUninterestingForModels(ApplicationModeGetCallable::getCallable(e)) or
|
||||
ModelExclusions::isUninterestingForModels(e.getEnclosingCallable())
|
||||
}
|
||||
}
|
||||
@@ -316,7 +323,7 @@ private class NonPublicMethodCharacteristic extends CharacteristicsImpl::Uninter
|
||||
NonPublicMethodCharacteristic() { this = "non-public method" }
|
||||
|
||||
override predicate appliesToEndpoint(Endpoint e) {
|
||||
not ApplicationCandidatesImpl::getCallable(e).isPublic()
|
||||
not ApplicationModeGetCallable::getCallable(e).isPublic()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ private import semmle.code.java.security.QueryInjection
|
||||
private import semmle.code.java.security.RequestForgery
|
||||
private import semmle.code.java.dataflow.internal.ModelExclusions as ModelExclusions
|
||||
private import AutomodelSharedUtil as AutomodelSharedUtil
|
||||
private import AutomodelSharedGetCallable as AutomodelSharedGetCallable
|
||||
import AutomodelSharedCharacteristics as SharedCharacteristics
|
||||
import AutomodelEndpointTypes as AutomodelEndpointTypes
|
||||
|
||||
@@ -66,8 +67,8 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig {
|
||||
additional predicate sinkSpec(
|
||||
Endpoint e, string package, string type, string name, string signature, string ext, string input
|
||||
) {
|
||||
FrameworkCandidatesImpl::getCallable(e).hasQualifiedName(package, type, name) and
|
||||
signature = ExternalFlow::paramsString(getCallable(e)) and
|
||||
FrameworkModeGetCallable::getCallable(e).hasQualifiedName(package, type, name) and
|
||||
signature = ExternalFlow::paramsString(FrameworkModeGetCallable::getCallable(e)) and
|
||||
ext = "" and
|
||||
exists(int paramIdx | e.isParameterOf(_, paramIdx) |
|
||||
input = AutomodelSharedUtil::getArgumentForIndex(paramIdx)
|
||||
@@ -81,18 +82,26 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig {
|
||||
*/
|
||||
RelatedLocation getRelatedLocation(Endpoint e, RelatedLocationType type) {
|
||||
type = MethodDoc() and
|
||||
result = FrameworkCandidatesImpl::getCallable(e).(Documentable).getJavadoc()
|
||||
result = FrameworkModeGetCallable::getCallable(e).(Documentable).getJavadoc()
|
||||
or
|
||||
type = ClassDoc() and
|
||||
result = FrameworkCandidatesImpl::getCallable(e).getDeclaringType().(Documentable).getJavadoc()
|
||||
result = FrameworkModeGetCallable::getCallable(e).getDeclaringType().(Documentable).getJavadoc()
|
||||
}
|
||||
}
|
||||
|
||||
private class JavaCallable = Callable;
|
||||
|
||||
private module FrameworkModeGetCallable implements AutomodelSharedGetCallable::GetCallableSig {
|
||||
class Callable = JavaCallable;
|
||||
|
||||
class Endpoint = FrameworkCandidatesImpl::Endpoint;
|
||||
|
||||
/**
|
||||
* Returns the callable that contains the given endpoint.
|
||||
*
|
||||
* Each Java mode should implement this predicate.
|
||||
*/
|
||||
additional Callable getCallable(Endpoint e) { result = e.getEnclosingCallable() }
|
||||
Callable getCallable(Endpoint e) { result = e.getEnclosingCallable() }
|
||||
}
|
||||
|
||||
module CharacteristicsImpl = SharedCharacteristics::SharedCharacteristics<FrameworkCandidatesImpl>;
|
||||
@@ -163,8 +172,8 @@ private class UnexploitableIsCharacteristic extends CharacteristicsImpl::NotASin
|
||||
|
||||
override predicate appliesToEndpoint(Endpoint e) {
|
||||
not FrameworkCandidatesImpl::isSink(e, _) and
|
||||
FrameworkCandidatesImpl::getCallable(e).getName().matches("is%") and
|
||||
FrameworkCandidatesImpl::getCallable(e).getReturnType() instanceof BooleanType
|
||||
FrameworkModeGetCallable::getCallable(e).getName().matches("is%") and
|
||||
FrameworkModeGetCallable::getCallable(e).getReturnType() instanceof BooleanType
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +191,7 @@ private class UnexploitableExistsCharacteristic extends CharacteristicsImpl::Not
|
||||
override predicate appliesToEndpoint(Endpoint e) {
|
||||
not FrameworkCandidatesImpl::isSink(e, _) and
|
||||
exists(Callable callable |
|
||||
callable = FrameworkCandidatesImpl::getCallable(e) and
|
||||
callable = FrameworkModeGetCallable::getCallable(e) and
|
||||
callable.getName().toLowerCase() = ["exists", "notexists"] and
|
||||
callable.getReturnType() instanceof BooleanType
|
||||
)
|
||||
@@ -196,7 +205,7 @@ private class ExceptionCharacteristic extends CharacteristicsImpl::NotASinkChara
|
||||
ExceptionCharacteristic() { this = "exception" }
|
||||
|
||||
override predicate appliesToEndpoint(Endpoint e) {
|
||||
FrameworkCandidatesImpl::getCallable(e).getDeclaringType().getASupertype*() instanceof
|
||||
FrameworkModeGetCallable::getCallable(e).getDeclaringType().getASupertype*() instanceof
|
||||
TypeThrowable
|
||||
}
|
||||
}
|
||||
@@ -222,7 +231,7 @@ private class NonPublicMethodCharacteristic extends CharacteristicsImpl::Uninter
|
||||
NonPublicMethodCharacteristic() { this = "non-public method" }
|
||||
|
||||
override predicate appliesToEndpoint(Endpoint e) {
|
||||
not FrameworkCandidatesImpl::getCallable(e).isPublic()
|
||||
not FrameworkModeGetCallable::getCallable(e).isPublic()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
21
java/ql/src/Telemetry/AutomodelSharedGetCallable.qll
Normal file
21
java/ql/src/Telemetry/AutomodelSharedGetCallable.qll
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* An automodel extraction mode instantiates this interface to define how to access
|
||||
* the callable that's associated with an endpoint.
|
||||
*/
|
||||
signature module GetCallableSig {
|
||||
/**
|
||||
* A callable is the definition of a method, function, etc. - something that can be called.
|
||||
*/
|
||||
class Callable;
|
||||
|
||||
/**
|
||||
* An endpoint is a potential candidate for modeling. This will typically be bound to the language's
|
||||
* DataFlow node class, or a subtype thereof.
|
||||
*/
|
||||
class Endpoint;
|
||||
|
||||
/**
|
||||
* Gets the callable that's associated with the given endpoint.
|
||||
*/
|
||||
Callable getCallable(Endpoint endpoint);
|
||||
}
|
||||
Reference in New Issue
Block a user