-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathThreadUnsafeICryptoTransformLambda.ql
More file actions
72 lines (63 loc) · 2.62 KB
/
ThreadUnsafeICryptoTransformLambda.ql
File metadata and controls
72 lines (63 loc) · 2.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/**
* @name Potential usage of a n object implementing ICryptoTransform class in a way that would be unsafe for concurrent threads.
* @description An instance of a class that either implements or has a field of type System.Security.Cryptography.ICryptoTransform is being captured by a lambda,
* and used in what seems to be a thread initialization method.
* Using this an instance of this class in concurrent threads is dangerous as it may not only result in an error,
* but under some circumstances may also result in incorrect results.
* @kind problem
* @problem.severity warning
* @precision medium
* @id cs/thread-unsafe-icryptotransform-captured-in-lambda
* @tags concurrency
* security
* external/cwe/cwe-362
*/
import csharp
import semmle.code.csharp.dataflow.DataFlow
class ICryptoTransform extends Class {
ICryptoTransform() {
this.getABaseType*().hasQualifiedName("System.Security.Cryptography", "ICryptoTransform")
}
}
predicate usesICryptoTransformType( Type t ) {
exists( ICryptoTransform ict |
ict = t
or usesICryptoTransformType( t.getAChild() )
or usesICryptoTransformType( t.(Class).getAMember() )
)
}
predicate hasICryptoTransformMember( Class c) {
exists( Field f |
f = c.getAMember()
and (
exists( ICryptoTransform ict | ict = f.getType() )
or hasICryptoTransformMember(f.getType())
or usesICryptoTransformType(f.getType())
)
)
}
class UsesICryptoTransform extends Class {
UsesICryptoTransform() {
usesICryptoTransformType(this) or hasICryptoTransformMember(this)
}
}
class NotThreadSafeCryptoUsageIntoStartingCallingConfig extends TaintTracking::Configuration {
NotThreadSafeCryptoUsageIntoStartingCallingConfig() { this = "NotThreadSafeCryptoUsageIntoStartingCallingConfig" }
override predicate isSource(DataFlow::Node source) {
exists( LambdaExpr l, LocalScopeVariable lsvar, UsesICryptoTransform ict |
l = source.asExpr() |
ict = lsvar.getType()
and lsvar.getACapturingCallable() = l
)
}
override predicate isSink(DataFlow::Node sink) {
exists( DelegateCreation dc, Expr e |
e = sink.asExpr() |
dc.getArgument() = e
and dc.getType().getName().matches("%Start")
)
}
}
from NotThreadSafeCryptoUsageIntoStartingCallingConfig config, LambdaExpr l, Expr e
where config.hasFlow(DataFlow::exprNode(l), DataFlow::exprNode(e))
select e, "A Lambda expression at " + l.getLocation() + " seems to be used to start a new thread is capturing a local variable that either implements 'System.Security.Cryptography.ICryptoTransform' or has a field of this type."