Skip to content

Commit 09170e5

Browse files
committed
Crypto: Making generic literal filter more explicit that it is for filtering all constants, not just for algorithms.
1 parent 100045d commit 09170e5

File tree

3 files changed

+25
-29
lines changed

3 files changed

+25
-29
lines changed

cpp/ql/lib/experimental/quantum/Language.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
private import cpp as Language
22
import semmle.code.cpp.dataflow.new.TaintTracking
33
import codeql.quantum.experimental.Model
4-
private import experimental.quantum.OpenSSL.AlgorithmCandidateLiteral
4+
private import experimental.quantum.OpenSSL.GericSourceCandidateLiteral
55

66
module CryptoInput implements InputSig<Language::Location> {
77
class DataFlowNode = DataFlow::Node;
@@ -90,7 +90,7 @@ module GenericDataSourceFlowConfig implements DataFlow::ConfigSig {
9090
module GenericDataSourceFlow = TaintTracking::Global<GenericDataSourceFlowConfig>;
9191

9292
private class ConstantDataSource extends Crypto::GenericConstantSourceInstance instanceof Literal {
93-
ConstantDataSource() { this instanceof OpenSSLAlgorithmCandidateLiteral }
93+
ConstantDataSource() { this instanceof OpenSSLGenericSourceCandidateLiteral }
9494

9595
override DataFlow::Node getOutputNode() { result.asExpr() = this }
9696

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KnownAlgorithmConstants.qll

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import cpp
2-
import experimental.quantum.OpenSSL.AlgorithmCandidateLiteral
2+
import experimental.quantum.OpenSSL.GericSourceCandidateLiteral
33

44
predicate resolveAlgorithmFromExpr(Expr e, string normalizedName, string algType) {
55
resolveAlgorithmFromCall(e, normalizedName, algType)
@@ -103,7 +103,7 @@ predicate resolveAlgorithmFromCall(Call c, string normalized, string algType) {
103103
* If this predicate does not hold, then `e` can be interpreted as being of `UNKNOWN` type.
104104
*/
105105
predicate resolveAlgorithmFromLiteral(
106-
OpenSSLAlgorithmCandidateLiteral e, string normalized, string algType
106+
OpenSSLGenericSourceCandidateLiteral e, string normalized, string algType
107107
) {
108108
knownOpenSSLAlgorithmLiteral(_, e.getValue().toInt(), normalized, algType)
109109
or
@@ -237,11 +237,6 @@ predicate defaultAliases(string target, string alias) {
237237
alias = "ssl3-sha1" and target = "sha1"
238238
}
239239

240-
predicate tbd(string normalized, string algType) {
241-
knownOpenSSLAlgorithmLiteral(_, _, normalized, algType) and
242-
algType = "HASH"
243-
}
244-
245240
/**
246241
* Enumeration of all known crypto algorithms for openSSL
247242
* `name` is all lower case (caller's must ensure they pass in lower case)

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmCandidateLiteral.qll renamed to cpp/ql/lib/experimental/quantum/OpenSSL/GenericSourceCandidateLiteral.qll

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,24 @@ private import semmle.code.cpp.models.Models
33
private import semmle.code.cpp.models.interfaces.FormattingFunction
44

55
/**
6-
* Holds if a StringLiteral could be an algorithm literal.
6+
* Holds if a StringLiteral could conceivably be used in some way for cryptography.
77
* Note: this predicate should only consider restrictions with respect to strings only.
8-
* General restrictions are in the OpenSSLAlgorithmCandidateLiteral class.
8+
* General restrictions are in the OpenSSLGenericSourceCandidateLiteral class.
99
*/
10-
private predicate isOpenSSLStringLiteralAlgorithmCandidate(StringLiteral s) {
10+
private predicate isOpenSSLStringLiteralGenericSourceCandidate(StringLiteral s) {
1111
// 'EC' is a constant that may be used where typical algorithms are specified,
1212
// but EC specifically means set up a default curve container, that will later be
1313
//specified explicitly (or if not a default) curve is used.
1414
s.getValue() != "EC" and
1515
// Ignore empty strings
1616
s.getValue() != "" and
17-
// ignore strings that represent integers, it is possible this could be used for actual
18-
// algorithms but assuming this is not the common case
19-
// NOTE: if we were to revert this restriction, we should still consider filtering "0"
20-
// to be consistent with filtering integer 0
21-
not exists(s.getValue().toInt()) and
2217
// Filter out strings with "%", to filter out format strings
2318
not s.getValue().matches("%\\%%") and
24-
// Filter out strings in brackets or braces
19+
// Filter out strings in brackets or braces (commonly seen strings not relevant for crypto)
2520
not s.getValue().matches(["[%]", "(%)"]) and
2621
// Filter out all strings of length 1, since these are not algorithm names
22+
// NOTE/ASSUMPTION: If a user legitimately passes a string of length 1 to some configuration
23+
// we will assume this is generally unknown. We may need to reassess this in the future.
2724
s.getValue().length() > 1 and
2825
// Ignore all strings that are in format string calls outputing to a stream (e.g., stdout)
2926
not exists(FormattingFunctionCall f |
@@ -43,15 +40,14 @@ private predicate isOpenSSLStringLiteralAlgorithmCandidate(StringLiteral s) {
4340
/**
4441
* Holds if an IntLiteral could be an algorithm literal.
4542
* Note: this predicate should only consider restrictions with respect to integers only.
46-
* General restrictions are in the OpenSSLAlgorithmCandidateLiteral class.
43+
* General restrictions are in the OpenSSLGenericSourceCandidateLiteral class.
4744
*/
48-
private predicate isOpenSSLIntLiteralAlgorithmCandidate(Literal l) {
45+
private predicate isOpenSSLIntLiteralGenericSourceCandidate(Literal l) {
4946
exists(l.getValue().toInt()) and
5047
// Ignore char literals
5148
not l instanceof CharLiteral and
5249
not l instanceof StringLiteral and
5350
// Ignore integer values of 0, commonly referring to NULL only (no known algorithm 0)
54-
// Also ignore integer values greater than 5000
5551
l.getValue().toInt() != 0 and
5652
// ASSUMPTION, no negative numbers are allowed
5753
// RATIONALE: this is a performance improvement to avoid having to trace every number
@@ -63,10 +59,9 @@ private predicate isOpenSSLIntLiteralAlgorithmCandidate(Literal l) {
6359
r.getExpr() = l and
6460
r.getEnclosingFunction().getType().getUnspecifiedType() instanceof DerivedType
6561
) and
66-
// A literal as an array index should never be an algorithm
62+
// A literal as an array index should not be relevant for crypo
6763
not exists(ArrayExpr op | op.getArrayOffset() = l) and
68-
// A literal used in a bitwise operation may be an algorithm, but not a candidate
69-
// for the purposes of finding applied algorithms
64+
// A literal used in a bitwise should not be relevant for crypto
7065
not exists(BinaryBitwiseOperation op | op.getAnOperand() = l) and
7166
not exists(AssignBitwiseOperation op | op.getAnOperand() = l) and
7267
//Filter out cases where an int is assigned or initialized into a pointer, e.g., char* x = NULL;
@@ -81,7 +76,13 @@ private predicate isOpenSSLIntLiteralAlgorithmCandidate(Literal l) {
8176
// Filter out cases where the literal is used in any kind of arithmetic operation
8277
not exists(BinaryArithmeticOperation op | op.getAnOperand() = l) and
8378
not exists(UnaryArithmeticOperation op | op.getOperand() = l) and
84-
not exists(AssignArithmeticOperation op | op.getAnOperand() = l)
79+
not exists(AssignArithmeticOperation op | op.getAnOperand() = l) and
80+
// If a literal has no parent ignore it, this is a workaround for the current inability
81+
// to find a literal in an array declaration: int x[100];
82+
// NOTE/ASSUMPTION: this value might actually be relevant for finding hard coded sizes
83+
// consider size as inferred through the allocation of a buffer.
84+
// In these cases, we advise that the source is not generic and must be traced explicitly.
85+
exists(l.getParent())
8586
}
8687

8788
/**
@@ -96,11 +97,11 @@ private predicate isOpenSSLIntLiteralAlgorithmCandidate(Literal l) {
9697
* "AES" may be a legitimate algorithm literal, but the literal will not be used for an operation directly
9798
* since it is in a equality comparison, hence this case would also be filtered.
9899
*/
99-
class OpenSSLAlgorithmCandidateLiteral extends Literal {
100-
OpenSSLAlgorithmCandidateLiteral() {
100+
class OpenSSLGenericSourceCandidateLiteral extends Literal {
101+
OpenSSLGenericSourceCandidateLiteral() {
101102
(
102-
isOpenSSLIntLiteralAlgorithmCandidate(this) or
103-
isOpenSSLStringLiteralAlgorithmCandidate(this)
103+
isOpenSSLIntLiteralGenericSourceCandidate(this) or
104+
isOpenSSLStringLiteralGenericSourceCandidate(this)
104105
) and
105106
// ********* General filters beyond what is filtered for strings and ints *********
106107
// An algorithm literal in a switch case will not be directly applied to an operation.

0 commit comments

Comments
 (0)