mirror of
https://github.com/github/codeql.git
synced 2026-07-07 12:35:33 +02:00
91 lines
3.2 KiB
Plaintext
91 lines
3.2 KiB
Plaintext
/**
|
|
* @name Unsafe usage of v1 version of Azure Storage client-side encryption.
|
|
* @description Using version v1 of Azure Storage client-side encryption is insecure, and may enable an attacker to decrypt encrypted data
|
|
* @kind problem
|
|
* @tags security
|
|
* cryptography
|
|
* external/cwe/cwe-327
|
|
* @id py/azure-storage/unsafe-client-side-encryption-in-use
|
|
* @problem.severity error
|
|
* @precision medium
|
|
*/
|
|
|
|
import python
|
|
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
|
|
|
|
|
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
|
|
not exists(
|
|
AssignStmt astmt2, Attribute a2, AttrNode encryptionVersionSet, StrConst uc,
|
|
API::Node encryptionVersion
|
|
|
|
|
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"]
|
|
)
|
|
)
|
|
}
|
|
|
|
from Call call, ControlFlowNode node
|
|
where
|
|
isUnsafeClientSideAzureStorageEncryptionViaAttributes(call, node) or
|
|
isUnsafeClientSideAzureStorageEncryptionViaObjectCreation(call, node)
|
|
select node, "Unsafe usage of v1 version of Azure Storage client-side encryption."
|