Java: share considerSubtypes predicate between Java modes

This commit is contained in:
Stephan Brandauer
2023-06-07 14:55:00 +02:00
parent 7e77e2ea82
commit 715b1351f3
8 changed files with 34 additions and 50 deletions

View File

@@ -14,7 +14,7 @@ private import semmle.code.java.Expr as Expr
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 AutomodelJavaUtil as AutomodelJavaUtil
private import semmle.code.java.security.PathSanitizer as PathSanitizer
private import AutomodelSharedGetCallable as AutomodelSharedGetCallable
import AutomodelSharedCharacteristics as SharedCharacteristics
@@ -65,7 +65,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
RelatedLocation asLocation(Endpoint e) { result = e.asExpr() }
predicate isKnownKind = AutomodelSharedUtil::isKnownKind/3;
predicate isKnownKind = AutomodelJavaUtil::isKnownKind/3;
predicate isSink(Endpoint e, string kind) {
exists(string package, string type, string name, string signature, string ext, string input |
@@ -92,11 +92,11 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
(
exists(Call c, int argIdx |
e.asExpr() = c.getArgument(argIdx) and
input = AutomodelSharedUtil::getArgumentForIndex(argIdx)
input = AutomodelJavaUtil::getArgumentForIndex(argIdx)
)
or
exists(Call c |
e.asExpr() = c.getQualifier() and input = AutomodelSharedUtil::getArgumentForIndex(-1)
e.asExpr() = c.getQualifier() and input = AutomodelJavaUtil::getArgumentForIndex(-1)
)
)
}
@@ -160,23 +160,6 @@ class Endpoint = ApplicationCandidatesImpl::Endpoint;
class ApplicationModeMetadataExtractor extends string {
ApplicationModeMetadataExtractor() { this = "ApplicationModeMetadataExtractor" }
/**
* By convention, the subtypes property of the MaD declaration should only be
* true when there _can_ exist any subtypes with a different implementation.
*
* It would technically be ok to always use the value 'true', but this would
* break convention.
*/
boolean considerSubtypes(Callable callable) {
if
callable.isStatic() or
callable.getDeclaringType().isStatic() or
callable.isFinal() or
callable.getDeclaringType().isFinal()
then result = false
else result = true
}
predicate hasMetadata(
Endpoint e, string package, string type, string subtypes, string name, string signature,
string input
@@ -188,12 +171,12 @@ class ApplicationModeMetadataExtractor extends string {
or
e.asExpr() = call.getQualifier() and argIdx = -1
) and
input = AutomodelSharedUtil::getArgumentForIndex(argIdx) and
input = AutomodelJavaUtil::getArgumentForIndex(argIdx) and
package = callable.getDeclaringType().getPackage().getName() and
// we're using the erased types because the MaD convention is to not specify type parameters.
// Whether something is or isn't a sink doesn't usually depend on the type parameters.
type = callable.getDeclaringType().getErasure().(RefType).nestedName() and
subtypes = this.considerSubtypes(callable).toString() and
subtypes = AutomodelJavaUtil::considerSubtypes(callable).toString() and
name = callable.getName() and
signature = ExternalFlow::paramsString(callable)
)

View File

@@ -11,7 +11,7 @@
private import java
private import AutomodelApplicationModeCharacteristics
private import AutomodelEndpointTypes
private import AutomodelSharedUtil
private import AutomodelJavaUtil
/**
* Gets a sample of endpoints (of at most `limit` samples) for which the given characteristic applies.

View File

@@ -10,7 +10,7 @@
private import AutomodelApplicationModeCharacteristics
private import AutomodelEndpointTypes
private import AutomodelSharedUtil
private import AutomodelJavaUtil
from
Endpoint endpoint, SinkType sinkType, ApplicationModeMetadataExtractor meta,

View File

@@ -14,7 +14,7 @@ private import semmle.code.java.Expr as Expr
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 AutomodelJavaUtil as AutomodelJavaUtil
private import AutomodelSharedGetCallable as AutomodelSharedGetCallable
import AutomodelSharedCharacteristics as SharedCharacteristics
import AutomodelEndpointTypes as AutomodelEndpointTypes
@@ -48,7 +48,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig {
RelatedLocation asLocation(Endpoint e) { result = e.asParameter() }
predicate isKnownKind = AutomodelSharedUtil::isKnownKind/3;
predicate isKnownKind = AutomodelJavaUtil::isKnownKind/3;
predicate isSink(Endpoint e, string kind) {
exists(string package, string type, string name, string signature, string ext, string input |
@@ -71,7 +71,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig {
signature = ExternalFlow::paramsString(FrameworkModeGetCallable::getCallable(e)) and
ext = "" and
exists(int paramIdx | e.isParameterOf(_, paramIdx) |
input = AutomodelSharedUtil::getArgumentForIndex(paramIdx)
input = AutomodelJavaUtil::getArgumentForIndex(paramIdx)
)
}
@@ -120,33 +120,16 @@ class Endpoint = FrameworkCandidatesImpl::Endpoint;
class FrameworkModeMetadataExtractor extends string {
FrameworkModeMetadataExtractor() { this = "FrameworkModeMetadataExtractor" }
/**
* By convention, the subtypes property of the MaD declaration should only be
* true when there _can_ exist any subtypes with a different implementation.
*
* It would technically be ok to always use the value 'true', but this would
* break convention.
*/
boolean considerSubtypes(Callable callable) {
if
callable.isStatic() or
callable.getDeclaringType().isStatic() or
callable.isFinal() or
callable.getDeclaringType().isFinal()
then result = false
else result = true
}
predicate hasMetadata(
Endpoint e, string package, string type, string subtypes, string name, string signature,
string input, string parameterName
) {
exists(Callable callable, int paramIdx |
e.asParameter() = callable.getParameter(paramIdx) and
input = AutomodelSharedUtil::getArgumentForIndex(paramIdx) and
input = AutomodelJavaUtil::getArgumentForIndex(paramIdx) and
package = callable.getDeclaringType().getPackage().getName() and
type = callable.getDeclaringType().getErasure().(RefType).nestedName() and
subtypes = this.considerSubtypes(callable).toString() and
subtypes = AutomodelJavaUtil::considerSubtypes(callable).toString() and
name = callable.getName() and
parameterName = e.asParameter().getName() and
signature = ExternalFlow::paramsString(callable)

View File

@@ -13,7 +13,7 @@
*/
private import AutomodelFrameworkModeCharacteristics
private import AutomodelSharedUtil
private import AutomodelJavaUtil
from
Endpoint endpoint, string message, FrameworkModeMetadataExtractor meta, DollarAtString package,

View File

@@ -10,7 +10,7 @@
private import AutomodelFrameworkModeCharacteristics
private import AutomodelEndpointTypes
private import AutomodelSharedUtil
private import AutomodelJavaUtil
from
Endpoint endpoint, EndpointCharacteristic characteristic, float confidence,

View File

@@ -10,7 +10,7 @@
private import AutomodelFrameworkModeCharacteristics
private import AutomodelEndpointTypes
private import AutomodelSharedUtil
private import AutomodelJavaUtil
from
Endpoint endpoint, SinkType sinkType, FrameworkModeMetadataExtractor meta, DollarAtString package,

View File

@@ -1,3 +1,4 @@
private import java
private import AutomodelEndpointTypes as AutomodelEndpointTypes
/**
@@ -61,3 +62,20 @@ string getArgumentForIndex(int index) {
or
index >= 0 and result = "Argument[" + index + "]"
}
/**
* By convention, the subtypes property of the MaD declaration should only be
* true when there _can_ exist any subtypes with a different implementation.
*
* It would technically be ok to always use the value 'true', but this would
* break convention.
*/
boolean considerSubtypes(Callable callable) {
if
callable.isStatic() or
callable.getDeclaringType().isStatic() or
callable.isFinal() or
callable.getDeclaringType().isFinal()
then result = false
else result = true
}