mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Fixes, add secure query
This commit is contained in:
@@ -27,10 +27,12 @@ private module SensitiveCookieNameConfig implements DataFlow::ConfigSig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Tracks flow from sensitive names to HTTP cookie writes. */
|
/** Tracks flow from sensitive names to HTTP cookie writes. */
|
||||||
module SensitiveCookieNameFlow = DataFlow::Global<SensitiveCookieNameConfig>;
|
module SensitiveCookieNameFlow = TaintTracking::Global<SensitiveCookieNameConfig>;
|
||||||
|
|
||||||
private module BooleanCookieSecureConfig implements DataFlow::ConfigSig {
|
private module BooleanCookieSecureConfig implements DataFlow::ConfigSig {
|
||||||
predicate isSource(DataFlow::Node source) { exists(source.asExpr().getBoolValue()) }
|
predicate isSource(DataFlow::Node source) {
|
||||||
|
source.getType().getUnderlyingType() instanceof BoolType
|
||||||
|
}
|
||||||
|
|
||||||
predicate isSink(DataFlow::Node sink) { exists(Http::CookieWrite cw | sink = cw.getSecure()) }
|
predicate isSink(DataFlow::Node sink) { exists(Http::CookieWrite cw | sink = cw.getSecure()) }
|
||||||
|
|
||||||
@@ -39,11 +41,13 @@ private module BooleanCookieSecureConfig implements DataFlow::ConfigSig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Tracks flow from boolean expressions to the `Secure` attribute HTTP cookie writes. */
|
/** Tracks flow from boolean expressions to the `Secure` attribute of HTTP cookie writes. */
|
||||||
module BooleanCookieSecureFlow = DataFlow::Global<BooleanCookieSecureConfig>;
|
module BooleanCookieSecureFlow = TaintTracking::Global<BooleanCookieSecureConfig>;
|
||||||
|
|
||||||
private module BooleanCookieHttpOnlyConfig implements DataFlow::ConfigSig {
|
private module BooleanCookieHttpOnlyConfig implements DataFlow::ConfigSig {
|
||||||
predicate isSource(DataFlow::Node source) { exists(source.asExpr().getBoolValue()) }
|
predicate isSource(DataFlow::Node source) {
|
||||||
|
source.getType().getUnderlyingType() instanceof BoolType
|
||||||
|
}
|
||||||
|
|
||||||
predicate isSink(DataFlow::Node sink) { exists(Http::CookieWrite cw | sink = cw.getHttpOnly()) }
|
predicate isSink(DataFlow::Node sink) { exists(Http::CookieWrite cw | sink = cw.getHttpOnly()) }
|
||||||
|
|
||||||
@@ -52,28 +56,53 @@ private module BooleanCookieHttpOnlyConfig implements DataFlow::ConfigSig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Tracks flow from boolean expressions to the `HttpOnly` attribute HTTP cookie writes. */
|
/** Tracks flow from boolean expressions to the `HttpOnly` attribute of HTTP cookie writes. */
|
||||||
module BooleanCookieHttpOnlyFlow = DataFlow::Global<BooleanCookieHttpOnlyConfig>;
|
module BooleanCookieHttpOnlyFlow = TaintTracking::Global<BooleanCookieHttpOnlyConfig>;
|
||||||
|
|
||||||
|
/** Holds if `cw` has the `Secure` attribute left at its default value of `false`. */
|
||||||
predicate isInsecureDefault(Http::CookieWrite cw) {
|
predicate isInsecureDefault(Http::CookieWrite cw) {
|
||||||
not BooleanCookieSecureFlow::flow(_, cw.getSecure())
|
not BooleanCookieSecureFlow::flow(_, cw.getSecure())
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate isNonHttpOnlyDefault(Http::CookieWrite cw) {
|
/** Holds if `cw` has the `Secure` attribute explicitly set to `false`, from the expression `boolFalse`. */
|
||||||
not BooleanCookieHttpOnlyFlow::flow(_, cw.getHttpOnly())
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate isInsecureDirect(Http::CookieWrite cw, Expr boolFalse) {
|
predicate isInsecureDirect(Http::CookieWrite cw, Expr boolFalse) {
|
||||||
BooleanCookieSecureFlow::flow(DataFlow::exprNode(boolFalse), cw.getSecure()) and
|
BooleanCookieSecureFlow::flow(DataFlow::exprNode(boolFalse), cw.getSecure()) and
|
||||||
boolFalse.getBoolValue() = false
|
boolFalse.getBoolValue() = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Holds if `cw` has the `Secure` attribute set to `false`, either explicitly or by default. */
|
||||||
|
predicate isInsecureCookie(Http::CookieWrite cw) {
|
||||||
|
isInsecureDefault(cw) or
|
||||||
|
isInsecureDirect(cw, _)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds if `cw` has the `HttpOnly` attribute left at its default value of `false`. */
|
||||||
|
predicate isNonHttpOnlyDefault(Http::CookieWrite cw) {
|
||||||
|
not BooleanCookieHttpOnlyFlow::flow(_, cw.getHttpOnly())
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds if `cw` has the `HttpOnly` attribute explicitly set to `false`, from the expression `boolFalse`. */
|
||||||
predicate isNonHttpOnlyDirect(Http::CookieWrite cw, Expr boolFalse) {
|
predicate isNonHttpOnlyDirect(Http::CookieWrite cw, Expr boolFalse) {
|
||||||
BooleanCookieHttpOnlyFlow::flow(DataFlow::exprNode(boolFalse), cw.getHttpOnly()) and
|
BooleanCookieHttpOnlyFlow::flow(DataFlow::exprNode(boolFalse), cw.getHttpOnly()) and
|
||||||
boolFalse.getBoolValue() = false
|
boolFalse.getBoolValue() = false
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate isSensitiveCookie(Http::CookieWrite cw, Expr nameExpr, string name) {
|
/** Holds if `cw` has the `HttpOnly` attribute set to `false`, either explicitly or by default. */
|
||||||
SensitiveCookieNameFlow::flow(DataFlow::exprNode(nameExpr), cw.getName()) and
|
predicate isNonHttpOnlyCookie(Http::CookieWrite cw) {
|
||||||
|
isNonHttpOnlyDefault(cw) or
|
||||||
|
isNonHttpOnlyDirect(cw, _)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `cw` has the sensitive name `name`, from the expression `nameExpr`.
|
||||||
|
* `source` and `sink` represent the data flow path from the sensitive name expression to the cookie write.
|
||||||
|
*/
|
||||||
|
predicate isSensitiveCookie(
|
||||||
|
Http::CookieWrite cw, Expr nameExpr, string name, SensitiveCookieNameFlow::PathNode source,
|
||||||
|
SensitiveCookieNameFlow::PathNode sink
|
||||||
|
) {
|
||||||
|
SensitiveCookieNameFlow::flowPath(source, sink) and
|
||||||
|
source.getNode().asExpr() = nameExpr and
|
||||||
|
sink.getNode() = cw.getName() and
|
||||||
isSensitiveExpr(nameExpr, name)
|
isSensitiveExpr(nameExpr, name)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,25 +4,24 @@
|
|||||||
* malicious JavaScript to steal it in case of XSS vulnerability. Always set
|
* malicious JavaScript to steal it in case of XSS vulnerability. Always set
|
||||||
* 'HttpOnly' to 'true' to authentication related cookie to make it
|
* 'HttpOnly' to 'true' to authentication related cookie to make it
|
||||||
* not accessible by JavaScript.
|
* not accessible by JavaScript.
|
||||||
* @kind problem
|
* @kind path-problem
|
||||||
* @problem.severity warning
|
* @problem.severity warning
|
||||||
* @precision high
|
* @precision high
|
||||||
* @id go/cookie-httponly-not-set
|
* @id go/cookie-httponly-not-set
|
||||||
* @tags security
|
* @tags security
|
||||||
* experimental
|
|
||||||
* external/cwe/cwe-1004
|
* external/cwe/cwe-1004
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import go
|
import go
|
||||||
import semmle.go.security.SecureCookies
|
import semmle.go.security.SecureCookies
|
||||||
import semmle.go.concepts.HTTP
|
import semmle.go.concepts.HTTP
|
||||||
|
import SensitiveCookieNameFlow::PathGraph
|
||||||
|
|
||||||
from Http::CookieWrite cw, Expr sensitiveNameExpr, string name
|
from
|
||||||
|
Http::CookieWrite cw, Expr sensitiveNameExpr, string name,
|
||||||
|
SensitiveCookieNameFlow::PathNode source, SensitiveCookieNameFlow::PathNode sink
|
||||||
where
|
where
|
||||||
isSensitiveCookie(cw, sensitiveNameExpr, name) and
|
isSensitiveCookie(cw, sensitiveNameExpr, name, source, sink) and
|
||||||
(
|
isNonHttpOnlyCookie(cw)
|
||||||
isNonHttpOnlyDefault(cw)
|
select cw, source, sink, "Sensitive cookie $@ does not set HttpOnly attribute to true.",
|
||||||
or
|
sensitiveNameExpr, name
|
||||||
isNonHttpOnlyDirect(cw, _)
|
|
||||||
)
|
|
||||||
select cw, "Sensitive cookie $@ does not set HttpOnly to true", sensitiveNameExpr, name
|
|
||||||
|
|||||||
18
go/ql/src/Security/CWE-614/CookieWithoutSecure.ql
Normal file
18
go/ql/src/Security/CWE-614/CookieWithoutSecure.ql
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* @name 'Secure' attribute is not set to true
|
||||||
|
* @description todo
|
||||||
|
* @kind problem
|
||||||
|
* @problem.severity warning
|
||||||
|
* @precision high
|
||||||
|
* @id go/cookie-secure-not-set
|
||||||
|
* @tags security
|
||||||
|
* external/cwe/cwe-1004
|
||||||
|
*/
|
||||||
|
|
||||||
|
import go
|
||||||
|
import semmle.go.security.SecureCookies
|
||||||
|
import semmle.go.concepts.HTTP
|
||||||
|
|
||||||
|
from Http::CookieWrite cw
|
||||||
|
where isInsecureCookie(cw)
|
||||||
|
select cw, "Cookie does not set Secure attribute to true"
|
||||||
Reference in New Issue
Block a user