mirror of
https://github.com/github/codeql.git
synced 2026-04-25 08:45:14 +02:00
Add JWT Security Queries
This commit is contained in:
@@ -1250,3 +1250,92 @@ module LdapExecution {
|
||||
abstract DataFlow::Node getQuery();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow node that encodes a Jwt token.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
* extend `JwtEncoding::Range` instead.
|
||||
*/
|
||||
class JwtEncoding extends DataFlow::Node instanceof JwtEncoding::Range {
|
||||
/** Gets the argument containing the encoding payload. */
|
||||
DataFlow::Node getPayload() { result = super.getPayload() }
|
||||
|
||||
/** Gets the argument containing the encoding algorithm. */
|
||||
DataFlow::Node getAlgorithm() { result = super.getAlgorithm() }
|
||||
|
||||
/** Gets the argument containing the encoding key. */
|
||||
DataFlow::Node getKey() { result = super.getKey() }
|
||||
|
||||
/** Checks if the payloads gets signed while encoding. */
|
||||
predicate signs() { super.signs() }
|
||||
}
|
||||
|
||||
/** Provides a class for modeling new Jwt token encoding APIs. */
|
||||
module JwtEncoding {
|
||||
/**
|
||||
* A data-flow node that encodes a Jwt token.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `JwtEncoding` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/** Gets the argument containing the encoding payload. */
|
||||
abstract DataFlow::Node getPayload();
|
||||
|
||||
/** Gets the argument containing the encoding algorithm. */
|
||||
abstract DataFlow::Node getAlgorithm();
|
||||
|
||||
/** Gets the argument containing the encoding key. */
|
||||
abstract DataFlow::Node getKey();
|
||||
|
||||
/** Checks if the payloads gets signed while encoding. */
|
||||
abstract predicate signs();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow node that decodes a Jwt token.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
* extend `JwtDecoding::Range` instead.
|
||||
*/
|
||||
class JwtDecoding extends DataFlow::Node instanceof JwtDecoding::Range {
|
||||
/** Gets the argument containing the encoding payload. */
|
||||
DataFlow::Node getPayload() { result = super.getPayload() }
|
||||
|
||||
/** Gets the argument containing the encoding algorithm. */
|
||||
DataFlow::Node getAlgorithm() { result = super.getAlgorithm() }
|
||||
|
||||
/** Gets the argument containing the encoding key. */
|
||||
DataFlow::Node getOptions() { result = super.getOptions() }
|
||||
|
||||
/** Checks if the signature gets verified while decoding. */
|
||||
predicate verifies() { super.verifies() }
|
||||
}
|
||||
|
||||
/** Provides a class for modeling new Jwt token encoding APIs. */
|
||||
module JwtDecoding {
|
||||
/**
|
||||
* A data-flow node that encodes a Jwt token.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `JwtDecoding` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/** Gets the argument containing the encoding payload. */
|
||||
abstract DataFlow::Node getPayload();
|
||||
|
||||
/** Gets the argument containing the encoding algorithm. */
|
||||
abstract DataFlow::Node getAlgorithm();
|
||||
|
||||
/** Gets the argument containing the encoding key. */
|
||||
abstract DataFlow::Node getKey();
|
||||
|
||||
/** Gets the argument containing the encoding options. */
|
||||
abstract DataFlow::Node getOptions();
|
||||
|
||||
/** Checks if the signature gets verified while decoding. */
|
||||
abstract predicate verifies();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,3 +37,4 @@ private import codeql.ruby.frameworks.Pg
|
||||
private import codeql.ruby.frameworks.Yaml
|
||||
private import codeql.ruby.frameworks.Sequel
|
||||
private import codeql.ruby.frameworks.Ldap
|
||||
private import codeql.ruby.frameworks.Jwt
|
||||
55
ruby/ql/lib/codeql/ruby/frameworks/Jwt.qll
Normal file
55
ruby/ql/lib/codeql/ruby/frameworks/Jwt.qll
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Provides creation, verification and decoding JSON Web Tokens (JWT).
|
||||
*/
|
||||
|
||||
private import ruby
|
||||
private import codeql.ruby.ApiGraphs
|
||||
private import codeql.ruby.dataflow.FlowSummary
|
||||
private import codeql.ruby.Concepts
|
||||
|
||||
/**
|
||||
* Provides creation, verification and decoding JSON Web Tokens (JWT).
|
||||
*/
|
||||
module Jwt {
|
||||
/** A call to `JWT.encode`, considered as a JWT encoding. */
|
||||
private class JwtEncode extends JwtEncoding::Range, DataFlow::CallNode {
|
||||
JwtEncode() { this = API::getTopLevelMember("JWT").getAMethodCall("encode") }
|
||||
|
||||
override DataFlow::Node getPayload() { result = this.getArgument(0) }
|
||||
|
||||
override DataFlow::Node getAlgorithm() { result = this.getArgument(2) }
|
||||
|
||||
override DataFlow::Node getKey() { result = this.getArgument(1) }
|
||||
|
||||
override predicate signs() {
|
||||
not (this.getKey().getConstantValue().isStringlikeValue("") or this.getKey().(DataFlow::ExprNode).getConstantValue().isNil())
|
||||
}
|
||||
}
|
||||
|
||||
/** A call to `JWT.decode`, considered as a JWT decoding. */
|
||||
private class JwtDecode extends JwtDecoding::Range, DataFlow::CallNode {
|
||||
JwtDecode() { this = API::getTopLevelMember("JWT").getAMethodCall("decode") }
|
||||
|
||||
override DataFlow::Node getPayload() { result = this.getArgument(0) }
|
||||
|
||||
override DataFlow::Node getAlgorithm() {
|
||||
result.asExpr().getExpr() = this.getArgument(3).asExpr().getExpr().(Pair).getValue() or
|
||||
result =
|
||||
this.getArgument(3)
|
||||
.(DataFlow::HashLiteralNode)
|
||||
.getElementFromKey(any(Ast::ConstantValue cv | cv.isStringlikeValue("algorithm"))) or
|
||||
result = this.getArgument(2)
|
||||
}
|
||||
|
||||
override DataFlow::Node getKey() { result = this.getArgument(1) }
|
||||
|
||||
override DataFlow::Node getOptions() { result = this.getArgument(3) }
|
||||
|
||||
override predicate verifies() {
|
||||
not this.getArgument(2).getConstantValue().isBoolean(false) and
|
||||
not this.getAlgorithm().getConstantValue().isStringlikeValue("none")
|
||||
or
|
||||
this.getNumberOfArguments() < 3
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user