Apache Shiro is a popular Java security framework used to handle authentication, authorization, session management, and more. Many Java web apps use it for access control. But if you’re running a version *before* 1.12. (or 2..-alpha-3), your app might be open to a critical bug: attackers could bypass login and get access to protected resources using a simple path traversal trick.

In this long read, I’ll explain how CVE-2023-34478 works, show you code examples, share references, and help you fix the issue.

What is CVE-2023-34478?

This vulnerability is path traversal weakness that leads to authentication bypass in Apache Shiro. It happens when Shiro is used with web frameworks or APIs that pass *non-normalized* requests (for example, URLs that still include /../ or similar segments) to Shiro’s filter.

Impact:  
A remote attacker can access protected endpoints—no password, no login required.

Affected versions:

Why Does This Happen?

Many Java web frameworks (like Spring Boot, JAX-RS, Jersey, etc.) perform their own URL routing and sometimes pass the original URL (which may have troublemaking ../ or extra slashes) to backend filters, including Shiro.

Shiro’s filter does *not* properly normalize (clean up) these paths, so /protected/../public/ may sneak past the authentication check, even if /protected is locked down.

Exploiting CVE-2023-34478

Suppose you have a web app protected by Shiro. Only logged-in users should see /admin/dashboard.

Because of this bug, an attacker can access the same endpoint with a path like this

/admin/foo/../dashboard

If the router resolves it to /admin/dashboard but Shiro still sees /admin/foo/../dashboard (which looks different), Shiro may skip the access restriction, because it thinks the real /admin/dashboard is protected but not the indirect path.

Suppose you have this shiro.ini config

[urls]
/admin/** = authc
/public/** = anon

And a Java controller like

@RestController
public class AdminController {
    @GetMapping("/admin/dashboard")
    public String getDashboard() {
        return "Secret dashboard";
    }
}

If requests are routed like this

GET /admin/dashboard        -> Protected (requires login)
GET /admin/foo/../dashboard -> *Should* be protected, but due to path traversal, may bypass

Sample Exploit Request

curl http://victim-app.com/admin/../../admin/dashboard


or

curl http://victim-app.com/admin/%2e%2e/dashboard  # URL-encoded ../

If your app or proxy sends the unmodified path to Shiro, it might return the protected resource without asking to log in.

CVE Entry:

NVD - CVE-2023-34478

Apache Shiro Advisory:

Shiro Security Issue (SHIRO-934)

GitHub Patch:

Shiro commit addressing normalization

How To Fix (Mitigation)

The only safe option:  
Update Shiro to at least 1.12., or 2..-alpha-3.

<!-- Maven dependency example -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-web-starter</artifactId>
    <version>1.12.</version>
</dependency>

Or, if you don’t use Maven, just grab the new jar from Apache Shiro downloads.

Other (not recommended) ideas:
- Try to block requests with suspicious paths (.., //, %2e%2e) at your load balancer or web server.

Normalize paths yourself in front of Shiro.

But both of these can be error-prone and complex. Upgrading is the best answer.

CVE-2023-34478 lets attackers bypass login in Apache Shiro protected Java apps via path tricks.

- It affects apps using Shiro before 1.12. (or 2..-alpha-3) with web frameworks that don’t normalize paths before sending them to Shiro.
- Upgrade NOW to be safe—path traversal bugs like this are widely exploited after they’re public.

Stay secure. Keep your libraries up to date!

If you have questions on patching Shiro or want to know if your stack is vulnerable, feel free to ask in the comments.

Further Reading

- Official Apache Shiro Site
- NIST NVD Detail on CVE-2023-34478
- Common Path Traversal Attacks (OWASP)

Timeline

Published on: 07/24/2023 19:15:00 UTC
Last modified on: 08/01/2023 19:15:00 UTC