From 113a615e6762a08e0bf4fa46a24449324da1ba59 Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Fri, 15 May 2026 03:25:38 +0200 Subject: [PATCH 1/2] security-model: draft additions for adversary model, known non-findings, triage dispositions Adds four new sections to the existing security-model document to complete the minimum-bar coverage expected by an automated agentic security scan the project will run through: == Adversary Model Names the in-scope adversary classes (external untrusted network user; authenticated low-privilege user) and the out-of-scope ones (application code, administrators with configuration access, local shell access / co-tenants, compromised realms). Cross-references the existing Trust Boundaries section. == Known Non-Findings Recurring report categories that the PMC has already decided are not vulnerabilities under the model: differential-error username enumeration (default behavior), username / session-ID appearance in logs, Shiro version disclosure, deprecated hash algorithms exposed in the hashing API, RememberMe with weaker guarantees, pluggable-crypto allowing weak operator configurations, and the CSRF / MFA / account-lockout omissions. Each linked back to the section that licenses the classification. == Triage Dispositions Closed set of outcomes for an inbound vulnerability report: VALID, VALID-HARDENING, OUT-OF-MODEL:* (trusted input / adversary not in scope), BY-DESIGN: property-disclaimed, KNOWN-NON-FINDING, MODEL-GAP. Each cell of the table cross-references the section that licenses the call, so triagers can answer reports with "see
" rather than ad-hoc prose. == Open Questions for the PMC Temporary section collecting the *(inferred)* tags elsewhere in the diff. The intent is that the PMC reviews, confirms or corrects each item, and then this section is removed and the corresponding *(inferred)* tags are promoted to *(maintainer)*. Every claim in the additions carries one of *(documented)* / *(maintainer)* / *(inferred)* provenance tags per the rubric in https://gist.github.com/potiuk/da14a826283038ddfe38cc9fe6310573. Items lifted from existing sections of this document are tagged *(documented)*; the ones the ASF Security team inferred from public artefacts are tagged *(inferred)* and routed to the Open Questions block for PMC review. The discoverability piece (AGENTS.md + SECURITY.md pointing at this model) is addressed by a separate PR against apache/shiro. Generated-by: Claude Code (Claude Opus 4.7) --- src/site/content/security-model.adoc | 121 +++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/src/site/content/security-model.adoc b/src/site/content/security-model.adoc index 0268029c7..26f0b53a1 100644 --- a/src/site/content/security-model.adoc +++ b/src/site/content/security-model.adoc @@ -39,6 +39,37 @@ However, Shiro relies on the application to: * Protect sensitive configuration values from exposure. * Implement proper transport-layer security (TLS/SSL) for credential transmission. +== Adversary Model + +Shiro's security model assumes the following adversary classes: + +=== External Untrusted Adversary (in scope) + +*(inferred)* The primary adversary Shiro defends against is an unauthenticated or authenticated-but-low-privilege network user attempting to access an application that integrates Shiro. This adversary can: + +* Submit arbitrary authentication credentials, session identifiers, and request data. +* Observe authentication error responses (including timing). +* Attempt session fixation, privilege escalation, and authorization bypass. + +This adversary cannot: + +* Run code in the application's JVM process. +* Read or modify application configuration files. +* Tamper with `Realm` implementations or their backing data sources. + +=== Authenticated User with Limited Privileges (in scope) + +*(inferred)* Shiro's authorization model defends against privilege escalation by an authenticated user. A user authenticated under one principal must not gain access to resources they are not authorized for through permission-string manipulation or session-state tampering. + +=== Adversaries Out of Scope + +The following adversary classes are explicitly *not* part of Shiro's threat model — defending against them is the application's or operator's responsibility: + +* **Application Code**: *(documented)* As stated in <>, Shiro trusts the code that invokes its APIs. An attacker who can execute arbitrary code in the application's JVM has already won at Shiro's layer. +* **Administrators with Configuration Access**: *(documented)* An attacker controlling INI files, Spring beans, or other configuration sources can disable security controls. Shiro relies on operators to secure these. +* **Local Shell Access / Co-Tenants**: *(inferred)* An attacker with shell access to the host can read process memory, log files, and the keystore. Shiro does not defend against this; isolate Shiro-secured applications appropriately. +* **Compromised Realms**: *(documented)* An attacker controlling the LDAP server, database, or other `Realm` backing data can grant arbitrary access. Realm data sources are part of the trust boundary. + == Authentication Guarantees === What Shiro Provides @@ -163,6 +194,75 @@ Shiro should be one layer in a defense-in-depth security strategy: * Employ rate limiting and brute-force protection at the infrastructure level. * Conduct regular security assessments and penetration testing. +== Known Non-Findings + +The following recurring report categories are explicitly *not* security vulnerabilities under Shiro's model. Reporters should consult this list before filing — a report matching one of these will be closed with a reference back to this section. + +=== Username Enumeration via Differential Error Responses + +*(documented)* By default, Shiro returns different exceptions for "unknown account" vs "incorrect password" (see <>). This is the framework's default behavior; applications that need to prevent enumeration must configure their `Realm` to return consistent exceptions, as documented above. + +=== Username and Session ID Appearing in Logs + +*(documented)* As stated in <>, principals (usernames) may appear in Shiro's SLF4J logs, and session identifiers may appear at DEBUG level. This is by design — log content is the operator's responsibility to secure. Plaintext passwords are not logged; that's the property Shiro maintains. + +=== Shiro Version Disclosure + +*(documented)* Per <>, Shiro does not actively prevent version disclosure through error messages or response headers. Operators who treat version disclosure as a finding must configure their web server, proxy, or custom error pages accordingly. + +=== Deprecated Hash Algorithms Exposed in the Hashing API + +*(inferred)* Shiro's `Hash` and `HashService` APIs expose MD5, SHA-1, and other algorithms that are no longer considered safe for new password hashing. These remain available for legacy interoperability and for non-security uses (e.g., content checksums). Reports that "Shiro supports MD5" are not findings; the framework's default for password hashing is the secure `PasswordService`. Operators must select appropriate algorithms. + +=== RememberMe with Weaker Authentication Guarantees + +*(documented)* Per <> under <>, the RememberMe mechanism explicitly provides weaker guarantees than full authentication. Reports that RememberMe-identified subjects bypass full authentication are not findings; the security tradeoff is documented and intentional. + +=== Pluggable Cryptography Allowing Weak Configurations + +*(inferred)* Shiro's `CipherService`, `Hash`, and related APIs are pluggable and accept any algorithm registered with the JCA. Configuring Shiro to use a weak cipher is an operator misconfiguration, not a framework vulnerability. Shiro's role is to provide secure defaults and clear documentation, which it does. + +=== CSRF, MFA, Account Lockout + +*(documented)* Per <>, <> under <>, and elsewhere, CSRF protection, MFA, and account lockout are explicitly *not* built into Shiro. Operators must implement these at the application or infrastructure level. Reports that "Shiro is missing CSRF protection" are not framework vulnerabilities. + +== Triage Dispositions + +The Shiro PMC classifies inbound vulnerability reports into one of the following dispositions. Each links to the section of this document that licenses the call. + +[cols="1,3,2",options="header"] +|=== +| Disposition | Meaning | Licensed by + +| VALID +| The report describes a real violation of a property Shiro provides (authentication / authorization / session-handling / crypto / web-security guarantees), accessible to an in-scope adversary through an in-scope code path. Fixed via coordinated disclosure and CVE. +| <>, <>, <>, <>, <>, <> + +| VALID-HARDENING +| No property in this model is violated, but the PMC elects to add defensive hardening (e.g., narrowing an API that's easy to misuse). Triaged privately; fixed at PMC discretion; typically no CVE. +| PMC discretion + +| OUT-OF-MODEL: trusted-input +| The report requires the attacker to control a value or input Shiro treats as trusted (application code, configuration files, realm data). +| <> + +| OUT-OF-MODEL: adversary-not-in-scope +| The report requires attacker capabilities Shiro does not defend against (local shell access, JVM control, administrator privileges). +| <> + +| BY-DESIGN: property-disclaimed +| The report concerns a property Shiro explicitly does not provide (CSRF, MFA, account lockout, key management, version concealment, etc.). +| <>, <>, <>, <> + +| KNOWN-NON-FINDING +| The report matches one of the documented categories in <>. +| <> + +| MODEL-GAP +| The report cannot be cleanly routed to any of the above. This indicates a gap in the security model itself; the PMC revises the model rather than ad-hoc-deciding the report. +| triggers a model revision +|=== + == Reporting Security Vulnerabilities If you discover a security vulnerability in Apache Shiro, please report it privately to the security team: @@ -172,6 +272,27 @@ If you discover a security vulnerability in Apache Shiro, please report it priva Do not disclose security vulnerabilities publicly until a fix is available and an advisory has been published. +== Open Questions for the PMC + +[NOTE] +==== +This section is temporary — it collects the `*(inferred)*` tags elsewhere in this document for PMC review. Once the PMC has confirmed, corrected, or struck each item, this section can be removed and the corresponding tags promoted to `*(maintainer)*`. +==== + +. *(inferred)* in <>: is "attempt session fixation, privilege escalation, and authorization bypass" the right framing for the adversary's intent? + +. *(inferred)* in <>: is privilege-escalation-via-permission-string-manipulation in scope as a Shiro-layer concern, or is permission-string construction the application's responsibility? + +. *(inferred)* in <> / Local Shell Access: the framing assumes JVM process is the trust boundary. Confirm or refine. + +. *(inferred)* in <>: "Deprecated Hash Algorithms Exposed in the Hashing API" — is this the right framing, or does the PMC consider it the operator's choice to NOT call the deprecated APIs? + +. *(inferred)* in <>: "Pluggable Cryptography Allowing Weak Configurations" — same question. Is misconfigured cipher selection a Shiro concern or fully the operator's? + +. *(inferred)* in <>: are the seven disposition labels above the right set? The ASF Security team's threat-model-producer rubric uses these labels; the PMC may prefer different terminology. + +Reply on the original email thread you started with the Security team, or against this PR with confirmations / corrections. + == Additional Resources * link:architecture.html[Apache Shiro Architecture] - Detailed component overview From 829e404a104d8b2a14331e7034e56822087f0859 Mon Sep 17 00:00:00 2001 From: lprimak Date: Sun, 24 May 2026 21:17:26 -0500 Subject: [PATCH 2/2] enh: corrections to security model --- src/site/content/security-model.adoc | 103 +++++++++++---------------- 1 file changed, 41 insertions(+), 62 deletions(-) diff --git a/src/site/content/security-model.adoc b/src/site/content/security-model.adoc index 26f0b53a1..4bdb4cb81 100644 --- a/src/site/content/security-model.adoc +++ b/src/site/content/security-model.adoc @@ -39,37 +39,6 @@ However, Shiro relies on the application to: * Protect sensitive configuration values from exposure. * Implement proper transport-layer security (TLS/SSL) for credential transmission. -== Adversary Model - -Shiro's security model assumes the following adversary classes: - -=== External Untrusted Adversary (in scope) - -*(inferred)* The primary adversary Shiro defends against is an unauthenticated or authenticated-but-low-privilege network user attempting to access an application that integrates Shiro. This adversary can: - -* Submit arbitrary authentication credentials, session identifiers, and request data. -* Observe authentication error responses (including timing). -* Attempt session fixation, privilege escalation, and authorization bypass. - -This adversary cannot: - -* Run code in the application's JVM process. -* Read or modify application configuration files. -* Tamper with `Realm` implementations or their backing data sources. - -=== Authenticated User with Limited Privileges (in scope) - -*(inferred)* Shiro's authorization model defends against privilege escalation by an authenticated user. A user authenticated under one principal must not gain access to resources they are not authorized for through permission-string manipulation or session-state tampering. - -=== Adversaries Out of Scope - -The following adversary classes are explicitly *not* part of Shiro's threat model — defending against them is the application's or operator's responsibility: - -* **Application Code**: *(documented)* As stated in <>, Shiro trusts the code that invokes its APIs. An attacker who can execute arbitrary code in the application's JVM has already won at Shiro's layer. -* **Administrators with Configuration Access**: *(documented)* An attacker controlling INI files, Spring beans, or other configuration sources can disable security controls. Shiro relies on operators to secure these. -* **Local Shell Access / Co-Tenants**: *(inferred)* An attacker with shell access to the host can read process memory, log files, and the keystore. Shiro does not defend against this; isolate Shiro-secured applications appropriately. -* **Compromised Realms**: *(documented)* An attacker controlling the LDAP server, database, or other `Realm` backing data can grant arbitrary access. Realm data sources are part of the trust boundary. - == Authentication Guarantees === What Shiro Provides @@ -130,12 +99,12 @@ By default, Shiro may reveal whether a username exists through different error r * **Hashing**: Simplified APIs for cryptographic hashing (SHA-256, SHA-512, MD5, etc.) with salt and iteration support. * **Encryption/Decryption**: `CipherService` implementations for symmetric encryption (AES, Blowfish, etc.). -* **Password Hashing**: `PasswordService` for secure credential hashing with configurable algorithms. +* **Password Hashing**: `PasswordService` for secure credential hashing with configurable algorithms (Argon2, BCrypt). === Important Notes * Shiro's cryptographic utilities are wrappers around standard Java cryptography (JCA/JCE) and `BouncyCastle` libraries. -* **Algorithm Selection**: Operators must choose appropriate algorithms. Avoid deprecated algorithms (MD5, SHA-1 for security purposes). +* **Algorithm Selection**: Operators must choose appropriate algorithms. Avoid deprecated algorithms (MD5, SHA-1 for security purposes). Avoid weak algorithms for passwords (use Argon2 or BCrypt with appropriate work factors). * **Key Management**: Shiro does not provide key management infrastructure. Secure key storage and rotation is the operator's responsibility. == Web Security @@ -182,7 +151,7 @@ Operators should: . Use the latest stable Shiro release. . Configure TLS for all credential transmission. . Use strong password hashing (bcrypt or Argon2 with appropriate work factors). -. Implement session fixation prevention. +. Implement session fixation prevention, if not using built-in session management. . Review and restrict default configurations. === Defense in Depth @@ -194,37 +163,68 @@ Shiro should be one layer in a defense-in-depth security strategy: * Employ rate limiting and brute-force protection at the infrastructure level. * Conduct regular security assessments and penetration testing. +== Adversary Model + +Shiro's security model assumes the following adversary classes: + +=== External Untrusted Adversary (in scope) + +The primary adversary Shiro defends against is an unauthenticated or authenticated-but-low-privilege network user attempting to access an application that integrates Shiro. This adversary can: + +* Submit arbitrary authentication credentials, session identifiers, and request data. +* Observe authentication error responses (including timing). +* Attempt session fixation, privilege escalation, and authorization bypass. + +This adversary cannot: + +* Run code in the application's JVM process. +* Read or modify application configuration files. +* Tamper with `Realm` implementations or their backing data sources. + +=== Authenticated User with Limited Privileges (in scope) + +Shiro's authorization model defends against privilege escalation by an authenticated user. A user authenticated under one principal must not gain access to resources they are not authorized for. Applications must not allow manipulation of permission strings or other inputs that could lead to unauthorized access. Shiro's role and permission checks are only as secure as the application's permission model and input handling. + +=== Adversaries Out of Scope + +The following adversary classes are explicitly *not* part of Shiro's threat model — defending against them is the application's or operator's responsibility: + +* **Application Code**: As stated in <>, Shiro trusts the code that invokes its APIs. An attacker who can execute arbitrary code in the application's JVM has already won at Shiro's layer. +* **Administrators with Configuration Access**: An attacker controlling INI files, Spring beans, or other configuration sources can disable security controls. Shiro relies on operators to secure these. +* **Local Shell Access / Co-Tenants**: An attacker with shell access to the host can read process memory, log files, and the keystore. Shiro does not defend against this; isolate Shiro-secured applications appropriately. +* **Compromised Realms**: An attacker controlling the LDAP server, database, or other `Realm` backing data can grant arbitrary access. Realm data sources are part of the trust boundary. + == Known Non-Findings The following recurring report categories are explicitly *not* security vulnerabilities under Shiro's model. Reporters should consult this list before filing — a report matching one of these will be closed with a reference back to this section. === Username Enumeration via Differential Error Responses -*(documented)* By default, Shiro returns different exceptions for "unknown account" vs "incorrect password" (see <>). This is the framework's default behavior; applications that need to prevent enumeration must configure their `Realm` to return consistent exceptions, as documented above. +By default, Shiro returns different exceptions for "unknown account" vs "incorrect password" (see <>). This is the framework's default behavior; applications that need to prevent enumeration must configure their `Realm` to return consistent exceptions, as documented above. === Username and Session ID Appearing in Logs -*(documented)* As stated in <>, principals (usernames) may appear in Shiro's SLF4J logs, and session identifiers may appear at DEBUG level. This is by design — log content is the operator's responsibility to secure. Plaintext passwords are not logged; that's the property Shiro maintains. +As stated in <>, principals (usernames) may appear in Shiro's SLF4J logs, and session identifiers may appear at DEBUG level. This is by design — log content is the operator's responsibility to secure. Plaintext passwords are not logged; that's the property Shiro maintains. === Shiro Version Disclosure -*(documented)* Per <>, Shiro does not actively prevent version disclosure through error messages or response headers. Operators who treat version disclosure as a finding must configure their web server, proxy, or custom error pages accordingly. +Per <>, Shiro does not actively prevent version disclosure through error messages or response headers. Operators who treat version disclosure as a finding must configure their web server, proxy, or custom error pages accordingly. === Deprecated Hash Algorithms Exposed in the Hashing API -*(inferred)* Shiro's `Hash` and `HashService` APIs expose MD5, SHA-1, and other algorithms that are no longer considered safe for new password hashing. These remain available for legacy interoperability and for non-security uses (e.g., content checksums). Reports that "Shiro supports MD5" are not findings; the framework's default for password hashing is the secure `PasswordService`. Operators must select appropriate algorithms. +Shiro's `Hash` and `HashService` APIs expose MD5, SHA-1, and other algorithms that are no longer considered safe for new password hashing. These remain available for legacy interoperability and for non-security uses (e.g., content checksums). Reports that "Shiro supports MD5" are not findings; the framework's default for password hashing is the secure `PasswordService`. Operators must select appropriate algorithms. === RememberMe with Weaker Authentication Guarantees -*(documented)* Per <> under <>, the RememberMe mechanism explicitly provides weaker guarantees than full authentication. Reports that RememberMe-identified subjects bypass full authentication are not findings; the security tradeoff is documented and intentional. +Per <> under <>, the RememberMe mechanism explicitly provides weaker guarantees than full authentication. Reports that RememberMe-identified subjects bypass full authentication are not findings; the security tradeoff is documented and intentional. === Pluggable Cryptography Allowing Weak Configurations -*(inferred)* Shiro's `CipherService`, `Hash`, and related APIs are pluggable and accept any algorithm registered with the JCA. Configuring Shiro to use a weak cipher is an operator misconfiguration, not a framework vulnerability. Shiro's role is to provide secure defaults and clear documentation, which it does. +Shiro's `CipherService`, `Hash`, and related APIs are pluggable and accept any algorithm registered with the JCA. Configuring Shiro to use a weak cipher is an operator misconfiguration, not a framework vulnerability. Shiro's role is to provide secure defaults and clear documentation, which it does. === CSRF, MFA, Account Lockout -*(documented)* Per <>, <> under <>, and elsewhere, CSRF protection, MFA, and account lockout are explicitly *not* built into Shiro. Operators must implement these at the application or infrastructure level. Reports that "Shiro is missing CSRF protection" are not framework vulnerabilities. +Per <>, <> under <>, and elsewhere, CSRF protection, MFA, and account lockout are explicitly *not* built into Shiro. Operators must implement these at the application or infrastructure level. Reports that "Shiro is missing CSRF protection" are not framework vulnerabilities. == Triage Dispositions @@ -272,27 +272,6 @@ If you discover a security vulnerability in Apache Shiro, please report it priva Do not disclose security vulnerabilities publicly until a fix is available and an advisory has been published. -== Open Questions for the PMC - -[NOTE] -==== -This section is temporary — it collects the `*(inferred)*` tags elsewhere in this document for PMC review. Once the PMC has confirmed, corrected, or struck each item, this section can be removed and the corresponding tags promoted to `*(maintainer)*`. -==== - -. *(inferred)* in <>: is "attempt session fixation, privilege escalation, and authorization bypass" the right framing for the adversary's intent? - -. *(inferred)* in <>: is privilege-escalation-via-permission-string-manipulation in scope as a Shiro-layer concern, or is permission-string construction the application's responsibility? - -. *(inferred)* in <> / Local Shell Access: the framing assumes JVM process is the trust boundary. Confirm or refine. - -. *(inferred)* in <>: "Deprecated Hash Algorithms Exposed in the Hashing API" — is this the right framing, or does the PMC consider it the operator's choice to NOT call the deprecated APIs? - -. *(inferred)* in <>: "Pluggable Cryptography Allowing Weak Configurations" — same question. Is misconfigured cipher selection a Shiro concern or fully the operator's? - -. *(inferred)* in <>: are the seven disposition labels above the right set? The ASF Security team's threat-model-producer rubric uses these labels; the PMC may prefer different terminology. - -Reply on the original email thread you started with the Security team, or against this PR with confirmations / corrections. - == Additional Resources * link:architecture.html[Apache Shiro Architecture] - Detailed component overview