Skip to content

Commit ac05577

Browse files
Making various changes based on the feedback. Pending: 2 non-trivial fixes for Java & Python.
1 parent e5702d0 commit ac05577

File tree

8 files changed

+51
-39
lines changed

8 files changed

+51
-39
lines changed

csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
11

2+
{
3+
SymmetricKey aesKey = new SymmetricKey(kid: "symencryptionkey");
4+
5+
// BAD: Using the outdated client side encryption version V1_0
6+
BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(key: aesKey, keyResolver: null);
7+
BlobRequestOptions uploadOptions = new BlobRequestOptions() { EncryptionPolicy = uploadPolicy };
8+
9+
MemoryStream stream = new MemoryStream(buffer);
10+
blob.UploadFromStream(stream, length: size, accessCondition: null, options: uploadOptions);
11+
}
12+
213
var client = new BlobClient(myConnectionString, new SpecializedBlobClientOptions()
314
{
415
// BAD: Using an outdated SDK that does not support client side encryption version V2_0

csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
<li>
2222
<a href="http://aka.ms/azstorageclientencryptionblog">Azure Storage Client Encryption Blog.</a>
2323
</li>
24+
<li>
25+
<a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-PENDING">CVE-2022-PENDING</a>
26+
</li>
2427

2528
</references>
2629
</qhelp>

csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,25 @@ predicate isCreatingOutdatedAzureClientSideEncryptionObject(ObjectCreation oc, C
3333
}
3434

3535
/**
36-
* Holds if the Azure.Storage assembly for `c` is a version knwon to support
37-
* version 2+ for client-side encryption and if the argument for the constructor `version`
38-
* is set to a secure value.
36+
* Holds if the Azure.Storage assembly for `c` is a version known to support
37+
* version 2+ for client-side encryption
3938
*/
40-
predicate isObjectCreationSafe(Expr versionExpr, Assembly asm) {
41-
// Check if the Azure.Storage assembly version has the fix
39+
predicate doesAzureStorageAssemblySupportSafeClientSideEncryption(Assembly asm) {
4240
exists(int versionCompare |
4341
versionCompare = asm.getVersion().compareTo("12.12.0.0") and
4442
versionCompare >= 0
4543
) and
44+
asm.getName() = "Azure.Storage.Common"
45+
}
46+
47+
/**
48+
* Holds if the Azure.Storage assembly for `c` is a version known to support
49+
* version 2+ for client-side encryption and if the argument for the constructor `version`
50+
* is set to a secure value.
51+
*/
52+
predicate isObjectCreationArgumentSafeAndUsingSafeVersionOfAssembly(Expr versionExpr, Assembly asm) {
53+
// Check if the Azure.Storage assembly version has the fix
54+
doesAzureStorageAssemblySupportSafeClientSideEncryption(asm) and
4655
// and that the version argument for the constructor is guaranteed to be Version2
4756
isExprAnAccessToSafeClientSideEncryptionVersionValue(versionExpr)
4857
}
@@ -56,8 +65,6 @@ predicate isExprAnAccessToSafeClientSideEncryptionVersionValue(Expr e) {
5665
ec.hasQualifiedName("Azure.Storage.ClientSideEncryptionVersion.V2_0") and
5766
ec.getAnAccess() = e
5867
)
59-
or
60-
e.getValue().toInt() >= 2
6168
}
6269

6370
from Expr e, Class c, Assembly asm
@@ -66,10 +73,9 @@ where
6673
(
6774
exists(Expr e2 |
6875
isCreatingAzureClientSideEncryptionObject(e, c, e2) and
69-
not isObjectCreationSafe(e2, asm)
76+
not isObjectCreationArgumentSafeAndUsingSafeVersionOfAssembly(e2, asm)
7077
)
7178
or
7279
isCreatingOutdatedAzureClientSideEncryptionObject(e, c)
7380
)
74-
select e,
75-
"Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-PENDING). See http://aka.ms/azstorageclientencryptionblog"
81+
select e, "Unsafe usage of v1 version of Azure Storage client-side encryption."

java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,16 @@
1414
</recommendation>
1515
<example>
1616

17-
<p>The following example shows an HTTP request parameter being used directly in a forming a
18-
new request without validating the input, which facilitates SSRF attacks.
19-
It also shows how to remedy the problem by validating the user input against a known fixed string.
20-
</p>
21-
2217
<sample src="UnsafeUsageOfClientSideEncryptionVersion.java" />
2318

2419
</example>
2520
<references>
2621
<li>
2722
<a href="http://aka.ms/azstorageclientencryptionblog">Azure Storage Client Encryption Blog.</a>
2823
</li>
24+
<li>
25+
<a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-PENDING">CVE-2022-PENDING</a>
26+
</li>
2927

3028
</references>
3129
</qhelp>

java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import java
1414

1515
/**
16-
* Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder`
16+
* Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder`
1717
* that takes no arguments, which means that it is using V1 encryption
1818
*/
1919
predicate isCreatingOutdatedAzureClientSideEncryptionObject(Call call, Class c) {
@@ -31,8 +31,8 @@ predicate isCreatingOutdatedAzureClientSideEncryptionObject(Call call, Class c)
3131
)
3232
}
3333

34-
/**
35-
* Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder`
34+
/**
35+
* Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder`
3636
* that takes `versionArg` as the argument for the version.
3737
*/
3838
predicate isCreatingAzureClientSideEncryptionObjectNewVersion(Call call, Class c, Expr versionArg) {
@@ -47,7 +47,7 @@ predicate isCreatingAzureClientSideEncryptionObjectNewVersion(Call call, Class c
4747
}
4848

4949
/**
50-
* Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder`
50+
* Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder`
5151
* that takes `versionArg` as the argument for the version, and the version number is safe
5252
*/
5353
predicate isCreatingSafeAzureClientSideEncryptionObject(Call call, Class c, Expr versionArg) {
@@ -67,5 +67,4 @@ where
6767
)
6868
or
6969
isCreatingOutdatedAzureClientSideEncryptionObject(e, c)
70-
select e,
71-
"Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-PENDING). See http://aka.ms/azstorageclientencryptionblog"
70+
select e, "Unsafe usage of v1 version of Azure Storage client-side encryption."
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name)
2-
blob_client.require_encryption = True
3-
blob_client.key_encryption_key = kek
4-
# GOOD: Must use `encryption_version` set to `2.0`
5-
blob_client.encryption_version = '2.0' # Use Version 2.0!
6-
with open(“decryptedcontentfile.txt”, “rb”) as stream:
7-
blob_client.upload_blob(stream, overwrite=OVERWRITE_EXISTING)
2+
blob_client.require_encryption = True
3+
blob_client.key_encryption_key = kek
4+
# GOOD: Must use `encryption_version` set to `2.0`
5+
blob_client.encryption_version = '2.0' # Use Version 2.0!
6+
with open(“decryptedcontentfile.txt”, “rb”) as stream:
7+
blob_client.upload_blob(stream, overwrite=OVERWRITE_EXISTING)

python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,16 @@
1414
</recommendation>
1515
<example>
1616

17-
<p>The following example shows an HTTP request parameter being used directly in a forming a
18-
new request without validating the input, which facilitates SSRF attacks.
19-
It also shows how to remedy the problem by validating the user input against a known fixed string.
20-
</p>
21-
2217
<sample src="UnsafeUsageOfClientSideEncryptionVersion.py" />
2318

2419
</example>
2520
<references>
2621
<li>
2722
<a href="http://aka.ms/azstorageclientencryptionblog">Azure Storage Client Encryption Blog.</a>
2823
</li>
24+
<li>
25+
<a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-PENDING">CVE-2022-PENDING</a>
26+
</li>
2927

3028
</references>
3129
</qhelp>

python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrN
2424
not astmt.getValue() instanceof None and
2525
not exists(AssignStmt astmt2, Attribute a2, AttrNode encryptionVersionSet, StrConst uc |
2626
uc = astmt2.getValue() and
27-
uc.getLiteralValue().toString() in ["'2.0'", "2.0"] and
27+
uc.getText() in ["'2.0'", "2.0"] and
2828
a2.getAttr() = "encryption_version" and
2929
a2.getAFlowNode() = encryptionVersionSet and
3030
encryptionVersionSet.strictlyReaches(ctrlFlowNode)
@@ -34,15 +34,13 @@ predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrN
3434

3535
predicate isUnsafeClientSideAzureStorageEncryptionViaObjectCreation(Call call, ControlFlowNode node) {
3636
exists(Keyword k | k.getAFlowNode() = node |
37-
call.getFunc().(Name).getId().toString() in [
38-
"ContainerClient", "BlobClient", "BlobServiceClient"
39-
] and
37+
call.getFunc().(Name).getId() in ["ContainerClient", "BlobClient", "BlobServiceClient"] and
4038
k.getArg() = "key_encryption_key" and
4139
k = call.getANamedArg() and
4240
not k.getValue() instanceof None and
4341
not exists(Keyword k2 | k2 = call.getANamedArg() |
4442
k2.getArg() = "encryption_version" and
45-
k2.getValue().(StrConst).getLiteralValue().toString() in ["'2.0'", "2.0"]
43+
k2.getValue().(StrConst).getText() in ["'2.0'", "2.0"]
4644
)
4745
)
4846
}
@@ -51,5 +49,4 @@ from Call call, ControlFlowNode node
5149
where
5250
isUnsafeClientSideAzureStorageEncryptionViaAttributes(call, node) or
5351
isUnsafeClientSideAzureStorageEncryptionViaObjectCreation(call, node)
54-
select node,
55-
"Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-PENDING). See http://aka.ms/azstorageclientencryptionblog"
52+
select node, "Unsafe usage of v1 version of Azure Storage client-side encryption."

0 commit comments

Comments
 (0)