Skip to content

Commit 67ed863

Browse files
authored
Merge pull request #1200 from calumgrant/cs/icryptotransform
C#: Tidy up cs/thread-unsafe-icryptotransform-field-in-class
2 parents d619a8c + 42b2f09 commit 67ed863

File tree

4 files changed

+44
-65
lines changed

4 files changed

+44
-65
lines changed

change-notes/1.21/analysis-csharp.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
| **Query** | **Expected impact** | **Change** |
66
|------------------------------|------------------------|-----------------------------------|
7-
7+
| Class defines a field that uses an ICryptoTransform class in a way that would be unsafe for concurrent threads (`cs/thread-unsafe-icryptotransform-field-in-class`) | Fewer false positive results | The criteria for a result has changed to include nested properties, nested fields and collections. The format of the alert message has changed to highlight the static field. |
88

99
## Changes to code extraction
1010

Lines changed: 30 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* @name Class defines a field that uses an ICryptoTransform class in a way that would be unsafe for concurrent threads.
2+
* @name Class defines a field that uses an ICryptoTransform class in a way that would be unsafe for concurrent threads
33
* @description The class has a field that directly or indirectly make use of a static System.Security.Cryptography.ICryptoTransform object.
44
* Using this an instance of this class in concurrent threads is dangerous as it may not only result in an error,
55
* but under some circumstances may also result in incorrect results.
@@ -13,72 +13,44 @@
1313
*/
1414

1515
import csharp
16+
import semmle.code.csharp.frameworks.system.collections.Generic
1617

