Files
codeql/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeDynamicMethodAccessCustomizations.qll
2024-12-16 15:35:44 +01:00

114 lines
3.5 KiB
Plaintext

/**
* Provides default sources, sinks and sanitizers for reasoning about
* method invocations with a user-controlled method name on objects
* with unsafe methods, as well as extension points for adding your
* own.
*/
import javascript
import semmle.javascript.frameworks.Express
import PropertyInjectionShared
module UnsafeDynamicMethodAccess {
private newtype TFlowState =
TTaint() or
TUnsafeFunction()
/** A flow state to associate with a tracked value. */
class FlowState extends TFlowState {
/** Gets a string representation fo this flow state */
string toString() {
this = TTaint() and result = "taint"
or
this = TUnsafeFunction() and result = "unsafe-function"
}
/** Gets the corresponding flow label. */
deprecated DataFlow::FlowLabel toFlowLabel() {
this = TTaint() and result.isTaint()
or
this = TUnsafeFunction() and result instanceof UnsafeFunction
}
}
/** Predicates for working with flow states. */
module FlowState {
/** Gets the flow state corresponding to `label`. */
deprecated FlowState fromFlowLabel(DataFlow::FlowLabel label) { result.toFlowLabel() = label }
/** A tainted value. */
FlowState taint() { result = TTaint() }
/** A reference to an unsafe function, such as `eval`, obtained by reading from a tainted property name. */
FlowState unsafeFunction() { result = TUnsafeFunction() }
}
/**
* A data flow source for unsafe dynamic method access.
*/
abstract class Source extends DataFlow::Node {
/**
* Gets a flow state relevant for this source.
*/
FlowState getAFlowState() { result = FlowState::taint() }
/** DEPRECATED. Use `getAFlowState()` instead. */
deprecated DataFlow::FlowLabel getFlowLabel() { result = this.getAFlowState().toFlowLabel() }
}
/**
* A data flow sink for unsafe dynamic method access.
*/
abstract class Sink extends DataFlow::Node {
/**
* Gets a flow state relevant for this sink.
*/
FlowState getAFlowState() { result = FlowState::taint() }
/** DEPRECATED. Use `getAFlowState()` instead. */
deprecated DataFlow::FlowLabel getFlowLabel() { result = this.getAFlowState().toFlowLabel() }
}
/**
* A sanitizer for unsafe dynamic method access.
*/
abstract class Sanitizer extends DataFlow::Node { }
/**
* DEPRECATED. Use `FlowState::unsafeFunction()` instead.
*
* Gets the flow label describing values that may refer to an unsafe
* function as a result of an attacker-controlled property name.
*/
deprecated UnsafeFunction unsafeFunction() { any() }
/**
* DEPRECATED. Use `FlowState::unsafeFunction()` instead.
*
* A flow label describing values that may refer to an unsafe
* function as a result of an attacker-controlled property name.
*/
abstract deprecated class UnsafeFunction extends DataFlow::FlowLabel {
UnsafeFunction() { this = "UnsafeFunction" }
}
/**
* DEPRECATED: Use `ActiveThreatModelSource` from Concepts instead!
*/
deprecated class RemoteFlowSourceAsSource = ActiveThreatModelSourceAsSource;
/**
* An active threat-model source, considered as a flow source.
*/
private class ActiveThreatModelSourceAsSource extends Source, ActiveThreatModelSource { }
/**
* A function invocation of an unsafe function, as a sink for remote unsafe dynamic method access.
*/
class CalleeAsSink extends Sink {
CalleeAsSink() { this = any(DataFlow::InvokeNode node).getCalleeNode() }
override FlowState getAFlowState() { result = FlowState::unsafeFunction() }
}
}