Skip to content

Commit 5abc596

Browse files
chanel-yCopilot
andcommitted
Add weak HMAC algorithm detection query for PowerShell
Detects HMACMD5, HMACSHA1, and HMACRIPEMD160 usage via New-Object, static Create(), and ::new() patterns. Covers: Cryptography.10020 (CWE-327, CWE-328) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent cccecc4 commit 5abc596

4 files changed

Lines changed: 125 additions & 0 deletions

File tree

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/**
2+
* @name Use of weak HMAC algorithm
3+
* @description Using weak HMAC algorithms like HMACMD5 or HMACSHA1 can compromise message authentication.
4+
* @kind problem
5+
* @problem.severity warning
6+
* @security-severity 7.5
7+
* @precision high
8+
* @id powershell/microsoft/security/weak-hmac
9+
* @tags security
10+
* external/cwe/cwe-327
11+
* external/cwe/cwe-328
12+
*/
13+
14+
import powershell
15+
import semmle.code.powershell.ApiGraphs
16+
import semmle.code.powershell.dataflow.DataFlow
17+
import semmle.code.powershell.security.cryptography.CryptographyModule
18+
19+
/**
20+
* Holds if `name` is a weak HMAC algorithm name (lowercase).
21+
*/
22+
predicate isWeakHmacAlgorithm(string name) {
23+
name = ["hmacmd5", "hmacsha1", "hmacripemd160"]
24+
}
25+
26+
/** A weak HMAC algorithm instantiated via New-Object. */
27+
class WeakHmacObjectCreation extends DataFlow::ObjectCreationNode {
28+
string algName;
29+
30+
WeakHmacObjectCreation() {
31+
exists(string objName |
32+
objName =
33+
this.getExprNode().getExpr().(CallExpr).getAnArgument().getValue().asString().toLowerCase() and
34+
(
35+
objName = "system.security.cryptography." + algName or
36+
objName = algName
37+
) and
38+
isWeakHmacAlgorithm(algName)
39+
)
40+
}
41+
42+
string getName() { result = algName }
43+
}
44+
45+
/** A weak HMAC algorithm instantiated via [Type]::Create() or [Type]::new(). */
46+
class WeakHmacCreateCall extends DataFlow::CallNode {
47+
string algName;
48+
49+
WeakHmacCreateCall() {
50+
isWeakHmacAlgorithm(algName) and
51+
(
52+
this =
53+
API::getTopLevelMember("system")
54+
.getMember("security")
55+
.getMember("cryptography")
56+
.getMember(algName)
57+
.getMember("create")
58+
.asCall()
59+
or
60+
this =
61+
API::getTopLevelMember("system")
62+
.getMember("security")
63+
.getMember("cryptography")
64+
.getMember(algName)
65+
.getMember("new")
66+
.asCall()
67+
)
68+
}
69+
70+
string getName() { result = algName }
71+
}
72+
73+
/** A weak HMAC algorithm passed as string to CryptoConfig.CreateFromName(). */
74+
class WeakHmacCreateFromNameCall extends CryptoAlgorithmCreateFromNameCall {
75+
string algName;
76+
77+
WeakHmacCreateFromNameCall() {
78+
objectName = ["", "system.security.cryptography."] + algName and
79+
isWeakHmacAlgorithm(algName)
80+
}
81+
82+
string getHmacName() { result = algName }
83+
}
84+
85+
from DataFlow::Node node, string algName
86+
where
87+
exists(WeakHmacObjectCreation c | node = c and algName = c.getName())
88+
or
89+
exists(WeakHmacCreateCall c | node = c and algName = c.getName())
90+
or
91+
exists(WeakHmacCreateFromNameCall c | node = c and algName = c.getHmacName())
92+
select node, "Use of weak HMAC algorithm: " + algName + ". Use HMACSHA256 or stronger."
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.ps1:6:9:6:55 | Call to new-object | Use of weak HMAC algorithm: hmacmd5. Use HMACSHA256 or stronger. |
2+
| test.ps1:9:9:9:56 | Call to new-object | Use of weak HMAC algorithm: hmacsha1. Use HMACSHA256 or stronger. |
3+
| test.ps1:12:9:12:56 | Call to create | Use of weak HMAC algorithm: hmacmd5. Use HMACSHA256 or stronger. |
4+
| test.ps1:15:9:15:54 | Call to new | Use of weak HMAC algorithm: hmacsha1. Use HMACSHA256 or stronger. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
queries/security/cwe-328/WeakHmac.ql
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# ===================================================================
2+
# ========== TRUE POSITIVES (should trigger alert) ==================
3+
# ===================================================================
4+
5+
# --- Case 1: HMACMD5 via New-Object ---
6+
$hmac = New-Object System.Security.Cryptography.HMACMD5 # BAD
7+
8+
# --- Case 2: HMACSHA1 via New-Object ---
9+
$hmac = New-Object System.Security.Cryptography.HMACSHA1 # BAD
10+
11+
# --- Case 3: HMACMD5 via static Create ---
12+
$hmac = [System.Security.Cryptography.HMACMD5]::Create() # BAD
13+
14+
# --- Case 4: HMACSHA1 via ::new() ---
15+
$hmac = [System.Security.Cryptography.HMACSHA1]::new() # BAD
16+
17+
# ===================================================================
18+
# ========== TRUE NEGATIVES (should NOT trigger alert) ==============
19+
# ===================================================================
20+
21+
# --- Safe: HMACSHA256 ---
22+
$hmac = New-Object System.Security.Cryptography.HMACSHA256 # GOOD
23+
24+
# --- Safe: HMACSHA384 ---
25+
$hmac = [System.Security.Cryptography.HMACSHA384]::new() # GOOD
26+
27+
# --- Safe: HMACSHA512 ---
28+
$hmac = [System.Security.Cryptography.HMACSHA512]::Create() # GOOD

0 commit comments

Comments
 (0)