Separating some reusable code into QLL libraries.

Fixing bugs from code review.
This commit is contained in:
Raul Garcia
2019-03-12 09:48:15 -07:00
parent 4ad9163fa8
commit 5be19d7da4
4 changed files with 73 additions and 56 deletions

View File

@@ -0,0 +1,36 @@
import csharp
import semmle.code.csharp.dataflow.DataFlow
import csharp
class ImplementsICryptoTransform extends Class {
ImplementsICryptoTransform() {
this.getABaseType*().hasQualifiedName("System.Security.Cryptography", "ICryptoTransform")
}
}
predicate usesICryptoTransformType( ValueOrRefType t ) {
exists( ImplementsICryptoTransform ict |
ict = t
or usesICryptoTransformType( t.getAChild() )
)
}
predicate hasICryptoTransformMember( Class c) {
c.getAField().getType() instanceof UsesICryptoTransform
}
class UsesICryptoTransform extends Class {
UsesICryptoTransform() {
usesICryptoTransformType(this) or hasICryptoTransformMember(this)
}
}
class LambdaCapturingICryptoTransformSource extends DataFlow::Node {
LambdaCapturingICryptoTransformSource() {
exists( LambdaExpr l, LocalScopeVariable lsvar, UsesICryptoTransform ict |
l = this.asExpr() |
ict = lsvar.getType()
and lsvar.getACapturingCallable() = l
)
}
}

View File

@@ -0,0 +1,18 @@
import csharp
import semmle.code.csharp.dataflow.DataFlow
abstract class ParallelSink extends DataFlow::Node {
}
class LambdaParallelSink extends ParallelSink {
LambdaParallelSink() {
exists( Class c, Method m, MethodCall mc, Expr e |
e = this.asExpr() |
c.getABaseType*().hasQualifiedName("System.Threading.Tasks", "Parallel")
and c.getAMethod() = m
and m.getName() = "Invoke"
and m.getACall() = mc
and mc.getAnArgument() = e
)
}
}

View File

@@ -4,9 +4,9 @@ public static void RunThreadUnSafeICryptoTransformLambdaFixed()
var b = new Barrier(threadCount);
Action start = () => {
b.SignalAndWait();
// The hash object is no longer shared
for (int i = 0; i < 1000; i++)
{
// The hash object is no longer shared
var sha1 = SHA1.Create();
var pwd = Guid.NewGuid().ToString();
var bytes = Encoding.UTF8.GetBytes(pwd);

View File

@@ -1,8 +1,8 @@
/**
* @name Potential usage of a n object implementing ICryptoTransform class in a way that would be unsafe for concurrent threads.
* @name Potential usage of an 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,
* Using 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
@@ -15,47 +15,21 @@
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) {
c.getAField().getType() instanceof UsesICryptoTransform
}
class UsesICryptoTransform extends Class {
UsesICryptoTransform() {
usesICryptoTransformType(this) or hasICryptoTransformMember(this)
}
}
import ParallelSink
import ICryptoTransform
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
)
source instanceof LambdaCapturingICryptoTransformSource
}
override predicate isSink(DataFlow::Node sink) {
exists( DelegateCreation dc, Expr e |
e = sink.asExpr() |
dc.getArgument() = e
and dc.getType().getName().matches("%Start")
e = sink.asExpr() |
dc.getArgument() = e
and dc.getType().getName().matches("%Start")
)
}
}
@@ -64,33 +38,22 @@ class NotThreadSafeCryptoUsageIntoParallelInvokeConfig extends TaintTracking::Co
NotThreadSafeCryptoUsageIntoParallelInvokeConfig() { this = "NotThreadSafeCryptoUsageIntoParallelInvokeConfig" }
override predicate isSource(DataFlow::Node source) {
exists( LambdaExpr l, LocalScopeVariable lsvar, UsesICryptoTransform ict |
l = source.asExpr() |
ict = lsvar.getType()
and lsvar.getACapturingCallable() = l
)
source instanceof LambdaCapturingICryptoTransformSource
}
override predicate isSink(DataFlow::Node sink) {
exists( Class c, Method m, MethodCall mc, Expr e |
e = sink.asExpr() |
c.getABaseType*().hasQualifiedName("System.Threading.Tasks", "Parallel")
and c.getAMethod() = m
and m.getName() = "Invoke"
and m.getACall() = mc
and mc.getAnArgument() = e
)
sink instanceof ParallelSink
}
}
from Expr e, string m
from Expr e, string m, LambdaExpr l
where
exists( NotThreadSafeCryptoUsageIntoParallelInvokeConfig config, LambdaExpr l |
config.hasFlow(DataFlow::exprNode(l), DataFlow::exprNode(e))
and m = "A Lambda expression at " + l.getLocation() + " seems to be used to start a new thread using System.Threading.Tasks.Parallel.Invoke, and is capturing a local variable that either implements 'System.Security.Cryptography.ICryptoTransform' or has a field of this type."
exists( NotThreadSafeCryptoUsageIntoParallelInvokeConfig config |
config.hasFlow(DataFlow::exprNode(l), DataFlow::exprNode(e))
and m = "A $@ seems to be used to start a new thread using System.Threading.Tasks.Parallel.Invoke, and is capturing a local variable that either implements 'System.Security.Cryptography.ICryptoTransform' or has a field of this type."
)
or exists ( NotThreadSafeCryptoUsageIntoStartingCallingConfig config, LambdaExpr l |
config.hasFlow(DataFlow::exprNode(l), DataFlow::exprNode(e))
and m = "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."
or exists ( NotThreadSafeCryptoUsageIntoStartingCallingConfig config |
config.hasFlow(DataFlow::exprNode(l), DataFlow::exprNode(e))
and m = "A $@ 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."
)
select e, m
select e, m, l, "lambda expression"