Exclude known internal APIs from being modeled

This commit is contained in:
Benjamin Muskalla
2021-10-08 12:30:21 +02:00
parent 6b2460d4a1
commit 2654e27123
5 changed files with 35 additions and 28 deletions

View File

@@ -17,10 +17,11 @@ class PropagateToSinkConfiguration extends TaintTracking::Configuration {
override predicate isSource(DataFlow::Node source) {
source instanceof DataFlow::ParameterNode and
source.asParameter().getCallable().isPublic() and
source.asParameter().getCallable().getDeclaringType().isPublic()
source.asParameter().getCallable().getDeclaringType().isPublic() and
isRelevantForModels(source.getEnclosingCallable())
}
override predicate isSink(DataFlow::Node sink) { sinkNode(sink, _) }
override predicate isSink(DataFlow::Node sink) { sinkNode(sink, _)}
}
string asInputArgument(DataFlow::Node source) {
@@ -36,8 +37,7 @@ string captureSink(Callable api) {
)
}
from Callable api, string sink
from TargetAPI api, string sink
where
sink = captureSink(api) and
not isInTestFile(api)
sink = captureSink(api)
select sink order by sink

View File

@@ -47,8 +47,7 @@ string captureSource(Callable api) {
)
}
from Callable api, string sink
from TargetAPI api, string sink
where
sink = captureSource(api) and
not isInTestFile(api)
sink = captureSource(api)
select sink order by sink

View File

@@ -9,6 +9,7 @@ import ModelGeneratorUtils
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.internal.DataFlowImplCommon
import semmle.code.java.dataflow.internal.DataFlowNodes
import ModelGeneratorUtils
string captureFlow(Callable api) {
result = captureQualifierFlow(api) or
@@ -123,15 +124,6 @@ string captureParameterToParameterFlow(Callable api) {
// TODO: infer interface from multiple implementations? e.g. UriComponentsContributor
// TODO: distinguish between taint and value flows. If we find a value flow, omit the taint flow
// TODO: merge param->return value with param->parameter flow?
class TargetAPI extends Callable {
TargetAPI() {
this.isPublic() and
this.fromSource() and
this.getDeclaringType().isPublic() and
not isInTestFile(this)
}
}
from TargetAPI api, string flow
where flow = captureFlow(api)
select flow order by flow

View File

@@ -1,12 +1,9 @@
#!/usr/bin/python3
import errno
import json
import os
import os.path
import re
import shlex
import shutil
import subprocess
import sys
import tempfile

View File

@@ -2,7 +2,32 @@ import java
import semmle.code.java.dataflow.ExternalFlow
import semmle.code.java.dataflow.internal.ContainerFlow
string isExtensible(RefType ref) { if ref.isFinal() then result = "false" else result = "true" }
class TargetAPI extends Callable {
TargetAPI() {
this.isPublic() and
this.fromSource() and
this.getDeclaringType().isPublic() and
isRelevantForModels(this)
}
}
private string isExtensible(RefType ref) { if ref.isFinal() then result = "false" else result = "true" }
predicate isRelevantForModels(Callable api) {
not isInTestFile(api.getCompilationUnit().getFile()) and
not isJdkInternal(api.getCompilationUnit())
}
private predicate isInTestFile(File file) {
file.getAbsolutePath().matches("%src/test/%") or
file.getAbsolutePath().matches("%/guava-tests/%") or
file.getAbsolutePath().matches("%/guava-testlib/%")
}
private predicate isJdkInternal(CompilationUnit cu) {
cu.getPackage().getName().matches("com.sun") or cu.getPackage().getName().matches("sun") or cu.getPackage().getName().matches("")
}
bindingset[input, output]
string asTaintModel(Callable api, string input, string output) {
@@ -56,10 +81,4 @@ string parameterAccess(Parameter p) {
if p.getType() instanceof ContainerType
then result = "Element of Argument[" + p.getPosition() + "]"
else result = "Argument[" + p.getPosition() + "]"
}
predicate isInTestFile(Callable api) {
api.getCompilationUnit().getFile().getAbsolutePath().matches("%src/test/%") or
api.getCompilationUnit().getFile().getAbsolutePath().matches("%/guava-tests/%") or
api.getCompilationUnit().getFile().getAbsolutePath().matches("%/guava-testlib/%")
}
}