mirror of
https://github.com/github/codeql.git
synced 2025-12-18 01:33:15 +01:00
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @id py/examples/override-method
|
||||
* @name Override of method
|
||||
* @description Finds methods that overide MyClass.methodName
|
||||
* @description Finds methods that override MyClass.methodName
|
||||
* @tags method
|
||||
* override
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added the ability to refer to subscript operations in the API graph. It is now possible to write `response().getMember("cookies").getASubscript()` to find code like `resp.cookies["key"]` (assuming `response` returns an API node for reponse objects).
|
||||
* Added the ability to refer to subscript operations in the API graph. It is now possible to write `response().getMember("cookies").getASubscript()` to find code like `resp.cookies["key"]` (assuming `response` returns an API node for response objects).
|
||||
* Added modeling of creating Flask responses with `flask.jsonify`.
|
||||
|
||||
## 0.6.0
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added the ability to refer to subscript operations in the API graph. It is now possible to write `response().getMember("cookies").getASubscript()` to find code like `resp.cookies["key"]` (assuming `response` returns an API node for reponse objects).
|
||||
* Added the ability to refer to subscript operations in the API graph. It is now possible to write `response().getMember("cookies").getASubscript()` to find code like `resp.cookies["key"]` (assuming `response` returns an API node for response objects).
|
||||
* Added modeling of creating Flask responses with `flask.jsonify`.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# The Python libraries
|
||||
|
||||
The Python libraries are a collection of libraries for analysing Python code.
|
||||
Everythng can be imported by importing `python.qll`.
|
||||
Everything can be imported by importing `python.qll`.
|
||||
|
||||
## The analysis layers
|
||||
|
||||
@@ -15,10 +15,10 @@ The analysis is built up in layers. the stack looks like this:
|
||||
|
||||
## Avoiding non-monotonic recursion
|
||||
|
||||
Given the many interactivg layers, it is imprtant to decie which predicates are allowed to be mutually recursive in order to avoid non-monotonic recursion when negation is used to express the predicates.
|
||||
As an example, we have defined local source as those whcih do not receive local flow. This means that the local flow relation is not allowed to be recursive with anything depending on local sources.
|
||||
Given the many interacting layers, it is important to decide which predicates are allowed to be mutually recursive in order to avoid non-monotonic recursion when negation is used to express the predicates.
|
||||
As an example, we have defined local source as those which do not receive local flow. This means that the local flow relation is not allowed to be recursive with anything depending on local sources.
|
||||
|
||||
Some particular reatrictions to keep in mind:
|
||||
Some particular restrictions to keep in mind:
|
||||
|
||||
- Typetracking needs to use a local flow step not including summaries
|
||||
- Typetracking needs to use a call graph not including summaries
|
||||
|
||||
@@ -211,7 +211,7 @@ module API {
|
||||
* Gets a node representing the `i`th parameter of the function represented by this node.
|
||||
*
|
||||
* This predicate may have multiple results when there are multiple invocations of this API component.
|
||||
* Consider using `getAnInvocation()` if there is a need to distingiush between individual calls.
|
||||
* Consider using `getAnInvocation()` if there is a need to distinguish between individual calls.
|
||||
*/
|
||||
Node getParameter(int i) { result = this.getASuccessor(Label::parameter(i)) }
|
||||
|
||||
@@ -219,7 +219,7 @@ module API {
|
||||
* Gets the node representing the keyword parameter `name` of the function represented by this node.
|
||||
*
|
||||
* This predicate may have multiple results when there are multiple invocations of this API component.
|
||||
* Consider using `getAnInvocation()` if there is a need to distingiush between individual calls.
|
||||
* Consider using `getAnInvocation()` if there is a need to distinguish between individual calls.
|
||||
*/
|
||||
Node getKeywordParameter(string name) {
|
||||
result = this.getASuccessor(Label::keywordParameter(name))
|
||||
|
||||
@@ -7,7 +7,7 @@ int major_version() {
|
||||
explicit_major_version(result)
|
||||
or
|
||||
not explicit_major_version(_) and
|
||||
/* If there is more than one version, prefer 2 for backwards compatibilty */
|
||||
/* If there is more than one version, prefer 2 for backwards compatibility */
|
||||
(if py_flags_versioned("version.major", "2", "2") then result = 2 else result = 3)
|
||||
}
|
||||
|
||||
|
||||
@@ -931,7 +931,7 @@ class NameConstantNode extends NameNode {
|
||||
|
||||
}
|
||||
|
||||
/** A control flow node correspoinding to a starred expression, `*a`. */
|
||||
/** A control flow node corresponding to a starred expression, `*a`. */
|
||||
class StarredNode extends ControlFlowNode {
|
||||
StarredNode() { toAst(this) instanceof Starred }
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Provides an extension point for for modeling user-controlled data.
|
||||
* Provides an extension point for modeling user-controlled data.
|
||||
* Such data is often used as data-flow sources in security queries.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Provides an extension point for for modeling sensitive data, such as secrets, certificates, or passwords.
|
||||
* Provides an extension point for modeling sensitive data, such as secrets, certificates, or passwords.
|
||||
* Sensitive data can be interesting to use as data-flow sources in security queries.
|
||||
*/
|
||||
|
||||
|
||||
@@ -205,12 +205,12 @@ module ArgumentPassing {
|
||||
result = TCfgNode(call.getArgByName(unbind_string(argName)))
|
||||
)
|
||||
or
|
||||
// a synthezised argument passed to the starred parameter (at position -1)
|
||||
// a synthesized argument passed to the starred parameter (at position -1)
|
||||
callable.getScope().hasVarArg() and
|
||||
paramN = -1 and
|
||||
result = TPosOverflowNode(call, callable)
|
||||
or
|
||||
// a synthezised argument passed to the doubly starred parameter (at position -2)
|
||||
// a synthesized argument passed to the doubly starred parameter (at position -2)
|
||||
callable.getScope().hasKwArg() and
|
||||
paramN = -2 and
|
||||
result = TKwOverflowNode(call, callable)
|
||||
@@ -769,7 +769,7 @@ DataFlowCallable viableCallable(ExtractedDataFlowCall call) {
|
||||
// A call to a library callable with a flow summary
|
||||
// In this situation we can not resolve the callable from the call,
|
||||
// as that would make data flow depend on type tracking.
|
||||
// Instead we reolve the call from the summary.
|
||||
// Instead we resolve the call from the summary.
|
||||
exists(LibraryCallable callable |
|
||||
result = TLibraryCallable(callable) and
|
||||
call.getNode() = callable.getACall().getNode()
|
||||
|
||||
@@ -461,7 +461,7 @@ predicate jumpStep(Node nodeFrom, Node nodeTo) {
|
||||
* Set of jumpSteps that are shared with type-tracker implementation.
|
||||
*
|
||||
* For ORM modeling we want to add jumpsteps to global dataflow, but since these are
|
||||
* based on type-trackers, it's important that these new ORM jumsteps are not used in
|
||||
* based on type-trackers, it's important that these new ORM jumpsteps are not used in
|
||||
* the type-trackers as well, as that would make evaluation of type-tracking recursive
|
||||
* with the new jumpsteps.
|
||||
*
|
||||
@@ -487,7 +487,7 @@ predicate jumpStepSharedWithTypeTracker(Node nodeFrom, Node nodeTo) {
|
||||
* Set of jumpSteps that are NOT shared with type-tracker implementation.
|
||||
*
|
||||
* For ORM modeling we want to add jumpsteps to global dataflow, but since these are
|
||||
* based on type-trackers, it's important that these new ORM jumsteps are not used in
|
||||
* based on type-trackers, it's important that these new ORM jumpsteps are not used in
|
||||
* the type-trackers as well, as that would make evaluation of type-tracking recursive
|
||||
* with the new jumpsteps.
|
||||
*
|
||||
@@ -670,7 +670,7 @@ predicate attributeStoreStep(Node nodeFrom, AttributeContent c, PostUpdateNode n
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `nodeFrom` flows into the synthezised positional overflow argument (`nodeTo`)
|
||||
* Holds if `nodeFrom` flows into the synthesized positional overflow argument (`nodeTo`)
|
||||
* at the position indicated by `c`.
|
||||
*/
|
||||
predicate posOverflowStoreStep(CfgNode nodeFrom, TupleElementContent c, Node nodeTo) {
|
||||
@@ -682,7 +682,7 @@ predicate posOverflowStoreStep(CfgNode nodeFrom, TupleElementContent c, Node nod
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `nodeFrom` flows into the synthezised keyword overflow argument (`nodeTo`)
|
||||
* Holds if `nodeFrom` flows into the synthesized keyword overflow argument (`nodeTo`)
|
||||
* at the key indicated by `c`.
|
||||
*/
|
||||
predicate kwOverflowStoreStep(CfgNode nodeFrom, DictionaryElementContent c, Node nodeTo) {
|
||||
@@ -816,7 +816,7 @@ predicate attributeReadStep(Node nodeFrom, AttributeContent c, AttrRead nodeTo)
|
||||
|
||||
/**
|
||||
* Holds if `nodeFrom` is a dictionary argument being unpacked and `nodeTo` is the
|
||||
* synthezised unpacked argument with the name indicated by `c`.
|
||||
* synthesized unpacked argument with the name indicated by `c`.
|
||||
*/
|
||||
predicate kwUnpackReadStep(CfgNode nodeFrom, DictionaryElementContent c, Node nodeTo) {
|
||||
exists(CallNode call, CallableValue callable, string name |
|
||||
|
||||
@@ -12,15 +12,15 @@
|
||||
*
|
||||
* Having both extracted and non-extracted callables means that we now have three types of calls:
|
||||
* - Extracted calls to extracted callables, either `NormalCall` or `SpecialCall`. These are handled by standard data flow.
|
||||
* - Extracted calls to non-extracted callables, `LibraryCall`. These are handled by loking up the relevant summary when the
|
||||
* global data flwo graph is connected up via `getViableCallable`.
|
||||
* - Extracted calls to non-extracted callables, `LibraryCall`. These are handled by looking up the relevant summary when the
|
||||
* global data flow graph is connected up via `getViableCallable`.
|
||||
* - Non-extracted calls, `SummaryCall`. These are synthesised by the flow summary framework.
|
||||
*
|
||||
* The first two can be referred to as `ExtractedDataFlowCall`. In fact, `LibraryCall` is a subclass of `NormalCall`, where
|
||||
* `getCallable` is set to `none()`. The member predicate `ExtractedDataFlowCall::getCallable` is _not_ the mechanism for
|
||||
* call resolution in global data flow. That mechanism is `getViableCallable`.
|
||||
* Resolving a call to a non-extracted callable goes via `LibraryCallable::getACall`, which may involve type tracking.
|
||||
* To avoid that type tracking becomes mutualy recursive with data flow, type tracking must use a call graph not including summaries.
|
||||
* To avoid that type tracking becomes mutually recursive with data flow, type tracking must use a call graph not including summaries.
|
||||
* Type tracking sees the callgraph given by `ExtractedDataFlowCall::getACallable`.
|
||||
*
|
||||
* We do not support summaries of special methods via the special methods framework,
|
||||
|
||||
@@ -52,14 +52,14 @@
|
||||
* Note that an empty access path means that the value we are tracking flows directly to the element.
|
||||
*
|
||||
*
|
||||
* The `TIterableSequence(sequence)` is at this point superflous but becomes useful when handling recursive
|
||||
* The `TIterableSequence(sequence)` is at this point superfluous but becomes useful when handling recursive
|
||||
* structures in the LHS, where `sequence` is some internal sequence node. We can have a uniform treatment
|
||||
* by always having these two synthetic nodes. So we transfer to (or, in the recursive case, read into)
|
||||
* `TIterableSequence(sequence)`, from which we take a read step to `TIterableElement(sequence)` and then a
|
||||
* store step to `sequence`.
|
||||
*
|
||||
* This allows the unknown content from the RHS to be read into `TIterableElement(sequence)` and tuple content
|
||||
* to then be stored into `sequence`. If the content is already tuple content, this inderection creates crosstalk
|
||||
* to then be stored into `sequence`. If the content is already tuple content, this indirection creates crosstalk
|
||||
* between indices. Therefore, tuple content is never read into `TIterableElement(sequence)`; it is instead
|
||||
* transferred directly from `TIterableSequence(sequence)` to `sequence` via a flow step. Such a flow step will
|
||||
* also transfer other content, but only tuple content is further read from `sequence` into its elements.
|
||||
|
||||
@@ -185,7 +185,7 @@ private module Cached {
|
||||
/**
|
||||
* Holds if `source` is a `LocalSourceNode` that can reach `sink` via local flow steps.
|
||||
*
|
||||
* The slightly backwards parametering ordering is to force correct indexing.
|
||||
* The slightly backwards parameter ordering is to force correct indexing.
|
||||
*/
|
||||
cached
|
||||
predicate hasLocalSource(Node sink, LocalSourceNode source) {
|
||||
|
||||
@@ -250,7 +250,7 @@ class TaintTrackingImplementation extends string {
|
||||
}
|
||||
|
||||
/**
|
||||
* Hold if taint flows to `src` to `(node, context, path, kind)` in a single step, labelled with `egdeLabel` with this configuration.
|
||||
* Hold if taint flows to `src` to `(node, context, path, kind)` in a single step, labelled with `edgeLabel` with this configuration.
|
||||
* `edgeLabel` is purely informative.
|
||||
*/
|
||||
predicate flowStep(
|
||||
|
||||
@@ -31,7 +31,7 @@ module Aioch {
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to any of the the execute methods on a `aioch.Client`, which are just async
|
||||
* A call to any of the execute methods on a `aioch.Client`, which are just async
|
||||
* versions of the methods in the `clickhouse-driver` PyPI package.
|
||||
*
|
||||
* See
|
||||
|
||||
@@ -45,7 +45,7 @@ module AiohttpWebModel {
|
||||
}
|
||||
|
||||
/** Gets a reference to an `aiohttp.web.UrlDispatcher` instance. */
|
||||
API::Node urlDispathcerInstance() {
|
||||
API::Node urlDispatcherInstance() {
|
||||
result = API::moduleImport("aiohttp").getMember("web").getMember("UrlDispatcher").getReturn()
|
||||
or
|
||||
result = applicationInstance().getMember("router")
|
||||
@@ -170,7 +170,7 @@ module AiohttpWebModel {
|
||||
funcName = "route" and
|
||||
routeArgsStart = 1
|
||||
|
|
||||
this = urlDispathcerInstance().getMember("add_" + funcName).getACall()
|
||||
this = urlDispatcherInstance().getMember("add_" + funcName).getACall()
|
||||
or
|
||||
this = API::moduleImport("aiohttp").getMember("web").getMember(funcName).getACall()
|
||||
)
|
||||
|
||||
@@ -98,10 +98,10 @@ private module Aiopg {
|
||||
* See https://aiopg.readthedocs.io/en/stable/sa.html#aiopg.sa.SAConnection.execute
|
||||
*/
|
||||
class AwaitedSAConnectionExecuteCall extends SqlExecution::Range {
|
||||
SAConnectionExecuteCall excute;
|
||||
SAConnectionExecuteCall execute;
|
||||
|
||||
AwaitedSAConnectionExecuteCall() { this = excute.getReturn().getAwaited().asSource() }
|
||||
AwaitedSAConnectionExecuteCall() { this = execute.getReturn().getAwaited().asSource() }
|
||||
|
||||
override DataFlow::Node getSql() { result = excute.getSql() }
|
||||
override DataFlow::Node getSql() { result = execute.getSql() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ module ClickhouseDriver {
|
||||
string getExecuteMethodName() { result in ["execute_with_progress", "execute", "execute_iter"] }
|
||||
|
||||
/**
|
||||
* A call to any of the the execute methods on a `clickhouse_driver.Client` method
|
||||
* A call to any of the execute methods on a `clickhouse_driver.Client` method
|
||||
*
|
||||
* See
|
||||
* - https://clickhouse-driver.readthedocs.io/en/latest/api.html#clickhouse_driver.Client.execute
|
||||
|
||||
@@ -14,7 +14,7 @@ private import semmle.python.ApiGraphs
|
||||
*/
|
||||
private module CryptographyModel {
|
||||
/**
|
||||
* Provides helper predicates for the eliptic curve cryptography parts in
|
||||
* Provides helper predicates for the elliptic curve cryptography parts in
|
||||
* `cryptography.hazmat.primitives.asymmetric.ec`.
|
||||
*/
|
||||
module Ecc {
|
||||
|
||||
@@ -65,7 +65,7 @@ module Pydantic {
|
||||
* NOTE: We currently overapproximate, and treat all attributes as containing
|
||||
* another pydantic model. For the code below, we _could_ limit this to `main_foo`
|
||||
* and members of `other_foos`. IF THIS IS CHANGED, YOU MUST CHANGE THE ADDITIONAL
|
||||
* TAINT STEPS BELOW, SUCH THAT SIMPLE ACCESS OF SOMETHIGN LIKE `str` IS STILL
|
||||
* TAINT STEPS BELOW, SUCH THAT SIMPLE ACCESS OF SOMETHING LIKE `str` IS STILL
|
||||
* TAINTED.
|
||||
*
|
||||
*
|
||||
|
||||
@@ -113,7 +113,7 @@ private module Requests {
|
||||
ClassInstantiation() { this = classRef().getACall() }
|
||||
}
|
||||
|
||||
/** Return value from making a reuqest. */
|
||||
/** Return value from making a request. */
|
||||
private class RequestReturnValue extends InstanceSource, DataFlow::Node {
|
||||
RequestReturnValue() { this = any(OutgoingRequestCall c) }
|
||||
}
|
||||
|
||||
@@ -2403,7 +2403,7 @@ private module StdlibPrivate {
|
||||
|
||||
/**
|
||||
* Gets a name of a constructor for a `pathlib.Path` object.
|
||||
* We include the pure paths, as they can be "exported" (say with `as_posix`) and then used to acces the underlying file system.
|
||||
* We include the pure paths, as they can be "exported" (say with `as_posix`) and then used to access the underlying file system.
|
||||
*/
|
||||
private string pathlibPathConstructor() {
|
||||
result in ["Path", "PurePath", "PurePosixPath", "PureWindowsPath", "PosixPath", "WindowsPath"]
|
||||
@@ -2510,11 +2510,11 @@ private module StdlibPrivate {
|
||||
/** A file system access from a `pathlib.Path` method call. */
|
||||
private class PathlibFileAccess extends FileSystemAccess::Range, DataFlow::CallCfgNode {
|
||||
DataFlow::AttrRead fileAccess;
|
||||
string attrbuteName;
|
||||
string attributeName;
|
||||
|
||||
PathlibFileAccess() {
|
||||
attrbuteName = fileAccess.getAttributeName() and
|
||||
attrbuteName in [
|
||||
attributeName = fileAccess.getAttributeName() and
|
||||
attributeName in [
|
||||
"stat", "chmod", "exists", "expanduser", "glob", "group", "is_dir", "is_file", "is_mount",
|
||||
"is_symlink", "is_socket", "is_fifo", "is_block_device", "is_char_device", "iter_dir",
|
||||
"lchmod", "lstat", "mkdir", "open", "owner", "read_bytes", "read_text", "readlink",
|
||||
@@ -2530,14 +2530,14 @@ private module StdlibPrivate {
|
||||
|
||||
/** A file system write from a `pathlib.Path` method call. */
|
||||
private class PathlibFileWrites extends PathlibFileAccess, FileSystemWriteAccess::Range {
|
||||
PathlibFileWrites() { attrbuteName in ["write_bytes", "write_text"] }
|
||||
PathlibFileWrites() { attributeName in ["write_bytes", "write_text"] }
|
||||
|
||||
override DataFlow::Node getADataNode() { result in [this.getArg(0), this.getArgByName("data")] }
|
||||
}
|
||||
|
||||
/** A call to the `open` method on a `pathlib.Path` instance. */
|
||||
private class PathLibOpenCall extends PathlibFileAccess, Stdlib::FileLikeObject::InstanceSource {
|
||||
PathLibOpenCall() { attrbuteName = "open" }
|
||||
PathLibOpenCall() { attributeName = "open" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2549,7 +2549,7 @@ private module StdlibPrivate {
|
||||
* - https://docs.python.org/3/library/pathlib.html#pathlib.Path.symlink_to
|
||||
*/
|
||||
private class PathLibLinkToCall extends PathlibFileAccess, API::CallNode {
|
||||
PathLibLinkToCall() { attrbuteName in ["link_to", "hardlink_to", "symlink_to"] }
|
||||
PathLibLinkToCall() { attributeName in ["link_to", "hardlink_to", "symlink_to"] }
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result = super.getAPathArgument()
|
||||
@@ -2566,7 +2566,7 @@ private module StdlibPrivate {
|
||||
* - https://docs.python.org/3/library/pathlib.html#pathlib.Path.rename
|
||||
*/
|
||||
private class PathLibReplaceCall extends PathlibFileAccess, API::CallNode {
|
||||
PathLibReplaceCall() { attrbuteName in ["replace", "rename"] }
|
||||
PathLibReplaceCall() { attributeName in ["replace", "rename"] }
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result = super.getAPathArgument()
|
||||
@@ -2581,7 +2581,7 @@ private module StdlibPrivate {
|
||||
* See https://docs.python.org/3/library/pathlib.html#pathlib.Path.samefile
|
||||
*/
|
||||
private class PathLibSameFileCall extends PathlibFileAccess, API::CallNode {
|
||||
PathLibSameFileCall() { attrbuteName = "samefile" }
|
||||
PathLibSameFileCall() { attributeName = "samefile" }
|
||||
|
||||
override DataFlow::Node getAPathArgument() {
|
||||
result = super.getAPathArgument()
|
||||
@@ -2720,7 +2720,7 @@ private module StdlibPrivate {
|
||||
|
||||
/**
|
||||
* A hashing operation from the `hashlib` package using one of the predefined classes
|
||||
* (such as `hashlib.md5`), by calling its' `update` mehtod.
|
||||
* (such as `hashlib.md5`), by calling its' `update` method.
|
||||
*/
|
||||
class HashlibHashClassUpdateCall extends HashlibGenericHashOperation {
|
||||
HashlibHashClassUpdateCall() { this = hashClass.getReturn().getMember("update").getACall() }
|
||||
|
||||
@@ -10,7 +10,7 @@ private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
|
||||
/**
|
||||
* Provides models for the the `urllib2` module, part of
|
||||
* Provides models for the `urllib2` module, part of
|
||||
* the Python 2 standard library.
|
||||
*
|
||||
* See https://docs.python.org/2/library/urllib2.html
|
||||
|
||||
@@ -68,9 +68,9 @@ private module NotExposed {
|
||||
// modeling. See https://github.com/github/codeql/pull/5632 for more discussion.
|
||||
//
|
||||
//
|
||||
bindingset[fullyQaulified]
|
||||
string fullyQualifiedToApiGraphPath(string fullyQaulified) {
|
||||
result = "moduleImport(\"" + fullyQaulified.replaceAll(".", "\").getMember(\"") + "\")"
|
||||
bindingset[fullyQualified]
|
||||
string fullyQualifiedToApiGraphPath(string fullyQualified) {
|
||||
result = "moduleImport(\"" + fullyQualified.replaceAll(".", "\").getMember(\"") + "\")"
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for fullyQualifiedToApiGraphPath */
|
||||
|
||||
@@ -324,7 +324,7 @@ module Value {
|
||||
Value none_() { result = ObjectInternal::none_() }
|
||||
|
||||
/**
|
||||
* Shorcuts added by the `site` module to exit your interactive session.
|
||||
* Shortcuts added by the `site` module to exit your interactive session.
|
||||
*
|
||||
* see https://docs.python.org/3/library/constants.html#constants-added-by-the-site-module
|
||||
*/
|
||||
|
||||
@@ -1177,7 +1177,7 @@ module InterProceduralPointsTo {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if the named `argument` given the context `caller` is transferred to the parameter `param` with conntext `callee` by a call. */
|
||||
/** Holds if the named `argument` given the context `caller` is transferred to the parameter `param` with context `callee` by a call. */
|
||||
cached
|
||||
predicate named_argument_transfer(
|
||||
ControlFlowNode argument, PointsToContext caller, ParameterDefinition param,
|
||||
|
||||
@@ -283,7 +283,7 @@ abstract class RegexString extends Expr {
|
||||
|
||||
/**
|
||||
* Helper predicate for `escapingChar`.
|
||||
* In order to avoid negative recusrion, we return a boolean.
|
||||
* In order to avoid negative recursion, we return a boolean.
|
||||
* This way, we can refer to `escaping(pos - 1).booleanNot()`
|
||||
* rather than to a negated version of `escaping(pos)`.
|
||||
*/
|
||||
|
||||
@@ -28,7 +28,7 @@ class Configuration extends TaintTracking::Configuration {
|
||||
}
|
||||
|
||||
// A stack trace is accessible as the `__traceback__` attribute of a caught exception.
|
||||
// seehttps://docs.python.org/3/reference/datamodel.html#traceback-objects
|
||||
// see https://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
|
||||
|
||||
@@ -28,7 +28,7 @@ def f(): pass
|
||||
is equivalent to f = dec(x)(f)
|
||||
but in a context-insensitive context.
|
||||
Need a method:
|
||||
Object decoratored_function(Object decorator, Object undecorated);
|
||||
Object decorated_function(Object decorator, Object undecorated);
|
||||
But what is the decorator and what object is available as a result?
|
||||
Need to create an object for each decorator of a class or function.
|
||||
That should be the actual Object.
|
||||
|
||||
@@ -63,7 +63,7 @@ class InsecureContextConfiguration extends DataFlow::Configuration {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `conectionCreation` marks the creation of a connetion based on the contex
|
||||
* Holds if `conectionCreation` marks the creation of a connection based on the contex
|
||||
* found at `contextOrigin` and allowing `insecure_version`.
|
||||
*
|
||||
* `specific` is true iff the context is configured for a specific protocol version (`ssl.PROTOCOL_TLSv1_2`) rather
|
||||
@@ -88,7 +88,7 @@ predicate unsafe_connection_creation_with_context(
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `conectionCreation` marks the creation of a connetion witout reference to a context
|
||||
* Holds if `conectionCreation` marks the creation of a connection without reference to a context
|
||||
* and allowing `insecure_version`.
|
||||
*/
|
||||
predicate unsafe_connection_creation_without_context(
|
||||
|
||||
@@ -15,7 +15,7 @@ import semmle.python.dataflow.new.DataFlow
|
||||
import FluentApiModel
|
||||
|
||||
// Helper for pretty printer `configName`.
|
||||
// This is a consequence of missing pretty priting.
|
||||
// This is a consequence of missing pretty printing.
|
||||
// We do not want to evaluate our bespoke pretty printer
|
||||
// for all `DataFlow::Node`s so we define a sub class of interesting ones.
|
||||
class ProtocolConfiguration extends DataFlow::Node {
|
||||
@@ -31,7 +31,7 @@ class ProtocolConfiguration extends DataFlow::Node {
|
||||
}
|
||||
|
||||
// Helper for pretty printer `callName`.
|
||||
// This is a consequence of missing pretty priting.
|
||||
// This is a consequence of missing pretty printing.
|
||||
// We do not want to evaluate our bespoke pretty printer
|
||||
// for all `DataFlow::Node`s so we define a sub class of interesting ones.
|
||||
class Nameable extends DataFlow::Node {
|
||||
|
||||
@@ -14,7 +14,7 @@ This should be kept up to date; the world is moving fast and protocols are being
|
||||
> Deprecated since version 3.7: Since Python 3.2 and 2.7.9, it is recommended to use the `SSLContext.wrap_socket()` instead of `wrap_socket()`. The top-level function is limited and creates an insecure client socket without server name indication or hostname matching.
|
||||
- Default constructors are fine, a fluent API is used to constrain possible protocols later.
|
||||
|
||||
## Current recomendation
|
||||
## Current recommendation
|
||||
|
||||
TLS 1.2 or TLS 1.3
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ private string getACredentialRegex() {
|
||||
}
|
||||
|
||||
class HardcodedCredentialsConfiguration extends TaintTracking::Configuration {
|
||||
HardcodedCredentialsConfiguration() { this = "Hardcoded coredentials configuration" }
|
||||
HardcodedCredentialsConfiguration() { this = "Hardcoded credentials configuration" }
|
||||
|
||||
override predicate isSource(TaintTracking::Source source) {
|
||||
source instanceof HardcodedValueSource
|
||||
|
||||
@@ -55,7 +55,7 @@ predicate exitFunctionGuardedEdge(EssaVariable pred, EssaVariable succ) {
|
||||
}
|
||||
|
||||
class UninitializedConfig extends TaintTracking::Configuration {
|
||||
UninitializedConfig() { this = "Unitialized local config" }
|
||||
UninitializedConfig() { this = "Uninitialized local config" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source, TaintKind kind) {
|
||||
kind instanceof Uninitialized and
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Symbols for crosss-project jump-to-definition resolution.
|
||||
* Symbols for cross-project jump-to-definition resolution.
|
||||
*/
|
||||
|
||||
import python
|
||||
|
||||
@@ -22,10 +22,10 @@ def bad1():
|
||||
def good1():
|
||||
csv_data = request.args.get('csv')
|
||||
csvWriter = csv.writer(open("test.csv", "wt"))
|
||||
csvWriter.writerow(santize_for_csv(csv_data))
|
||||
csvWriter.writerow(sanitize_for_csv(csv_data))
|
||||
return "good1"
|
||||
|
||||
def santize_for_csv(data: str| List[str] | List[List[str]]):
|
||||
def sanitize_for_csv(data: str| List[str] | List[List[str]]):
|
||||
def sanitize(item):
|
||||
return "'" + item
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import experimental.semmle.python.templates.SSTISink
|
||||
deprecated ClassValue theDjangoTemplateClass() { result = Value::named("django.template.Template") }
|
||||
|
||||
/**
|
||||
* A sink representng `django.template.Template` class instantiation argument.
|
||||
* A sink representing `django.template.Template` class instantiation argument.
|
||||
*
|
||||
* from django.template import Template
|
||||
* template = Template(`sink`)
|
||||
@@ -26,7 +26,7 @@ deprecated class DjangoTemplateTemplateSink extends SSTISink {
|
||||
}
|
||||
// TODO (intentionally commented out QLDoc, since qlformat will delete those lines otherwise)
|
||||
// /**
|
||||
// * Sinks representng the django.template.Template class instantiation.
|
||||
// * Sinks representing the django.template.Template class instantiation.
|
||||
// *
|
||||
// * from django.template import engines
|
||||
// *
|
||||
|
||||
@@ -9,7 +9,7 @@ deprecated Value theFlaskRenderTemplateClass() {
|
||||
}
|
||||
|
||||
/**
|
||||
* A sink representng `flask.render_template_string` function call argument.
|
||||
* A sink representing `flask.render_template_string` function call argument.
|
||||
*
|
||||
* from flask import render_template_string
|
||||
* render_template_string(`sink`)
|
||||
|
||||
@@ -33,7 +33,7 @@ module ModificationOfParameterWithDefault {
|
||||
* should determine if the node (which is perhaps about to be modified)
|
||||
* can be the default value or not.
|
||||
*
|
||||
* In this query we do not track the default value exactly, but rather wheter
|
||||
* In this query we do not track the default value exactly, but rather whether
|
||||
* it is empty or not (see `Source`).
|
||||
*
|
||||
* This is the extension point for determining that a node must be empty and
|
||||
@@ -46,7 +46,7 @@ module ModificationOfParameterWithDefault {
|
||||
* should determine if the node (which is perhaps about to be modified)
|
||||
* can be the default value or not.
|
||||
*
|
||||
* In this query we do not track the default value exactly, but rather wheter
|
||||
* In this query we do not track the default value exactly, but rather whether
|
||||
* it is empty or not (see `Source`).
|
||||
*
|
||||
* This is the extension point for determining that a node must be non-empty
|
||||
@@ -54,7 +54,7 @@ module ModificationOfParameterWithDefault {
|
||||
*/
|
||||
abstract class MustBeNonEmpty extends DataFlow::Node { }
|
||||
|
||||
/** Gets the truthiness (non emptyness) of the default of `p` if that value is mutable */
|
||||
/** Gets the truthiness (non emptiness) of the default of `p` if that value is mutable */
|
||||
private boolean mutableDefaultValue(Parameter p) {
|
||||
exists(Dict d | p.getDefault() = d |
|
||||
exists(d.getAKey()) and result = true
|
||||
|
||||
Reference in New Issue
Block a user