17-
class ICryptoTransform extends Class {
18-
ICryptoTransform() {
19-
this.getABaseType*().hasQualifiedName("System.Security.Cryptography", "ICryptoTransform")
18+
class UnsafeField extends Field {
19+
UnsafeField() {
20+
this.isStatic() and
21+
not this.getAnAttribute().getType().getQualifiedName() = "System.ThreadStaticAttribute" and
22+
this.getType() instanceof UsesICryptoTransform
2023
}
2124
}
2225

23-
predicate usesICryptoTransformType(Type t) {
24-
exists(ICryptoTransform ict |
25-
ict = t or
26-
usesICryptoTransformType(t.getAChild())
26+
ValueOrRefType getAnEnumeratedType(ValueOrRefType type) {
27+
exists(ConstructedInterface interface |
28+
interface = type.getABaseInterface*() and
29+
interface.getUnboundGeneric() instanceof SystemCollectionsGenericIEnumerableTInterface
30+
|
31+
result = interface.getATypeArgument()
2732
)
2833
}
2934

30-
predicate hasICryptoTransformMember(Class c) {
31-
exists(Field f |
32-
f = c.getAMember() and
33-
(
34-
exists(ICryptoTransform ict | ict = f.getType()) or
35-
hasICryptoTransformMember(f.getType()) or
36-
usesICryptoTransformType(f.getType())
37-
)
38-
)
39-
}
40-
41-
predicate hasICryptoTransformStaticMemberNested(Class c) {
42-
exists(Field f | f = c.getAMember() |
43-
hasICryptoTransformStaticMemberNested(f.getType())
35+
class UsesICryptoTransform extends ValueOrRefType {
36+
UsesICryptoTransform() {
37+
this instanceof ICryptoTransform
4438
or
45-
f.isStatic() and
46-
hasICryptoTransformMember(f.getType()) and
47-
not exists(Attribute a | a = f.getAnAttribute() |
48-
a.getType().getQualifiedName() = "System.ThreadStaticAttribute"
49-
)
50-
)
39+
this.getAField().getType() instanceof UsesICryptoTransform
40+
or
41+
this.getAProperty().getType() instanceof UsesICryptoTransform
42+
or
43+
getAnEnumeratedType(this) instanceof UsesICryptoTransform
44+
}
5145
}
5246

53-
predicate hasICryptoTransformStaticMember(Class c, string msg) {
54-
exists(Field f |
55-
f = c.getAMember*() and
56-
f.isStatic() and
57-
not exists(Attribute a |
58-
a = f.getAnAttribute() and
59-
a.getType().getQualifiedName() = "System.ThreadStaticAttribute"
60-
) and
61-
(
62-
exists(ICryptoTransform ict |
63-
ict = f.getType() and
64-
msg = "Static field " + f + " of type " + f.getType() +
65-
", implements 'System.Security.Cryptography.ICryptoTransform', but it does not have an attribute [ThreadStatic]. The usage of this class is unsafe for concurrent threads."
66-
)
67-
or
68-
not exists(ICryptoTransform ict | ict = f.getType()) and // Avoid dup messages
69-
exists(Type t | t = f.getType() |
70-
usesICryptoTransformType(t) and
71-
msg = "Static field " + f + " of type " + f.getType() +
72-
" makes usage of 'System.Security.Cryptography.ICryptoTransform', but it does not have an attribute [ThreadStatic]. The usage of this class is unsafe for concurrent threads."
73-
)
74-
)
75-
)
76-
or
77-
hasICryptoTransformStaticMemberNested(c) and
78-
msg = "Class" + c +
79-
" implementation depends on a static object of type 'System.Security.Cryptography.ICryptoTransform' in a way that is unsafe for concurrent threads."
47+
class ICryptoTransform extends ValueOrRefType {
48+
ICryptoTransform() {
49+
this.getABaseType*().hasQualifiedName("System.Security.Cryptography", "ICryptoTransform")
50+
}
8051
}
8152

82-
from Class c, string s
83-
where hasICryptoTransformStaticMember(c, s)
84-
select c, s
53+
from UnsafeField field
54+
select field,
55+
"Static field '" + field.getName() +
56+
"' contains a 'System.Security.Cryptography.ICryptoTransform' that could be used in an unsafe way."

csharp/ql/test/query-tests/Likely Bugs/ThreadUnsafeICryptoTransform/ThreadUnsafeICryptoTransform.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public enum DigestAlgorithm
5454
SHA256,
5555
}
5656

57-
private static readonly Dictionary<DigestAlgorithm, HashAlgorithm> HashMap = new Dictionary<DigestAlgorithm, HashAlgorithm>
57+
private static readonly IDictionary<DigestAlgorithm, HashAlgorithm> HashMap = new Dictionary<DigestAlgorithm, HashAlgorithm>
5858
{
5959
{ DigestAlgorithm.SHA1, SHA1.Create() },
6060
{ DigestAlgorithm.SHA256, SHA256.Create() },
@@ -112,3 +112,10 @@ private string ComputeHash(string password)
112112
}
113113
}
114114

115+
public class FuncTest
116+
{
117+
/// <summary>
118+
/// Should be OK. Does not store the field.
119+
/// </summary>
120+
public static Func<SHA1> function;
121+
}
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
| ThreadUnsafeICryptoTransform.cs:39:14:39:19 | Nest03 | ClassNest03 implementation depends on a static object of type 'System.Security.Cryptography.ICryptoTransform' in a way that is unsafe for concurrent threads. |
2-
| ThreadUnsafeICryptoTransform.cs:44:14:44:19 | Nest04 | ClassNest04 implementation depends on a static object of type 'System.Security.Cryptography.ICryptoTransform' in a way that is unsafe for concurrent threads. |
3-
| ThreadUnsafeICryptoTransform.cs:49:21:49:42 | StaticMemberChildUsage | Static field HashMap of type Dictionary<DigestAlgorithm,HashAlgorithm> makes usage of 'System.Security.Cryptography.ICryptoTransform', but it does not have an attribute [ThreadStatic]. The usage of this class is unsafe for concurrent threads. |
4-
| ThreadUnsafeICryptoTransform.cs:64:14:64:25 | StaticMember | Static field _sha1 of type SHA1, implements 'System.Security.Cryptography.ICryptoTransform', but it does not have an attribute [ThreadStatic]. The usage of this class is unsafe for concurrent threads. |
5-
| ThreadUnsafeICryptoTransform.cs:69:14:69:28 | IndirectStatic2 | ClassIndirectStatic2 implementation depends on a static object of type 'System.Security.Cryptography.ICryptoTransform' in a way that is unsafe for concurrent threads. |
1+
| ThreadUnsafeICryptoTransform.cs:41:36:41:37 | _n | Static field '_n' contains a 'System.Security.Cryptography.ICryptoTransform' that could be used in an unsafe way. |
2+
| ThreadUnsafeICryptoTransform.cs:46:26:46:30 | _list | Static field '_list' contains a 'System.Security.Cryptography.ICryptoTransform' that could be used in an unsafe way. |
3+
| ThreadUnsafeICryptoTransform.cs:57:73:57:79 | HashMap | Static field 'HashMap' contains a 'System.Security.Cryptography.ICryptoTransform' that could be used in an unsafe way. |
4+
| ThreadUnsafeICryptoTransform.cs:66:25:66:29 | _sha1 | Static field '_sha1' contains a 'System.Security.Cryptography.ICryptoTransform' that could be used in an unsafe way. |
5+
| ThreadUnsafeICryptoTransform.cs:71:19:71:20 | _n | Static field '_n' contains a 'System.Security.Cryptography.ICryptoTransform' that could be used in an unsafe way. |

0 commit comments

Comments
 (0)