java Tomcat 提供静态内容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3822524/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 03:32:26  来源:igfitidea点击:

Tomcat serving static content

javaspringtomcatservlets

提问by Steve

I have a Spring app and I'm wondering the best way to serve static content. I have tried the following:

我有一个 Spring 应用程序,我想知道提供静态内容的最佳方式。我尝试了以下方法:

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/static/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>app</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

This works, but the behaviour of the DefaultServlet means that any request of the form /static/PATHserves the file from webapp/PATH. This exposes a massive vulnerability, allowing sensitive information to be shown with URLs such as: http://localhost/app/static/META-INF/context.xml

这是可行的,但 DefaultServlet 的行为意味着表单的任何请求都/static/PATH可以从webapp/PATH. 这暴露了一个巨大的漏洞,允许使用 URL 显示敏感信息,例如:http://localhost/app/static/META-INF/context.xml

What's the common solution for this? Should I move the sensitive files? Write my own DefaultServlet? Or is there a better way to serve static content?

对此的常见解决方案是什么?我应该移动敏感文件吗?写我自己的 DefaultServlet?或者有没有更好的方法来提供静态内容?

回答by BalusC

Did you test it? The /META-INFand /WEB-INFfolders are supposed to be public inaccessibleas per the Servlet specification. The client should have gotten a 404 for this. It would otherwise have been a bug in DefaultServlet.

你测试了吗?根据Servlet 规范,/META-INF/WEB-INF文件夹应该是公共不可访问的。客户端应该为此得到 404。否则它会是DefaultServlet.

Here's an extract of Servlet 2.5 spec:

这是Servlet 2.5 规范的摘录:

SRV.9.5 Directory Structure

... Also, any requests from the client to access the resources in WEB-INF/directory must be returned with a SC_NOT_FOUND(404)response.

SRV.9.5 目录结构

...此外,来自客户端的任何访问WEB-INF/目录中资源的请求都必须与SC_NOT_FOUND(404)响应一起返回。

and

SRV.9.6 Web Application Archive File

... Also, any requests to access the resources in META-INFdirectory must be returned with a SC_NOT_FOUND(404)response.

SRV.9.6 Web 应用程序存档文件

...此外,任何访问META-INF目录中资源的请求都必须与SC_NOT_FOUND(404)响应一起返回。



Update: OK, I take my words back. I can reproduce this on latest Tomcat 6 and 7. It's definitely a bug in DefaultServlet. It works fine (returns 404) on Glassfish 3.0.1.

更新:好的,我收回我的话。我可以在最新的 Tomcat 6 和 7 上重现这个。这绝对是DefaultServlet. 它在 Glassfish 3.0.1 上运行良好(返回 404)。



Update 2:I've reported this to the Tomcat guys as issue 50026.

更新 2:我已将此作为问题 50026报告给 Tomcat 人员。



Update 3:one of the Tomcat guys responsed as:

更新 3:Tomcat 人员之一回应为:

I'm thinking this is a WONTFIX.

The servlet engine protects the WEB-INFand META-INFpaths in the web application (which is working fine), not files of that name under arbitrary paths.

What's actually happening here is you're configuring a general purpose file serving servlet to mount up your entire web application under a different path - it's equivalent to configuring Apache to do the same thing. Except that DefaultServlet isn't a general purpose file server - it's designed to be mapped to /, and you can't configure it to do anything but serve files out of the web application directory.

I'm guessing you're trying to work around a problem introduced by mapping another servlet to /*, which is basically trying to work around the way a servlet engine works. How to access static resources when mapping a global front controller servlet on /*has an example of a better way to approach things if this is what you're trying to do.

Advice to remount DefaultServletin Tomcat seems to have been around as long as Tomcat has existed, so perhaps we need to lock it down (so people can't accidentally create insecure configurations) or support mounting specific directories (inside or outside the web application), and break if accessing the root resources when mapped to a sub-path in any case.

我想这是一个WONTFIX.

servlet 引擎保护Web 应用程序中的WEB-INFMETA-INF路径(工作正常),而不是任意路径下具有该名称的文件。

这里实际发生的是您正在配置一个通用文件服务 servlet,以在不同的路径下挂载整个 Web 应用程序 - 这相当于配置 Apache 以执行相同的操作。除了 DefaultServlet 不是通用文件服务器 - 它旨在映射到/,并且您不能将其配置为执行任何操作,只能从 Web 应用程序目录中提供文件。

我猜您正在尝试解决通过将另一个 servlet 映射到 引入的问题/*,这基本上是尝试解决 servlet 引擎的工作方式。 How to access static resources when mapping a global front controller servlet on /*有一个更好的方法来处理事情的例子,如果这是你想要做的。

DefaultServlet在 Tomcat 中重新挂载的建议似乎自 Tomcat 存在以来就一直存在,所以也许我们需要将其锁定(这样人们就不会意外创建不安全的配置)或支持挂载特定目录(在 Web 应用程序内部或外部),如果在任何情况下都映射到子路径时访问根资源,则中断。



Update 4:they've ultimately fixed it:

更新 4:他们最终修复了它:

Fixes for DefaultServlet and WebdavServlet are committed for 7.0.x (will be in 7.0.4+) and proposed for 6.0.x. Will need to check 5.5.x and see if a backport is required for that too.

DefaultServlet 和 WebdavServlet 的修复已针对 7.0.x(将在 7.0.4+ 中)提交并针对 6.0.x 提出。需要检查 5.5.x 并查看是否也需要向后移植。

回答by axtavt

There are several better ways to serve static content.

有几种更好的方法来提供静态内容。

The traditional approachwas to use a UrlRewriteFilterto remap URLs as follows:

传统方法是使用 aUrlRewriteFilter重新映射 URL,如下所示:

web.xml:

web.xml

<filter>
    <filter-name>UrlRewriteFilter</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
...
<servlet-mapping>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    <url-pattern>/app/*</url-pattern>
</servlet-mapping>

urlrewrite.xml:

urlrewrite.xml

<urlrewrite default-match-type="wildcard">
    <rule>
        <from>/images/**</from>
        <to>/images/</to>
    </rule>
    <rule>
        <from>/scripts/**</from>
        <to>/scripts/</to>
    </rule>
    <rule>
        <from>/styles/**</from>
        <to>/styles/</to>
    </rule>
    <rule>
        <from>/**</from>
        <to>/app/</to>
    </rule>
</urlrewrite>

This approach can be seen in the most of Spring samples.

这种方法可以在大多数 Spring 示例中看到。



Spring 3.0.1 引入 a newer apporach更新的方法- 它可以通过DispatcherServletDispatcherServlet. 它可以使用<mvc:resource><mvc:resource>Spring 配置文件中的元素进行配置。在 Spring 3.0.4 中它被扩展以支持多个位置和缓存控制选项,请参阅15.12.4 mvc:resources15.12.4 MVC:资源

回答by giri

WEB-INFand META-INFare private folders. The client must be getting 404 error for this. As META_INFcontents are not accessible directly.Otherwise move all sensitive files in WEB_INF.

WEB-INF并且META-INF是私人文件夹。客户端必须为此收到 404 错误。由于META_INF内容无法直接访问WEB_INF。否则将所有敏感文件移动到.