Compliance & CWE Coverage
jSentinel’s credential layer is designed against three reference frameworks, with an explicit traceability artifact for each:
| Standard | Scope | Where it shows up |
|---|---|---|
| OWASP ASVS V2 (Authentication) | Verification requirements for credential storage, lifecycle and recovery | Per-control mapping in the repo’s credential/standards package |
| NIST SP 800-63B | Memorised-secret rules: length, breached-password checks, no composition rules, rate limiting | Input policy, compromised-password checker, abuse detection |
| CWE (MITRE) | 40 concrete weakness classes | Full matrix below |
Threat-vector coverage
The credential layer is built bottom-up from a catalogue of concrete attacks. Each row is countered by a cluster of features — most measures raise the cost of an attack or prevent a specific exploitation rather than guaranteeing absolute security.
| Category | Attack vector | Countered by |
|---|---|---|
| Offline hash attacks | Offline brute-force / dictionary | Memory-hard KDF (Argon2id / scrypt), per-hash salt, pepper, high PBKDF2 iteration floor |
| GPU / ASIC / FPGA cracking | Argon2id / scrypt memory-hardness | |
| Rainbow tables / precomputation | Per-credential random salt | |
| DB leak without the pepper | Post-KDF HMAC pepper held separately from the hash DB | |
| Stale, un-upgraded parameters | Rehash-on-verify with deterministic precedence | |
| Format / algorithm tampering | Algorithm downgrade / silent fallback | Fail-fast when the modern profile’s provider is absent (no silent downgrade) |
| Forged / unknown algorithm id | Self-describing envelope + strict parameter validators | |
| Format confusion / forward-incompat | Versioned $pwh$v=1$… envelope, rejected-version policy | |
| Resource / DoS | KDF resource exhaustion | KdfExecutionLimiter (concurrency + wait budget) |
| Crafted-parameter “decompression bomb” | Parameter bounds validated before any KDF; memory cost overflow-checked | |
| Online login attacks | Online brute-force | Abuse detection + LoginAttemptPolicy + rate limiting |
| Credential stuffing | Compromised-password check, abuse detection, multi-dim sliding window | |
| Password spraying | Global / tenant sliding-window spraying detector | |
| Enumeration & side channels | Account enumeration (response + timing) | verifyAgainstNothing dummy KDF, generic perimeter responses |
| Timing side channel on compare | Constant-time MessageDigest.isEqual | |
| Tenant enumeration | Generic public errors, no tenant leak | |
| Password quality | Weak / guessable passwords | Input policy, breached-password blocklist + HIBP |
| Context-trivial password | ContextAwarePasswordValidator (username / email / term overlap) | |
| Reuse on change | Optional PasswordHistoryService | |
| bcrypt-specific | 72-byte truncation | Explicit rejection, no silent pre-hashing |
| Password shucking | Same — no upstream unsalted hash | |
| Reset / recovery | Reset-token guessing | 16-byte selector + 32-byte verifier from SecureRandom |
| Reset-token DB theft | Digest-only storage (selector/verifier model) | |
| Reset-token replay | Single-use via dual compare-and-swap | |
| Reset abuse / mail-bombing / enumeration | Generic responses + abuse detection on the reset flow | |
| Credential lifecycle | Account takeover via password change w/o re-auth | Mandatory re-authentication in PasswordChangeService |
| Lingering sessions after compromise/change | INVALIDATE_OTHER_SESSIONS default | |
| Persistence / concurrency | Race condition / lost update (TOCTOU) | Compare-and-swap on every credential mutation |
| Migration blind-overwrite | CAS witness (originalEncodedHash) on rehash | |
| Secret exposure | Secret leak via logs / toString() / heap | SecretValue (AutoCloseable), redacted toString, zeroed buffers |
| Secret / token leak via audit / errors | Audit-only internal types, perimeter-safe public types | |
| Supply chain / crypto trust | Compromised crypto provider or JDK | FIPS profile, JDK distribution trust, SBOM, PKCS#11 HSM docs |
| Weak / subverted randomness | SecureRandom throughout | |
| Operations / config | Test / weak parameters in production | Parameter validators reject out-of-range; calibration never auto-runs |
| No emergency response | Emergency playbooks + EmergencyPolicyOverride + MassCredentialStatusChange |
CWE coverage matrix
The credential layer addresses 40 CWE weakness classes. The counts below are the number of features that directly cover each weakness, plus supporting features (tests, governance, operating rules). This is the condensed view; the full per-feature breakdown (166 features across 19 epics) lives in the project repository.
| CWE | Title | Direct | Supporting |
|---|---|---|---|
| CWE-16 | Configuration | 2 | 0 |
| CWE-20 | Improper Input Validation | 8 | 3 |
| CWE-200 | Exposure of Sensitive Information to an Unauthorized Actor | 15 | 0 |
| CWE-203 | Observable Discrepancy | 11 | 1 |
| CWE-208 | Observable Timing Discrepancy | 3 | 1 |
| CWE-209 | Generation of Error Message Containing Sensitive Information | 7 | 0 |
| CWE-223 | Omission of Security-relevant Information | 3 | 3 |
| CWE-256 | Plaintext Storage of a Password | 1 | 0 |
| CWE-257 | Storing Passwords in a Recoverable Format | 3 | 0 |
| CWE-284 | Improper Access Control | 10 | 1 |
| CWE-287 | Improper Authentication | 25 | 4 |
| CWE-306 | Missing Authentication for Critical Function | 5 | 0 |
| CWE-307 | Improper Restriction of Excessive Authentication Attempts | 15 | 3 |
| CWE-312 | Cleartext Storage of Sensitive Information | 12 | 0 |
| CWE-321 | Use of Hard-coded Cryptographic Key | 10 | 1 |
| CWE-325 | Missing Cryptographic Step | 11 | 2 |
| CWE-326 | Inadequate Encryption Strength | 8 | 0 |
| CWE-327 | Use of a Broken or Risky Cryptographic Algorithm | 35 | 8 |
| CWE-330 | Use of Insufficiently Random Values | 5 | 2 |
| CWE-338 | Use of Cryptographically Weak Pseudo-Random Number Generator | 4 | 2 |
| CWE-362 | Race Condition | 9 | 1 |
| CWE-367 | Time-of-check Time-of-use Race Condition | 9 | 1 |
| CWE-400 | Uncontrolled Resource Consumption | 14 | 3 |
| CWE-521 | Weak Password Requirements | 14 | 2 |
| CWE-522 | Insufficiently Protected Credentials | 50 | 7 |
| CWE-532 | Insertion of Sensitive Information into Log File | 8 | 0 |
| CWE-613 | Insufficient Session Expiration | 2 | 0 |
| CWE-620 | Unverified Password Change | 3 | 0 |
| CWE-639 | Authorization Bypass Through User-Controlled Key | 2 | 0 |
| CWE-640 | Weak Password Recovery Mechanism for Forgotten Password | 13 | 1 |
| CWE-759 | Use of a One-Way Hash without a Salt | 1 | 2 |
| CWE-760 | Use of a One-Way Hash with a Predictable Salt | 1 | 1 |
| CWE-770 | Allocation of Resources Without Limits or Throttling | 9 | 1 |
| CWE-778 | Insufficient Logging | 13 | 6 |
| CWE-798 | Use of Hard-coded Credentials | 3 | 0 |
| CWE-829 | Inclusion of Functionality from Untrusted Control Sphere | 6 | 1 |
| CWE-863 | Incorrect Authorization | 4 | 0 |
| CWE-916 | Use of Password Hash With Insufficient Computational Effort | 21 | 7 |
| CWE-1104 | Use of Unmaintained Third Party Components | 4 | 1 |
| CWE-1240 | Use of a Cryptographic Primitive with a Risky Implementation | 3 | 1 |
The three highest-coverage weakness classes — CWE-522 (Insufficiently Protected Credentials, 50 features), CWE-327 (Broken / Risky Crypto, 35) and CWE-287 (Improper Authentication, 25) — are exactly the core of credential security, which is where this layer concentrates.
How a control maps end-to-end
A worked example for CWE-916 (Use of Password Hash With Insufficient Computational Effort):
- Default — PBKDF2 at the OWASP-2023 floor (600 000 iterations) in
JDK-only
security-core. - Modern profile — Argon2id (t=3, m=64 MiB, p=1) via the opt-in
security-crypto-bcmodule. - No silent downgrade — requesting the modern profile without the provider on the classpath fails fast (CWE-693).
- Crypto-agility —
RehashDecisionupgrades hashes on next login when parameters fall behind policy. - Resource control —
KdfExecutionLimiterbounds concurrent KDF work so the strong parameters can’t be turned into a DoS (CWE-400).
That is five distinct features cooperating on one weakness class — the pattern the matrix above counts.
Caveats
- Not every vector is closed by the credential layer alone. Session
management, brute-force lockout and throttling lean on
SessionPolicy,LoginAttemptPolicyandLogoutService— the credential features supply the signals and interfaces, not the full implementation. - Several controls are SPIs: they take effect only once the
application provides an implementation — e.g. the atomic
CredentialStore(depends on your persistence layer) and abuse detection (needs a shared counter/event store in distributed deployments). - The full per-feature justification (166 rows, German) is maintained in
the repository under
docs/v00.71.00/.