> For the complete documentation index, see [llms.txt](https://p4d0rn.gitbook.io/java/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://p4d0rn.gitbook.io/java/shiro/cve-2016-6802.md).

# Context Path ByPass

CVE-2016-6802

影响版本：`shiro < 1.3.2`

`Shiro`使用非根`servlet`上下文路径中存在安全漏洞。远程攻击者通过构造的请求，利用此漏洞可绕过目标`servlet`过滤器并获取访问权限。

上一个请求路径未标准化类似

`getPathWithinApplication`先后获取到上下文路径和请求路径，若请求路径以上下文路径开头，截断后并返回；否则返回整个请求路径

![image-20230405164445051](https://1239337109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2HLPOkuOfb7iyCzDJ8vA%2Fuploads%2Fgit-blob-1c4c4c57161a81ce56b18f385b29e19fc09bd9c8%2Fimage-20230405164445051.png?alt=media)

跟进`getContextPath`

![image-20230405190720737](https://1239337109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2HLPOkuOfb7iyCzDJ8vA%2Fuploads%2Fgit-blob-e58fc0b94d477a684e5098c5678c1bd500c48911%2Fimage-20230405190720737.png?alt=media)

`request.getContextPath()`实际上是tomcat内部去解析的，逻辑在`org.apache.catalina.connector#getContextPath`

获取`Application Context`和请求的URL，对URL进行如下操作

* 去除开头的斜杠，只保留一个

![image-20230405195637104](https://1239337109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2HLPOkuOfb7iyCzDJ8vA%2Fuploads%2Fgit-blob-a37371e6ba603fe7135f8d7db6090b3c3bf6828b%2Fimage-20230405195637104.png?alt=media)

* 获取第二个斜杠前面的内容作为`candidate`

![image-20230405195921658](https://1239337109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2HLPOkuOfb7iyCzDJ8vA%2Fuploads%2Fgit-blob-a2560e5d9313835ec7d847c6c063fa0aad8d0461%2Fimage-20230405195921658.png?alt=media)

* 去除请求参数、URL解码、标准化（处理`/./、/../、//等`），判断`candidate`和`Application Context`是否相等，若不等则继续获取下一个斜杠之前的内容

![image-20230405200231360](https://1239337109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2HLPOkuOfb7iyCzDJ8vA%2Fuploads%2Fgit-blob-aeb00c4e1e877a4903e4449c64b738c9892f292d%2Fimage-20230405200231360.png?alt=media)

假设`Application Context`为`/taco`，若我们请求的路径为`////hello/try/../../taco/admin/put`

* 保留首个斜杠 => `/hello/try/../../taco/admin/put`
* `/hello`不匹配`/taco`，获取下一个斜杠前面的内容
* `/hello/try`不匹配`/taco`
* `/hello/try/..`标准化后`/hello`不匹配`/taco`
* `/hello/try/../..`标准化后`/`不匹配`/taco`
* `/hello/try/../../taco`标准化后`/taco`，成功匹配，返回`/hello/try/../../taco`

`Shiro 1.0.0`之后的版本对`Request uri`进行了标准化，而`getContextPath()`返回的是没有标准化的，可以利用此绕过

![image-20230405203148965](https://1239337109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2HLPOkuOfb7iyCzDJ8vA%2Fuploads%2Fgit-blob-01ddecbd817e2d8fcf158779c50d3db130e5c8ff%2Fimage-20230405203148965.png?alt=media)

![image-20230405203244671](https://1239337109-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2HLPOkuOfb7iyCzDJ8vA%2Fuploads%2Fgit-blob-772be7a3daf6d601e84f929e517cb7dee52c8ebd%2Fimage-20230405203244671.png?alt=media)

显然后面版本的修复就是对`getContextPath()`进行`normalize`标准化。

Shiro这波感觉有点自己造轮子了。

`getContextPath()`可以直接调用`request.getServletContext().getContextPath()`
