Python: Port py/stack-trace-exposure to use proper source/sink customization

This commit is contained in:
Rasmus Wriedt Larsen
2021-07-02 15:33:51 +02:00
parent 934007c811
commit 47f5c977cf
3 changed files with 91 additions and 21 deletions

View File

@@ -17,7 +17,7 @@ import python
import semmle.python.security.dataflow.StackTraceExposure
import DataFlow::PathGraph
from StackTraceExposureConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
from StackTraceExposure::Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "$@ may be exposed to an external user", source.getNode(),
"Error information"

View File

@@ -1,33 +1,51 @@
/**
* Provides a taint-tracking configuration for detecting stack trace exposure
* vulnerabilities.
* Provides a taint-tracking configuration for detecting "stack trace exposure" vulnerabilities.
*
* Note, for performance reasons: only import this file if
* `StackTraceExposure::Configuration` is needed, otherwise
* `StackTraceExposureCustomizations` should be imported instead.
*/
import python
private import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import semmle.python.Concepts
import semmle.python.dataflow.new.internal.Attributes
private import ExceptionInfo
/**
* A taint-tracking configuration for detecting stack trace exposure.
* Provides a taint-tracking configuration for detecting "stack trace exposure" vulnerabilities.
*/
class StackTraceExposureConfiguration extends TaintTracking::Configuration {
StackTraceExposureConfiguration() { this = "StackTraceExposureConfiguration" }
module StackTraceExposure {
import StackTraceExposureCustomizations::StackTraceExposure
override predicate isSource(DataFlow::Node source) { source instanceof ExceptionInfo }
/**
* A taint-tracking configuration for detecting "stack trace exposure" vulnerabilities.
*/
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "StackTraceExposure" }
override predicate isSink(DataFlow::Node sink) {
sink = any(HTTP::Server::HttpResponse response).getBody()
}
override predicate isSource(DataFlow::Node source) { source instanceof Source }
// A stack trace is accessible as the `__traceback__` attribute of a caught exception.
// seehttps://docs.python.org/3/reference/datamodel.html#traceback-objects
override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
exists(AttrRead attr | attr.getAttributeName() = "__traceback__" |
nodeFrom = attr.getObject() and
nodeTo = attr
)
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
guard instanceof SanitizerGuard
}
// A stack trace is accessible as the `__traceback__` attribute of a caught exception.
// seehttps://docs.python.org/3/reference/datamodel.html#traceback-objects
override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
exists(DataFlow::AttrRead attr | attr.getAttributeName() = "__traceback__" |
nodeFrom = attr.getObject() and
nodeTo = attr
)
}
}
}
/**
* DEPRECATED: Don't extend this class for customization, since this will lead to bad
* performance, instead use the new `StackTraceExposureCustomizations.qll` file, and extend
* its' classes.
*/
deprecated class StackTraceExposureConfiguration = StackTraceExposure::Configuration;

View File

@@ -0,0 +1,52 @@
/**
* Provides default sources, sinks and sanitizers for detecting
* "stack trace exposure"
* vulnerabilities, as well as extension points for adding your own.
*/
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.Concepts
private import semmle.python.dataflow.new.BarrierGuards
private import ExceptionInfo
/**
* Provides default sources, sinks and sanitizers for detecting
* "stack trace exposure"
* vulnerabilities, as well as extension points for adding your own.
*/
module StackTraceExposure {
/**
* A data flow source for "stack trace exposure" vulnerabilities.
*/
abstract class Source extends DataFlow::Node { }
/**
* A data flow sink for "stack trace exposure" vulnerabilities.
*/
abstract class Sink extends DataFlow::Node { }
/**
* A sanitizer for "stack trace exposure" vulnerabilities.
*/
abstract class Sanitizer extends DataFlow::Node { }
/**
* A sanitizer guard for "stack trace exposure" vulnerabilities.
*/
abstract class SanitizerGuard extends DataFlow::BarrierGuard { }
/**
* A source of exception info, considered as a flow source.
*/
class ExceptionInfoAsSource extends Source {
ExceptionInfoAsSource() { this instanceof ExceptionInfo }
}
/**
* The body of a HTTP response that will be returned from a server, considered as a flow sink.
*/
class ServerHttpResponseBodyAsSink extends Sink {
ServerHttpResponseBodyAsSink() { this = any(HTTP::Server::HttpResponse response).getBody() }
}
}