Update UnsafeUsageOfClientSideEncryptionVersion.ql

*  predicate `isUnsafeClientSideAzureStorageEncryptionViaObjectCreation` was not useful (it was meant to detect the SDK code, not its usage)
* fixed & simplified `isUnsafeClientSideAzureStorageEncryptionViaAttributes`, the original query was not finding the right code.
NOTE: tested with a real project: https://github.com/wastore/azure-storage-samples-for-python/tree/master/ClientSideEncryptionToServerSideEncryptionMigrationSamples/ClientSideEncryptionV1ToV2
This commit is contained in:
Raul Garcia
2023-03-20 18:52:58 -07:00
parent 569c38c833
commit 1400b4b520

View File

@@ -16,76 +16,38 @@ import semmle.python.ApiGraphs
predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrNode node) {
exists(
API::Node n, API::Node n2, Attribute a, AssignStmt astmt, API::Node uploadBlob,
ControlFlowNode ctrlFlowNode, string s
API::Node n, ControlFlowNode startingNode, Attribute attr, ControlFlowNode ctrlFlowNode,
Attribute attrUploadBlob, ControlFlowNode ctrlFlowNodeUploadBlob, string s1, string s2,
string s3
|
s in ["key_encryption_key", "key_resolver_function"] and
n =
API::moduleImport("azure")
.getMember("storage")
.getMember("blob")
.getMember("BlobClient")
.getReturn()
.getMember(s) and
n2 =
API::moduleImport("azure")
.getMember("storage")
.getMember("blob")
.getMember("BlobClient")
.getReturn()
.getMember("upload_blob") and
n.getAValueReachableFromSource().asExpr() = a and
astmt.getATarget() = a and
a.getAFlowNode() = node and
uploadBlob =
API::moduleImport("azure")
.getMember("storage")
.getMember("blob")
.getMember("BlobClient")
.getReturn()
.getMember("upload_blob") and
uploadBlob.getACall().asExpr() = call and
ctrlFlowNode = call.getAFlowNode() and
node.strictlyReaches(ctrlFlowNode) and
node != ctrlFlowNode and
call.getAChildNode() = attrUploadBlob and
node = ctrlFlowNode
|
s1 in ["key_encryption_key", "key_resolver_function"] and
s2 in ["ContainerClient", "BlobClient", "BlobServiceClient"] and
s3 in ["upload_blob"] and
n = API::moduleImport("azure").getMember("storage").getMember("blob").getMember(s2).getAMember() and
startingNode = n.getACall().getReturn().getAValueReachableFromSource().asExpr().getAFlowNode() and
startingNode.strictlyReaches(ctrlFlowNode) and
attr.getAFlowNode() = ctrlFlowNode and
attr.getName() = s1 and
ctrlFlowNode.strictlyReaches(ctrlFlowNodeUploadBlob) and
attrUploadBlob.getAFlowNode() = ctrlFlowNodeUploadBlob and
attrUploadBlob.getName() = s3 and
not exists(
AssignStmt astmt2, Attribute a2, AttrNode encryptionVersionSet, StrConst uc,
API::Node encryptionVersion
Attribute attrBarrier, ControlFlowNode ctrlFlowNodeBarrier, AssignStmt astmt2, StrConst uc
|
startingNode.strictlyReaches(ctrlFlowNodeBarrier) and
attrBarrier.getAFlowNode() = ctrlFlowNodeBarrier and
attrBarrier.getName() = "encryption_version" and
uc = astmt2.getValue() and
uc.getText() in ["'2.0'", "2.0"] and
encryptionVersion =
API::moduleImport("azure")
.getMember("storage")
.getMember("blob")
.getMember("BlobClient")
.getReturn()
.getMember("encryption_version") and
encryptionVersion.getAValueReachableFromSource().asExpr() = a2 and
astmt2.getATarget() = a2 and
a2.getAFlowNode() = encryptionVersionSet and
encryptionVersionSet.strictlyReaches(ctrlFlowNode)
)
)
}
predicate isUnsafeClientSideAzureStorageEncryptionViaObjectCreation(Call call, ControlFlowNode node) {
exists(API::Node c, string s, Keyword k | k.getAFlowNode() = node |
c.getACall().asExpr() = call and
c = API::moduleImport("azure").getMember("storage").getMember("blob").getMember(s) and
s in ["ContainerClient", "BlobClient", "BlobServiceClient"] and
k.getArg() = "key_encryption_key" and
k = call.getANamedArg() and
not k.getValue() instanceof None and
not exists(Keyword k2 | k2 = call.getANamedArg() |
k2.getArg() = "encryption_version" and
k2.getValue().(StrConst).getText() in ["'2.0'", "2.0"]
astmt2.getATarget().getAChildNode*() = attrBarrier and
ctrlFlowNodeBarrier.strictlyReaches(ctrlFlowNodeUploadBlob)
)
)
}
from Call call, ControlFlowNode node
where
isUnsafeClientSideAzureStorageEncryptionViaAttributes(call, node) or
isUnsafeClientSideAzureStorageEncryptionViaObjectCreation(call, node)
where isUnsafeClientSideAzureStorageEncryptionViaAttributes(call, node)
select node, "Unsafe usage of v1 version of Azure Storage client-side encryption."