|
1 | 1 | /** |
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 |
3 | 3 | * @description The class has a field that directly or indirectly make use of a static System.Security.Cryptography.ICryptoTransform object. |
4 | 4 | * Using this an instance of this class in concurrent threads is dangerous as it may not only result in an error, |
5 | 5 | * but under some circumstances may also result in incorrect results. |
|
13 | 13 | */ |
14 | 14 |
|
15 | 15 | import csharp |
| 16 | +import semmle.code.csharp.frameworks.system.collections.Generic |
16 | 17 |
|
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 |
20 | 23 | } |
21 | 24 | } |
22 | 25 |
|
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() |
27 | 32 | ) |
28 | 33 | } |
29 | 34 |
|
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 |
44 | 38 | 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 | + } |
51 | 45 | } |
52 | 46 |
|
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 | + } |
80 | 51 | } |
81 | 52 |
|
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." |
0 commit comments