mirror of
https://github.com/github/codeql.git
synced 2026-04-26 01:05:15 +02:00
Remove experimental query versions
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
from flask import Flask, request, make_response, Response
|
||||
|
||||
|
||||
@app.route("/1")
|
||||
def true():
|
||||
resp = make_response()
|
||||
resp.set_cookie("name", value="value", secure=True)
|
||||
return resp
|
||||
|
||||
|
||||
@app.route("/2")
|
||||
def flask_make_response():
|
||||
resp = make_response("hello")
|
||||
resp.headers['Set-Cookie'] = "name=value; Secure;"
|
||||
return resp
|
||||
@@ -1,31 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>Setting the 'secure' flag on a cookie to <code>False</code> can cause it to be sent in cleartext.
|
||||
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>
|
||||
|
||||
<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>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>
|
||||
|
||||
<example>
|
||||
<p>This example shows two ways of adding a cookie to a Flask response. The first way uses <code>set_cookie</code>'s
|
||||
secure flag and the second adds the secure flag in the cookie's raw value.</p>
|
||||
<sample src="InsecureCookie.py" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>Detectify: <a href="https://support.detectify.com/support/solutions/articles/48001048982-cookie-lack-secure-flag">Cookie lack Secure flag</a>.</li>
|
||||
<li>PortSwigger: <a href="https://portswigger.net/kb/issues/00500200_tls-cookie-without-secure-flag-set">TLS cookie without secure flag set</a>.</li>
|
||||
</references>
|
||||
|
||||
</qhelp>
|
||||
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* @name Failure to use secure cookies
|
||||
* @description Insecure cookies may be sent in cleartext, which makes them vulnerable to
|
||||
* interception.
|
||||
* @kind problem
|
||||
* @problem.severity error
|
||||
* @security-severity 5.0
|
||||
* @precision ???
|
||||
* @id py/insecure-cookie
|
||||
* @tags security
|
||||
* experimental
|
||||
* external/cwe/cwe-614
|
||||
*/
|
||||
|
||||
// TODO: determine precision above
|
||||
import python
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import experimental.semmle.python.Concepts
|
||||
import semmle.python.Concepts
|
||||
|
||||
from Http::Server::CookieWrite cookie, string alert
|
||||
where
|
||||
cookie.hasSecureFlag(false) and
|
||||
alert = "secure"
|
||||
or
|
||||
cookie.hasHttpOnlyFlag(false) and
|
||||
alert = "httponly"
|
||||
or
|
||||
cookie.hasSameSiteAttribute(any(Http::Server::CookieWrite::SameSiteNone v)) and
|
||||
alert = "samesite"
|
||||
select cookie, "Cookie is added without the '" + alert + "' flag properly set."
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
private import experimental.semmle.python.frameworks.AsyncSsh
|
||||
private import experimental.semmle.python.frameworks.Stdlib
|
||||
private import experimental.semmle.python.frameworks.Flask
|
||||
private import experimental.semmle.python.frameworks.Django
|
||||
private import experimental.semmle.python.frameworks.LDAP
|
||||
private import experimental.semmle.python.frameworks.Netmiko
|
||||
|
||||
@@ -87,73 +87,6 @@ private module ExperimentalPrivateDjango {
|
||||
or
|
||||
result = baseClassRef().getReturn().getAMember()
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 DjangoResponseSetCookieCall extends DataFlow::MethodCallNode,
|
||||
Http::Server::CookieWrite::Range
|
||||
{
|
||||
DjangoResponseSetCookieCall() {
|
||||
this.calls(PrivateDjango::DjangoImpl::DjangoHttp::Response::HttpResponse::instance(),
|
||||
"set_cookie")
|
||||
}
|
||||
|
||||
override DataFlow::Node getNameArg() {
|
||||
result in [this.getArg(0), this.getArgByName("key")]
|
||||
}
|
||||
|
||||
override DataFlow::Node getValueArg() {
|
||||
result in [this.getArg(1), this.getArgByName("value")]
|
||||
}
|
||||
|
||||
override predicate hasSecureFlag(boolean b) {
|
||||
if
|
||||
DataFlow::exprNode(any(True t))
|
||||
.(DataFlow::LocalSourceNode)
|
||||
.flowsTo(this.(DataFlow::CallCfgNode).getArgByName("secure"))
|
||||
then b = true
|
||||
else b = false
|
||||
}
|
||||
|
||||
override predicate hasHttpOnlyFlag(boolean b) {
|
||||
if
|
||||
DataFlow::exprNode(any(True t))
|
||||
.(DataFlow::LocalSourceNode)
|
||||
.flowsTo(this.(DataFlow::CallCfgNode).getArgByName("httponly"))
|
||||
then b = true
|
||||
else b = false
|
||||
}
|
||||
|
||||
// override predicate hasSameSiteFlag(boolean b) {
|
||||
// if
|
||||
// exists(StringLiteral str |
|
||||
// str.getText() in ["Strict", "Lax"] and
|
||||
// DataFlow::exprNode(str)
|
||||
// .(DataFlow::LocalSourceNode)
|
||||
// .flowsTo(this.(DataFlow::CallCfgNode).getArgByName("samesite"))
|
||||
// )
|
||||
// then b = true
|
||||
// else b = false
|
||||
// }
|
||||
override DataFlow::Node getHeaderArg() { none() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `flask` PyPI package.
|
||||
* See https://flask.palletsprojects.com/en/1.1.x/.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.frameworks.Flask
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import experimental.semmle.python.Concepts
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
private import semmle.python.frameworks.Flask
|
||||
|
||||
module ExperimentalFlask {
|
||||
/**
|
||||
* 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 Http::Server::CookieWrite::Range instanceof Flask::FlaskResponseSetCookieCall
|
||||
{
|
||||
override DataFlow::Node getNameArg() { result = this.getNameArg() }
|
||||
|
||||
override DataFlow::Node getValueArg() { result = this.getValueArg() }
|
||||
|
||||
override predicate hasSecureFlag(boolean b) {
|
||||
if
|
||||
DataFlow::exprNode(any(True t))
|
||||
.(DataFlow::LocalSourceNode)
|
||||
.flowsTo(this.(DataFlow::CallCfgNode).getArgByName("secure"))
|
||||
then b = true
|
||||
else b = false
|
||||
}
|
||||
|
||||
override predicate hasHttpOnlyFlag(boolean b) {
|
||||
if
|
||||
DataFlow::exprNode(any(True t))
|
||||
.(DataFlow::LocalSourceNode)
|
||||
.flowsTo(this.(DataFlow::CallCfgNode).getArgByName("httponly"))
|
||||
then b = true
|
||||
else b = false
|
||||
}
|
||||
|
||||
// override predicate hasSameSiteFlag(boolean b) {
|
||||
// if
|
||||
// exists(StringLiteral str |
|
||||
// str.getText() in ["Strict", "Lax"] and
|
||||
// DataFlow::exprNode(str)
|
||||
// .(DataFlow::LocalSourceNode)
|
||||
// .flowsTo(this.(DataFlow::CallCfgNode).getArgByName("samesite"))
|
||||
// )
|
||||
// then b = true
|
||||
// else b = false
|
||||
// }
|
||||
override DataFlow::Node getHeaderArg() { none() }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user