Compare commits

..

1 Commits

Author SHA1 Message Date
Florin Coada
4cf5d4178f Changelogx fix for 2.18.0 c/cpp breaking changes 2024-07-29 10:11:26 +01:00
27 changed files with 194 additions and 322 deletions

View File

@@ -1,41 +0,0 @@
# This workflow ensures that if the "No Autofix Validation Required" label is
# added to a pull request, the "Autofix Validation Required" label is removed.
name: Autofix Label Manager
on:
pull_request_target:
types: [labeled]
# Allows manual triggering of the workflow for testing
workflow_dispatch:
jobs:
check-to-remove-autofix-label:
env:
GITHUB_REPOSITORY: ${{ github.repository }}
PR_NUMBER: ${{ github.event.number }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REQUIRES_AUTOFIX_LABEL: "Autofix Validation Required"
DOES_NOT_REQUIRE_AUTOFIX_LABEL: "No Autofix Validation Required"
LABEL_ADDED: ${{ github.event.label.name }}
runs-on: ubuntu-latest
steps:
- name: Check if label "No Autofix Validation Required" is added
shell: bash
run: |
if [ "$LABEL_ADDED" != "$DOES_NOT_REQUIRE_AUTOFIX_LABEL" ]; then
echo "Label $DOES_NOT_REQUIRE_AUTOFIX_LABEL was not added."
exit 0
fi
echo "Label $DOES_NOT_REQUIRE_AUTOFIX_LABEL was added."
# Check if Label $REQUIRES_AUTOFIX_LABEL exists and remove it
REQUIRES_AUTOFIX_LABEL_EXISTS=$(gh api /repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/labels | jq --arg label "Autofix Validation Required" '.[] | select(.name==$label) | .name')
if [ "$REQUIRES_AUTOFIX_LABEL_EXISTS" == "$REQUIRES_AUTOFIX_LABEL" ]; then
gh api -X DELETE "/repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/labels/$REQUIRES_AUTOFIX_LABEL"
echo "$REQUIRES_AUTOFIX_LABEL Label removed."
else
echo "$REQUIRES_AUTOFIX_LABEL Label does not exist or was already removed."
fi

View File

@@ -1,56 +0,0 @@
# This workflow creates a reminder to query authors to test their queries
# in autofix.
name: Autofix reminder
permissions:
contents: read
pull-requests: write
issues: write
on:
pull_request:
branches:
- main
- "rc/*"
paths:
- "**/*.qhelp"
- "**/*.ql"
- "**/*.qll"
# This workflow
- ".github/workflows/autofix-reminder.yml"
workflow_dispatch:
jobs:
autofix-reminder:
env:
GITHUB_REPOSITORY: ${{ github.repository }}
PR_NUMBER: ${{ github.event.number }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REQUIRES_AUTOFIX_LABEL: "Autofix Validation Required"
DOES_NOT_REQUIRE_AUTOFIX_LABEL: "No Autofix Validation Required"
runs-on: ubuntu-latest
steps:
- name: Check existing labels
id: label_check
shell: bash
run: |
gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/labels" | jq -r '.[].name' > labels.txt
if grep -q -x -e "${REQUIRES_AUTOFIX_LABEL}" labels.txt || grep -q -x -e "${DOES_NOT_REQUIRE_AUTOFIX_LABEL}" labels.txt; then
echo "Stopping workflow due to label presence."
echo "should_continue=false" >> $GITHUB_OUTPUT
else
echo "Add $REQUIRES_AUTOFIX_LABEL label."
echo "should_continue=true" >> $GITHUB_OUTPUT
fi
- name: Add label
if: steps.label_check.outputs.should_continue == 'true'
run: |
gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/labels" -X POST -f "labels[]=$REQUIRES_AUTOFIX_LABEL"
- name: Comment on PR
if: steps.label_check.outputs.should_continue == 'true'
run: gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" -X POST --field body="This pull request updates '.ql', '.qll', or '.qhelp' files, Please validate that autofixes generated based on these changes are valid. See [the documentation](https://github.com/github/codeql-team/blob/main/docs/best-practices/validating-autofix-for-query-changes.md) (internal access required). If autofix validation is not required, please add the label '${DOES_NOT_REQUIRE_AUTOFIX_LABEL}' to this pull request."

View File

@@ -22,11 +22,9 @@ CodeQL CLI
Breaking Changes
~~~~~~~~~~~~~~~~
* A number of breaking changes have been made to the C and C++ CodeQL environment:
* A number of breaking changes have been made to the C and C++ CodeQL test environment as used by :code:`codeql test run`\ :
* The environment no longer defines any GNU-specific builtin macros.
If these macros are still needed, please define them via
:code:`semmle-extractor-options`.
* The test environment no longer defines any GNU-specific builtin macros. If these macros are still needed by a test, please define them via :code:`semmle-extractor-options`.
* The :code:`--force-recompute` option is no longer directly supported by
:code:`semmle-extractor-options`. Instead, :code:`--edg --force-recompute` should be specified.

View File

@@ -14,11 +14,19 @@
Windows,"Windows 10 / Windows Server 2019
Windows 11 / Windows Server 2022","x86-64"
macOS,"macOS 12 Monterey
macOS,"macOS 10.15 Catalina
macOS 11 Big Sur
macOS 12 Monterey
macOS 13 Ventura
macOS 14 Sonoma","x86-64, arm64 (Apple Silicon)
macOS 14 Sonoma","x86-64
x86-64, arm64 (Apple Silicon)
x86-64, arm64 (Apple Silicon)
x86-64, arm64 (Apple Silicon)

View File

@@ -1,18 +0,0 @@
/**
* @kind test-postprocess
*/
import codeql.dataflow.test.ProvenancePathGraph
import semmle.go.dataflow.ExternalFlow
external predicate queryResults(string relation, int row, int column, string data);
external predicate queryRelations(string relation);
query predicate resultRelations(string relation) { queryRelations(relation) }
module Res = TranslateProvenanceResults<interpretModelForTest/2, queryResults/4>;
from string relation, int row, int column, string data
where Res::results(relation, row, column, data)
select relation, row, column, data

View File

@@ -0,0 +1,14 @@
/**
* @kind path-problem
*/
import go
import semmle.go.security.TaintedPath
import codeql.dataflow.test.ProvenancePathGraph
import semmle.go.dataflow.ExternalFlow
import ShowProvenance<interpretModelForTest/2, TaintedPath::Flow::PathNode, TaintedPath::Flow::PathGraph>
from TaintedPath::Flow::PathNode source, TaintedPath::Flow::PathNode sink
where TaintedPath::Flow::flowPath(source, sink)
select sink.getNode(), source, sink, "This path depends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -1,2 +0,0 @@
query: Security/CWE-022/TaintedPath.ql
postprocess: TestUtilities/PrettyPrintModels.ql

View File

@@ -1,2 +1 @@
query: Security/CWE-022/UnsafeUnzipSymlink.ql
postprocess: TestUtilities/PrettyPrintModels.ql
Security/CWE-022/UnsafeUnzipSymlink.ql

View File

@@ -1,8 +1,3 @@
#select
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | Unsanitized archive entry, which may contain '..', is used in a $@. | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | file system operation |
| ZipSlip.go:11:2:15:2 | range statement[1] | ZipSlip.go:11:2:15:2 | range statement[1] | ZipSlip.go:14:20:14:20 | p | Unsanitized archive entry, which may contain '..', is used in a $@. | ZipSlip.go:14:20:14:20 | p | file system operation |
| tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:16:14:16:34 | call to Dir | Unsanitized archive entry, which may contain '..', is used in a $@. | tarslip.go:16:14:16:34 | call to Dir | file system operation |
| tst.go:23:2:43:2 | range statement[1] | tst.go:23:2:43:2 | range statement[1] | tst.go:29:20:29:23 | path | Unsanitized archive entry, which may contain '..', is used in a $@. | tst.go:29:20:29:23 | path | file system operation |
edges
| UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | provenance | |
| UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | provenance | FunctionModel |
@@ -12,13 +7,10 @@ edges
| UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | provenance | |
| ZipSlip.go:11:2:15:2 | range statement[1] | ZipSlip.go:12:24:12:29 | selection of Name | provenance | |
| ZipSlip.go:12:3:12:30 | ... := ...[0] | ZipSlip.go:14:20:14:20 | p | provenance | |
| ZipSlip.go:12:24:12:29 | selection of Name | ZipSlip.go:12:3:12:30 | ... := ...[0] | provenance | MaD:1 |
| ZipSlip.go:12:24:12:29 | selection of Name | ZipSlip.go:12:3:12:30 | ... := ...[0] | provenance | MaD:877 |
| tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:16:23:16:33 | selection of Name | provenance | |
| tarslip.go:16:23:16:33 | selection of Name | tarslip.go:16:14:16:34 | call to Dir | provenance | MaD:2 |
| tarslip.go:16:23:16:33 | selection of Name | tarslip.go:16:14:16:34 | call to Dir | provenance | MaD:892 |
| tst.go:23:2:43:2 | range statement[1] | tst.go:29:20:29:23 | path | provenance | |
models
| 1 | Summary: path/filepath; ; false; Abs; ; ; Argument[0]; ReturnValue[0]; taint; manual |
| 2 | Summary: path; ; false; Dir; ; ; Argument[0]; ReturnValue; taint; manual |
nodes
| UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | semmle.label | definition of candidate |
| UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | semmle.label | call to Join |
@@ -36,3 +28,8 @@ nodes
| tst.go:23:2:43:2 | range statement[1] | semmle.label | range statement[1] |
| tst.go:29:20:29:23 | path | semmle.label | path |
subpaths
#select
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | Unsanitized archive entry, which may contain '..', is used in a $@. | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | file system operation |
| ZipSlip.go:11:2:15:2 | range statement[1] | ZipSlip.go:11:2:15:2 | range statement[1] | ZipSlip.go:14:20:14:20 | p | Unsanitized archive entry, which may contain '..', is used in a $@. | ZipSlip.go:14:20:14:20 | p | file system operation |
| tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:16:14:16:34 | call to Dir | Unsanitized archive entry, which may contain '..', is used in a $@. | tarslip.go:16:14:16:34 | call to Dir | file system operation |
| tst.go:23:2:43:2 | range statement[1] | tst.go:23:2:43:2 | range statement[1] | tst.go:29:20:29:23 | path | Unsanitized archive entry, which may contain '..', is used in a $@. | tst.go:29:20:29:23 | path | file system operation |

View File

@@ -1,2 +1 @@
query: Security/CWE-022/ZipSlip.ql
postprocess: TestUtilities/PrettyPrintModels.ql
Security/CWE-022/ZipSlip.ql

View File

@@ -78,11 +78,13 @@ public class OdasaOutput {
}
public OdasaOutput(boolean trackClassOrigins, Compression compression, Logger log) {
String trapFolderVar = Env.systemEnv().get("CODEQL_EXTRACTOR_JAVA_TRAP_DIR");
String trapFolderVar = Env.systemEnv().getFirstNonEmpty("CODEQL_EXTRACTOR_JAVA_TRAP_DIR",
Var.TRAP_FOLDER.name());
if (trapFolderVar == null) {
throw new ResourceError("CODEQL_EXTRACTOR_JAVA_TRAP_DIR was not set");
}
String sourceArchiveVar = Env.systemEnv().get("CODEQL_EXTRACTOR_JAVA_SOURCE_ARCHIVE_DIR");
String sourceArchiveVar = Env.systemEnv().getFirstNonEmpty("CODEQL_EXTRACTOR_JAVA_SOURCE_ARCHIVE_DIR",
Var.SOURCE_ARCHIVE.name());
if (sourceArchiveVar == null) {
throw new ResourceError("CODEQL_EXTRACTOR_JAVA_SOURCE_ARCHIVE_DIR was not set");
}

View File

@@ -256,6 +256,8 @@ public class Env {
*/
ODASA_SRC,
ODASA_DB,
TRAP_FOLDER,
SOURCE_ARCHIVE,
ODASA_OUTPUT,
ODASA_SUBPROJECT_THREADS,

View File

@@ -1,4 +0,0 @@
---
category: breaking
---
* The Java and Kotlin extractors no longer support the `SOURCE_ARCHIVE` and `TRAP_FOLDER` legacy environment variable.

View File

@@ -1,48 +0,0 @@
/**
* Provides default sources, sinks and sanitizers for detecting
* "cookie injection"
* 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.RemoteFlowSources
/**
* Provides default sources, sinks and sanitizers for detecting
* "cookie injection"
* vulnerabilities, as well as extension points for adding your own.
*/
module CookieInjection {
/**
* A data flow source for "cookie injection" vulnerabilities.
*/
abstract class Source extends DataFlow::Node { }
/**
* A data flow sink for "cookie injection" vulnerabilities.
*/
abstract class Sink extends DataFlow::Node { }
/**
* A sanitizer for "cookie injection" vulnerabilities.
*/
abstract class Sanitizer extends DataFlow::Node { }
/**
* A source of remote user input, considered as a flow source.
*/
class RemoteFlowSourceAsSource extends Source, RemoteFlowSource { }
/**
* A write to a cookie, considered as a sink.
*/
class CookieWriteSink extends Sink {
CookieWriteSink() {
exists(Http::Server::CookieWrite cw |
this = [cw.getNameArg(), cw.getValueArg(), cw.getHeaderArg()]
)
}
}
}

View File

@@ -1,26 +0,0 @@
/**
* Provides a taint-tracking configuration for detecting "cookie injection" vulnerabilities.
*
* Note, for performance reasons: only import this file if
* `CookieInjectionFlow` is needed, otherwise
* `CookieInjectionCustomizations` should be imported instead.
*/
private import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import CookieInjectionCustomizations::CookieInjection
/**
* A taint-tracking configuration for detecting "cookie injection" vulnerabilities.
*/
module CookieInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof Source }
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}
/** Global taint-tracking for detecting "cookie injection" vulnerabilities. */
module CookieInjectionFlow = TaintTracking::Global<CookieInjectionConfig>;

View File

@@ -1,27 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Constructing cookies from user input can allow an attacker to control a user's cookie.
This may lead to a session fixation attack. Additionally, client code may not expect a cookie to contain attacker-controlled data, and fail to sanitize it for common vulnerabilities such as Cross Site Scripting (XSS).
An attacker manipulating the raw cookie header may additionally be able to set cookie attributes such as <code>HttpOnly</code> to insecure values.
</p>
</overview>
<recommendation>
<p>Do not use raw user input to construct cookies.</p>
</recommendation>
<example>
<p>In the following cases, a cookie is constructed for a Flask response using user input. The first uses <code>set_cookie</code>,
and the second sets a cookie's raw value through the <code>set-cookie</code> header.</p>
<sample src="examples/CookieInjection.py" />
</example>
<references>
<li>Wikipedia - <a href="https://en.wikipedia.org/wiki/Session_fixation">Session Fixation</a>.</li>
</references>
</qhelp>

View File

@@ -1,20 +0,0 @@
/**
* @name Construction of a cookie using user-supplied input.
* @description Constructing cookies from user input may allow an attacker to perform a Cookie Poisoning attack.
* @kind path-problem
* @problem.severity warning
* @precision high
* @security-severity 5.0
* @id py/cookie-injection
* @tags security
* external/cwe/cwe-20
*/
import python
import semmle.python.security.dataflow.CookieInjectionQuery
import CookieInjectionFlow::PathGraph
from CookieInjectionFlow::PathNode source, CookieInjectionFlow::PathNode sink
where CookieInjectionFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "Cookie is constructed from a $@.", source.getNode(),
"user-supplied input"

View File

@@ -1,4 +0,0 @@
---
category: newQuery
---
* The `py/cookie-injection` query, originally contributed to the experimental query pack by @jorgectf, has been promoted to the main query pack. This query finds instances of cookies being constructed from user input.

View File

@@ -2,15 +2,15 @@ from flask import request, make_response
@app.route("/1")
def set_cookie():
def true():
resp = make_response()
resp.set_cookie(request.args["name"], # BAD: User input is used to set the cookie's name and value
resp.set_cookie(request.args["name"],
value=request.args["name"])
return resp
@app.route("/2")
def set_cookie_header():
resp = make_response()
resp.headers['Set-Cookie'] = f"{request.args['name']}={request.args['name']};" # BAD: User input is used to set the raw cookie header.
def flask_make_response():
resp = make_response("hello")
resp.headers['Set-Cookie'] = f"{request.args['name']}={request.args['name']};"
return resp

View File

@@ -0,0 +1,28 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Constructing cookies from user input may allow an attacker to perform a Cookie Poisoning attack.
It is possible, however, to perform other parameter-like attacks through cookie poisoning techniques,
such as SQL Injection, Directory Traversal, or Stealth Commanding, etc. Additionally,
cookie injection may relate to attempts to perform Access of Administrative Interface.
</p>
</overview>
<recommendation>
<p>Do not use raw user input to construct cookies.</p>
</recommendation>
<example>
<p>This example shows two ways of adding a cookie to a Flask response. The first way uses <code>set_cookie</code>'s
and the second sets a cookie's raw value through a header, both using user-supplied input.</p>
<sample src="CookieInjection.py" />
</example>
<references>
<li>Imperva: <a href="https://docs.imperva.com/bundle/on-premises-knowledgebase-reference-guide/page/cookie_injection.htm">Cookie injection</a>.</li>
</references>
</qhelp>

View File

@@ -0,0 +1,27 @@
/**
* @name Construction of a cookie using user-supplied input.
* @description Constructing cookies from user input may allow an attacker to perform a Cookie Poisoning attack.
* @kind path-problem
* @problem.severity error
* @id py/cookie-injection
* @tags security
* experimental
* external/cwe/cwe-614
*/
// determine precision above
import python
import semmle.python.dataflow.new.DataFlow
import experimental.semmle.python.Concepts
import experimental.semmle.python.CookieHeader
import experimental.semmle.python.security.injection.CookieInjection
import CookieInjectionFlow::PathGraph
from CookieInjectionFlow::PathNode source, CookieInjectionFlow::PathNode sink, string insecure
where
CookieInjectionFlow::flowPath(source, sink) and
if exists(sink.getNode().(CookieSink))
then insecure = ",and its " + sink.getNode().(CookieSink).getFlag() + " flag is not properly set."
else insecure = "."
select sink.getNode(), source, sink, "Cookie is constructed from a $@" + insecure, source.getNode(),
"user-supplied input"

View File

@@ -0,0 +1,41 @@
import python
import experimental.semmle.python.Concepts
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import semmle.python.dataflow.new.RemoteFlowSources
class CookieSink extends DataFlow::Node {
string flag;
CookieSink() {
exists(Cookie cookie |
this in [cookie.getNameArg(), cookie.getValueArg()] and
(
not cookie.isSecure() and
flag = "secure"
or
not cookie.isHttpOnly() and
flag = "httponly"
or
not cookie.isSameSite() and
flag = "samesite"
)
)
}
string getFlag() { result = flag }
}
/**
* A taint-tracking configuration for detecting Cookie injections.
*/
private module CookieInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
predicate isSink(DataFlow::Node sink) {
exists(Cookie c | sink in [c.getNameArg(), c.getValueArg()])
}
}
/** Global taint-tracking for detecting "Cookie injections" vulnerabilities. */
module CookieInjectionFlow = TaintTracking::Global<CookieInjectionConfig>;

View File

@@ -0,0 +1,51 @@
edges
| django_bad.py:27:33:27:67 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | provenance | |
| django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | provenance | |
| flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:1:26:1:32 | ControlFlowNode for request | provenance | |
| flask_bad.py:1:26:1:32 | ControlFlowNode for request | flask_bad.py:24:21:24:27 | ControlFlowNode for request | provenance | |
| flask_bad.py:1:26:1:32 | ControlFlowNode for request | flask_bad.py:24:49:24:55 | ControlFlowNode for request | provenance | |
| flask_bad.py:1:26:1:32 | ControlFlowNode for request | flask_bad.py:32:37:32:43 | ControlFlowNode for request | provenance | |
| flask_bad.py:1:26:1:32 | ControlFlowNode for request | flask_bad.py:32:60:32:66 | ControlFlowNode for request | provenance | |
| flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | provenance | AdditionalTaintStep |
| flask_bad.py:24:21:24:27 | ControlFlowNode for request | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | provenance | AdditionalTaintStep |
| flask_bad.py:24:49:24:55 | ControlFlowNode for request | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | provenance | AdditionalTaintStep |
| flask_bad.py:32:37:32:43 | ControlFlowNode for request | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | provenance | AdditionalTaintStep |
| flask_bad.py:32:60:32:66 | ControlFlowNode for request | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | provenance | AdditionalTaintStep |
nodes
| django_bad.py:19:21:19:55 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| django_bad.py:20:21:20:56 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | semmle.label | ControlFlowNode for Fstring |
| django_bad.py:27:33:27:67 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember |
| flask_bad.py:1:26:1:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| flask_bad.py:24:21:24:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| flask_bad.py:24:49:24:55 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | semmle.label | ControlFlowNode for Fstring |
| flask_bad.py:32:37:32:43 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| flask_bad.py:32:60:32:66 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
subpaths
#select
| django_bad.py:19:21:19:55 | ControlFlowNode for Attribute() | django_bad.py:19:21:19:55 | ControlFlowNode for Attribute() | django_bad.py:19:21:19:55 | ControlFlowNode for Attribute() | Cookie is constructed from a $@,and its httponly flag is not properly set. | django_bad.py:19:21:19:55 | ControlFlowNode for Attribute() | user-supplied input |
| django_bad.py:19:21:19:55 | ControlFlowNode for Attribute() | django_bad.py:19:21:19:55 | ControlFlowNode for Attribute() | django_bad.py:19:21:19:55 | ControlFlowNode for Attribute() | Cookie is constructed from a $@,and its samesite flag is not properly set. | django_bad.py:19:21:19:55 | ControlFlowNode for Attribute() | user-supplied input |
| django_bad.py:19:21:19:55 | ControlFlowNode for Attribute() | django_bad.py:19:21:19:55 | ControlFlowNode for Attribute() | django_bad.py:19:21:19:55 | ControlFlowNode for Attribute() | Cookie is constructed from a $@,and its secure flag is not properly set. | django_bad.py:19:21:19:55 | ControlFlowNode for Attribute() | user-supplied input |
| django_bad.py:20:21:20:56 | ControlFlowNode for Attribute() | django_bad.py:20:21:20:56 | ControlFlowNode for Attribute() | django_bad.py:20:21:20:56 | ControlFlowNode for Attribute() | Cookie is constructed from a $@,and its httponly flag is not properly set. | django_bad.py:20:21:20:56 | ControlFlowNode for Attribute() | user-supplied input |
| django_bad.py:20:21:20:56 | ControlFlowNode for Attribute() | django_bad.py:20:21:20:56 | ControlFlowNode for Attribute() | django_bad.py:20:21:20:56 | ControlFlowNode for Attribute() | Cookie is constructed from a $@,and its samesite flag is not properly set. | django_bad.py:20:21:20:56 | ControlFlowNode for Attribute() | user-supplied input |
| django_bad.py:20:21:20:56 | ControlFlowNode for Attribute() | django_bad.py:20:21:20:56 | ControlFlowNode for Attribute() | django_bad.py:20:21:20:56 | ControlFlowNode for Attribute() | Cookie is constructed from a $@,and its secure flag is not properly set. | django_bad.py:20:21:20:56 | ControlFlowNode for Attribute() | user-supplied input |
| django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | django_bad.py:27:33:27:67 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its httponly flag is not properly set. | django_bad.py:27:33:27:67 | ControlFlowNode for Attribute() | user-supplied input |
| django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | django_bad.py:27:33:27:67 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its samesite flag is not properly set. | django_bad.py:27:33:27:67 | ControlFlowNode for Attribute() | user-supplied input |
| django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | django_bad.py:27:33:27:67 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its secure flag is not properly set. | django_bad.py:27:33:27:67 | ControlFlowNode for Attribute() | user-supplied input |
| django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its httponly flag is not properly set. | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | user-supplied input |
| django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its samesite flag is not properly set. | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | user-supplied input |
| django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | django_bad.py:27:30:27:124 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its secure flag is not properly set. | django_bad.py:27:71:27:106 | ControlFlowNode for Attribute() | user-supplied input |
| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input |
| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input |
| flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:21:24:40 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input |
| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input |
| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input |
| flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:24:49:24:69 | ControlFlowNode for Subscript | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input |
| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its httponly flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input |
| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its samesite flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input |
| flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | flask_bad.py:32:34:32:98 | ControlFlowNode for Fstring | Cookie is constructed from a $@,and its secure flag is not properly set. | flask_bad.py:1:26:1:32 | ControlFlowNode for ImportMember | user-supplied input |

View File

@@ -0,0 +1 @@
experimental/Security/CWE-614/CookieInjection.ql

View File

@@ -1,28 +0,0 @@
edges
| django_tests.py:4:25:4:31 | ControlFlowNode for request | django_tests.py:6:21:6:31 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep |
| django_tests.py:4:25:4:31 | ControlFlowNode for request | django_tests.py:7:21:7:31 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep |
| django_tests.py:6:21:6:31 | ControlFlowNode for Attribute | django_tests.py:6:21:6:43 | ControlFlowNode for Attribute() | provenance | dict.get |
| django_tests.py:7:21:7:31 | ControlFlowNode for Attribute | django_tests.py:7:21:7:44 | ControlFlowNode for Attribute() | provenance | dict.get |
| django_tests.py:11:26:11:32 | ControlFlowNode for request | django_tests.py:13:33:13:43 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep |
| django_tests.py:11:26:11:32 | ControlFlowNode for request | django_tests.py:13:59:13:69 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep |
| django_tests.py:13:33:13:43 | ControlFlowNode for Attribute | django_tests.py:13:33:13:55 | ControlFlowNode for Attribute() | provenance | dict.get |
| django_tests.py:13:33:13:55 | ControlFlowNode for Attribute() | django_tests.py:13:30:13:100 | ControlFlowNode for Fstring | provenance | |
| django_tests.py:13:59:13:69 | ControlFlowNode for Attribute | django_tests.py:13:59:13:82 | ControlFlowNode for Attribute() | provenance | dict.get |
| django_tests.py:13:59:13:82 | ControlFlowNode for Attribute() | django_tests.py:13:30:13:100 | ControlFlowNode for Fstring | provenance | |
nodes
| django_tests.py:4:25:4:31 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| django_tests.py:6:21:6:31 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| django_tests.py:6:21:6:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| django_tests.py:7:21:7:31 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| django_tests.py:7:21:7:44 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| django_tests.py:11:26:11:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| django_tests.py:13:30:13:100 | ControlFlowNode for Fstring | semmle.label | ControlFlowNode for Fstring |
| django_tests.py:13:33:13:43 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| django_tests.py:13:33:13:55 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| django_tests.py:13:59:13:69 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| django_tests.py:13:59:13:82 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
subpaths
#select
| django_tests.py:6:21:6:43 | ControlFlowNode for Attribute() | django_tests.py:4:25:4:31 | ControlFlowNode for request | django_tests.py:6:21:6:43 | ControlFlowNode for Attribute() | Cookie is constructed from a $@. | django_tests.py:4:25:4:31 | ControlFlowNode for request | user-supplied input |
| django_tests.py:7:21:7:44 | ControlFlowNode for Attribute() | django_tests.py:4:25:4:31 | ControlFlowNode for request | django_tests.py:7:21:7:44 | ControlFlowNode for Attribute() | Cookie is constructed from a $@. | django_tests.py:4:25:4:31 | ControlFlowNode for request | user-supplied input |
| django_tests.py:13:30:13:100 | ControlFlowNode for Fstring | django_tests.py:11:26:11:32 | ControlFlowNode for request | django_tests.py:13:30:13:100 | ControlFlowNode for Fstring | Cookie is constructed from a $@. | django_tests.py:11:26:11:32 | ControlFlowNode for request | user-supplied input |

View File

@@ -1 +0,0 @@
Security/CWE-020/CookieInjection.ql

View File

@@ -1,20 +0,0 @@
import django.http
from django.urls import path
def django_response_bad(request):
resp = django.http.HttpResponse()
resp.set_cookie(request.GET.get("name"), # BAD: Cookie is constructed from user input
request.GET.get("value"))
return resp
def django_response_bad2(request):
response = django.http.HttpResponse()
response['Set-Cookie'] = f"{request.GET.get('name')}={request.GET.get('value')}; SameSite=None;" # BAD: Cookie header is constructed from user input.
return response
# fake setup, you can't actually run this
urlpatterns = [
path("response_bad", django_response_bad),
path("response_bd2", django_response_bad2)
]