Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
shiro-cve-2020-17523 — shiro-cve-2020-17523 漏洞的两种绕过姿势分析 以及配套的漏洞环境 | Kitploit
Tools/GitHubGitHub/jweny/shiro-cve-2020-17523
Authentication & AuthorizationVulnerability AnalysisWeb Application ExploitationPenetration TestingLearning & EducationLabs & Practice
GitHubjweny/shiro-cve-2020-17523

shiro-cve-2020-17523

shiro-cve-2020-17523 漏洞的两种绕过姿势分析 以及配套的漏洞环境

View Repository
118115 years agoReviewed by Kitploit

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

Apache Shiro Two Postures Authentication Bypass Analysis (CVE-2020-17523)

0x01 Vulnerability Description

Apache Shiro is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro's easy-to-understand API, you can quickly and easily secure any application, from the smallest mobile application to the largest web and enterprise applications.

When used with Spring, under certain authorization matching rules, an attacker can bypass authentication by crafting special HTTP request packets.

Affected versions: Apache Shiro < 1.7.1

0x02 Vulnerability Environment Setup

shiro 1.7.0

https://github.com/jweny/shiro-cve-2020-17523 Both postures' vulnerability environments have been updated.

0x03 POC Testing

Posture One:

http://127.0.0.1:8080/admin/%20 or http://127.0.0.1:8080/admin/%20/

Using blank characters such as spaces can bypass Shiro authentication.

image-20210205120522547

Posture Two:

After discussing with p0desta, another exploitation method in a special scenario was discovered.

http://127.0.0.1:8080/admin/%2e or http://127.0.0.1:8080/admin/%2e/

However, . (and /) represent path separators in Spring's path matching rules and are not matched as ordinary characters. Therefore, under default conditions, accessing /admin/. will return 404.

But when full-path matching is enabled with setAlwaysUseFullPath(true), it can be matched correctly.

image-20210205102100797

0x04 Vulnerability Analysis

Shiro's URL acquisition and matching are performed in org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain

Let's first take a brief look at this getChain method:

carbon (2)

image-20210205103341569

This method first checks if the requestURI ends with /. If so, it removes the last /.

Then, in the loop matching paths, it first checks if the pathPattern ends with / and removes it if so. Then it calls the pathMatches() method for path matching.

Therefore, in both exploitation methods, whether it ends with / does not matter, because it will be removed by the getChain method at the start.

4.1 Space Bypass Analysis

Let's look at the pathMatches() method:

Bring up Evaluate and calculate pathMatches("/admin/*","/admin/1") and pathMatches("/admin/*","/admin/ "). The former matches correctly, the latter fails.

image-20210203134044268

image-20210203134119174

Start debugging. After a long F7, we reach doMatch("/admin/*","/admin/ "). It can be seen that the pathDirs returned by tokenizeToStringArray no longer have a second-level directory. Therefore, /admin/* and /admin do not match.

image-20210203150854085

Trace the tokenizeToStringArray method and find that when calling tokenizeToStringArray, the trimTokens parameter is true.

image-20210203150959413

In the tokenizeToStringArray method, when the trimTokens parameter is true, the strings undergo trim() processing, which removes whitespace. Thus, spaces are cleared. When returning to getChain, the last / is removed. Therefore, the pathDirs returned by tokenizeToStringArray have no second-level directory.

image-20210203151053344

Summary: In the vulnerable Shiro version, because the trimTokens parameter defaults to true when calling tokenizeToStringArray, spaces are processed by trim(), causing them to be removed. When returning to getChain, the last / is deleted, so /admin does not match /admin/*, leading to authentication bypass. Meanwhile, Spring receives the request path as /admin/%20 and returns the response normally, thus causing an authorization bypass.

4.2 /. Bypass Analysis

Seeing /. and /./ in the second posture, does it remind you of a familiar method? That's right, it's normalize().

carbon (3)

A brief translation is:

ConditionExample
Backslash to forward slash\ -> /
Double forward slash to single// -> /
Ends with /. or /.., append /

Thus, /admin/. becomes /admin/./ and then /admin/.

image-20210205113301788

After being processed by org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain, because it ends with /, the last / is removed, resulting in /admin. /admin does not match /admin/*, thus bypassing Shiro authentication.

image-20210205113518970

At this time, the request received by Spring is /admin/.. If full-path matching is not enabled, . and / act as path separators in Spring and are not involved in path matching. Therefore, it cannot find a mapping and returns 404.

image-20210205114350972

If full-path matching is enabled, the entire URL is matched, so Spring returns 200.

Here is the code to enable full-path matching:

root@kitploit:~
@SpringBootApplication
public class SpringbootShiroApplication extends SpringBootServletInitializer implements BeanPostProcessor {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(SpringbootShiroApplication.class);
    }

    public static void main(String[] args) {

        SpringApplication.run(SpringbootShiroApplication.class, args);
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        if (bean instanceof RequestMappingHandlerMapping) {
            ((RequestMappingHandlerMapping) bean).setAlwaysUseFullPath(true);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        return bean;
    }
}

0x05 Official Fix

Based on the analysis above, there are two reasons for Shiro authorization bypass:

  1. The tokenizeToStringArray function does not properly handle spaces.
  2. The logic for handling the last / should not be placed before the loop matching paths.

Therefore, the official fix is:

https://github.com/apache/shiro/commit/0842c27fa72d0da5de0c5723a66d402fe20903df

  1. Set the trimTokens parameter of tokenizeToStringArray to false. image-20210203154342100
  2. Adjust the logic for removing the last /. Change it to first match the original path, and only if matching fails, proceed with the logic to remove the last /. image-20210205115522098

0x06 About trim

In principle, trim() removes all whitespace from the beginning and end of a string, with space being just one type. However, during testing, other whitespace characters such as %08, %09, %0a, when processed by Spring+Tomcat, all return 400.

Therefore, for the first posture, other than spaces, no other usable payloads have been found.

0x07 References

https://github.com/apache/shiro/commit/0842c27fa72d0da5de0c5723a66d402fe20903df

https://www.anquanke.com/post/id/216096

https://www.cnblogs.com/syp172654682/p/9257282.html

Download Tool
/. -> /./ /.. -> /../
Normalize /.//./ -> /
Path traversal/aaa/../bbb -> /bbb