M4: No Explicit Algorithm Allowlist in JWT Validation
Severity: MEDIUM
Category: Cryptographic Weakness / Algorithm Confusion
File: src/Spe/Core/Settings/Authorization/SharedSecretAuthenticationProvider.cs
Lines: 235–249 (ComputeHash method)
Risk Explanation
The ComputeHash method selects the HMAC algorithm based on the alg claim from the untrusted JWT header:
switch (algorithm)
{
case "HS256": using (var hmac = new HMACSHA256(key)) { return hmac.ComputeHash(data); }
case "HS384": using (var hmac = new HMACSHA384(key)) { return hmac.ComputeHash(data); }
case "HS512": using (var hmac = new HMACSHA512(key)) { return hmac.ComputeHash(data); }
default: return null;
}
The alg: "none" attack is currently blocked by accident — ComputeHash returns null, and the subsequent Convert.ToBase64String(hash) throws a NullReferenceException, caught by the generic catch (Exception) block.
Why this is fragile:
- If anyone refactors to handle
null gracefully, the alg: "none" bypass becomes exploitable.
- If new algorithms are added (e.g., RS256), an attacker could force algorithm confusion (classic CVE-2015-9235).
- The defense is not visible or documented — a future developer will not know the
NullReferenceException is load-bearing.
Implementation Plan
Add an explicit algorithm allowlist check before the switch statement, and a fail-closed null check after:
private static readonly HashSet<string> AllowedAlgorithms = new HashSet<string>(StringComparer.Ordinal)
{
"HS256", "HS384", "HS512"
};
private byte[] ComputeHash(string algorithm, byte[] key, byte[] data)
{
if (!AllowedAlgorithms.Contains(algorithm))
{
PowerShellLog.Warn($"[Auth] action=algorithmRejected algorithm={algorithm}");
return null;
}
// ... existing cases ...
}
And after ComputeHash returns:
var hash = ComputeHash(tokenHeader.Alg, keyBytes, inputBytes);
if (hash == null)
{
PowerShellLog.Warn("[Auth] action=authFailed reason=unsupportedAlgorithm");
return false;
}
var computedSignature = Convert.ToBase64String(hash);
Files to modify
| File |
Change |
src/Spe/Core/Settings/Authorization/SharedSecretAuthenticationProvider.cs |
Add algorithm allowlist, null check after ComputeHash |
Test Plan
- Unit test —
alg: "none" token: Rejected.
- Unit test — unknown algorithms: RS256, ES256, PS256, empty, NONE, hs256 (case-sensitive) — all rejected.
- Unit test — allowed algorithms: HS256, HS384, HS512 — all accepted.
- Warning is logged when unsupported algorithm is attempted.
- Existing JWT authentication tests pass.
M4: No Explicit Algorithm Allowlist in JWT Validation
Severity: MEDIUM
Category: Cryptographic Weakness / Algorithm Confusion
File:
src/Spe/Core/Settings/Authorization/SharedSecretAuthenticationProvider.csLines: 235–249 (ComputeHash method)
Risk Explanation
The
ComputeHashmethod selects the HMAC algorithm based on thealgclaim from the untrusted JWT header:The
alg: "none"attack is currently blocked by accident —ComputeHashreturnsnull, and the subsequentConvert.ToBase64String(hash)throws aNullReferenceException, caught by the genericcatch (Exception)block.Why this is fragile:
nullgracefully, thealg: "none"bypass becomes exploitable.NullReferenceExceptionis load-bearing.Implementation Plan
Add an explicit algorithm allowlist check before the switch statement, and a fail-closed null check after:
And after ComputeHash returns:
Files to modify
src/Spe/Core/Settings/Authorization/SharedSecretAuthenticationProvider.csTest Plan
alg: "none"token: Rejected.