mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Polish documentation.
This commit is contained in:
@@ -1,10 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* @name Failure to use secure cookies
|
* @name Construction of a cookie using user-supplied input.
|
||||||
* @description Insecure cookies may be sent in cleartext, which makes them vulnerable to
|
* @description Constructing cookies from user input may allow an attacker to perform a Cookie Poisoning attack.
|
||||||
* interception.
|
|
||||||
* @kind problem
|
* @kind problem
|
||||||
* @problem.severity error
|
* @problem.severity error
|
||||||
* @id py/insecure-cookie
|
* @id py/cookie-injection
|
||||||
* @tags security
|
* @tags security
|
||||||
* external/cwe/cwe-614
|
* external/cwe/cwe-614
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -4,12 +4,17 @@
|
|||||||
<qhelp>
|
<qhelp>
|
||||||
|
|
||||||
<overview>
|
<overview>
|
||||||
<p>Failing to set the 'secure' flag on a cookie can cause it to be sent in cleartext.
|
<p>Setting the 'secure' flag on a cookie to <code>False</code> can cause it to be sent in cleartext.
|
||||||
This makes it easier for an attacker to intercept.</p>
|
Setting the 'httponly' flag on a cookie to <code>False</code> may allow attackers access it via JavaScript.
|
||||||
|
Setting the 'samesite' flag on a cookie to <code>'None'</code> will make the cookie to be sent in third-party
|
||||||
|
contexts which may be attacker-controlled.</p>
|
||||||
</overview>
|
</overview>
|
||||||
|
|
||||||
<recommendation>
|
<recommendation>
|
||||||
<p>Always set <code>secure</code> to <code>True</code> or add "; Secure;" to the cookie's raw value.</p>
|
<p>Always set <code>secure</code> to <code>True</code> or add "; Secure;" to the cookie's raw value.</p>
|
||||||
|
<p>Always set <code>httponly</code> to <code>True</code> or add "; HttpOnly;" to the cookie's raw value.</p>
|
||||||
|
<p>Always set <code>samesite</code> to <code>Lax</code> or <code>Strict</code>, or add "; SameSite=Lax;", or
|
||||||
|
"; Samesite=Strict;" to the cookie's raw header value.</p>
|
||||||
</recommendation>
|
</recommendation>
|
||||||
|
|
||||||
<example>
|
<example>
|
||||||
|
|||||||
@@ -7,6 +7,25 @@ import semmle.python.dataflow.new.DataFlow
|
|||||||
import semmle.python.dataflow.new.TaintTracking
|
import semmle.python.dataflow.new.TaintTracking
|
||||||
import experimental.semmle.python.Concepts
|
import experimental.semmle.python.Concepts
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a header setting a cookie.
|
||||||
|
*
|
||||||
|
* Given the following example:
|
||||||
|
*
|
||||||
|
* ```py
|
||||||
|
* @app.route("/")
|
||||||
|
* def flask_make_response():
|
||||||
|
* resp = make_response("")
|
||||||
|
* resp.headers['Set-Cookie'] = "name=value; Secure;"
|
||||||
|
* return resp
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* * `this` would be `resp.headers['Set-Cookie'] = "name=value; Secure;"`.
|
||||||
|
* * `isSecure()` predicate would succeed.
|
||||||
|
* * `isHttpOnly()` predicate would fail.
|
||||||
|
* * `isSameSite()` predicate would fail.
|
||||||
|
* * `getName()` and `getValue()` results would be `"name=value; Secure;"`.
|
||||||
|
*/
|
||||||
class CookieHeader extends HeaderDeclaration, Cookie::Range {
|
class CookieHeader extends HeaderDeclaration, Cookie::Range {
|
||||||
CookieHeader() {
|
CookieHeader() {
|
||||||
this instanceof HeaderDeclaration and
|
this instanceof HeaderDeclaration and
|
||||||
|
|||||||
@@ -87,6 +87,25 @@ private module PrivateDjango {
|
|||||||
override DataFlow::Node getValueArg() { result = headerInput }
|
override DataFlow::Node getValueArg() { result = headerInput }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a call to `set_cookie()`.
|
||||||
|
*
|
||||||
|
* Given the following example:
|
||||||
|
*
|
||||||
|
* ```py
|
||||||
|
* def django_response(request):
|
||||||
|
* resp = django.http.HttpResponse()
|
||||||
|
* resp.set_cookie("name", "value", secure=True, httponly=True, samesite='Lax')
|
||||||
|
* return resp
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* * `this` would be `resp.set_cookie("name", "value", secure=False, httponly=False, samesite='None')`.
|
||||||
|
* * `getName()`'s result would be `"name"`.
|
||||||
|
* * `getValue()`'s result would be `"value"`.
|
||||||
|
* * `isSecure()` predicate would succeed.
|
||||||
|
* * `isHttpOnly()` predicate would succeed.
|
||||||
|
* * `isSameSite()` predicate would succeed.
|
||||||
|
*/
|
||||||
class DjangoSetCookieCall extends DataFlow::CallCfgNode, Cookie::Range {
|
class DjangoSetCookieCall extends DataFlow::CallCfgNode, Cookie::Range {
|
||||||
DjangoSetCookieCall() { this = baseClassRef().getMember("set_cookie").getACall() }
|
DjangoSetCookieCall() { this = baseClassRef().getMember("set_cookie").getACall() }
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,26 @@ module ExperimentalFlask {
|
|||||||
override DataFlow::Node getValueArg() { result.asExpr() = item.getValue() }
|
override DataFlow::Node getValueArg() { result.asExpr() = item.getValue() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a call to `set_cookie()`.
|
||||||
|
*
|
||||||
|
* Given the following example:
|
||||||
|
*
|
||||||
|
* ```py
|
||||||
|
* @app.route("/")
|
||||||
|
* def false():
|
||||||
|
* resp = make_response()
|
||||||
|
* resp.set_cookie("name", value="value", secure=True, httponly=True, samesite='Lax')
|
||||||
|
* return resp
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* * `this` would be `resp.set_cookie("name", value="value", secure=False, httponly=False, samesite='None')`.
|
||||||
|
* * `getName()`'s result would be `"name"`.
|
||||||
|
* * `getValue()`'s result would be `"value"`.
|
||||||
|
* * `isSecure()` predicate would succeed.
|
||||||
|
* * `isHttpOnly()` predicate would succeed.
|
||||||
|
* * `isSameSite()` predicate would succeed.
|
||||||
|
*/
|
||||||
class FlaskSetCookieCall extends DataFlow::CallCfgNode, Cookie::Range {
|
class FlaskSetCookieCall extends DataFlow::CallCfgNode, Cookie::Range {
|
||||||
FlaskSetCookieCall() {
|
FlaskSetCookieCall() {
|
||||||
this =
|
this =
|
||||||
|
|||||||
Reference in New Issue
Block a user