Tomcat部署Spring Boot应用时隐藏受限字符请求返回的服务器详情与堆栈跟踪的配置方法
兄弟,我完全懂你这个困扰——当请求里带了RFC 7230和RFC 3986规范外的非法字符时,Tomcat默认返回的400错误页面把堆栈跟踪、Tomcat版本号这些敏感信息全暴露了,确实存在安全风险。别慌,咱们分两种场景来配置解决:
一、部署到独立外部Tomcat的情况
如果是把Spring Boot打war包部署到独立的Tomcat服务器上,直接修改Tomcat的配置文件就能搞定:
关闭堆栈跟踪显示
打开Tomcat目录下的conf/web.xml,添加下面的上下文参数,把堆栈跟踪的显示关掉:<context-param> <param-name>javax.servlet.error.show-stacktrace</param-name> <param-value>false</param-value> </context-param>同时,你可以自定义400错误页面,替换掉默认的Tomcat错误页,避免暴露服务器相关样式和信息:
<error-page> <error-code>400</error-code> <location>/custom-400.html</location> </error-page>把你自己写的
custom-400.html放到Tomcat的webapps/ROOT目录或者你的应用根目录下就行,页面内容只保留友好提示,比如“请求参数格式有误,请检查后重试”。隐藏Tomcat版本信息
打开conf/server.xml,找到Connector节点,添加server属性自定义服务器标识,或者直接设为空字符串:<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" server="CustomServer" /> <!-- 改成你想显示的标识,或者设为"" -->这样响应头里的
Server字段就不会暴露Tomcat的具体版本了。
二、使用Spring Boot嵌入式Tomcat的情况
如果是直接用Spring Boot自带的嵌入式Tomcat运行应用,咱们可以结合Spring Boot的配置和自定义错误控制器来处理:
配置隐藏敏感信息
在application.properties里添加以下配置,关闭堆栈跟踪显示,自定义服务器标识:# 隐藏堆栈跟踪 server.error.include-stacktrace=never server.error.include-exception=false # 自定义服务器响应头标识 server.tomcat.server-header=CustomServer要是用
application.yml的话,写法是这样:server: error: include-stacktrace: never include-exception: false tomcat: server-header: CustomServer自定义错误控制器拦截400请求
因为非法字符的请求可能在Tomcat层面就被拦截了,咱们可以写一个自定义的错误控制器,确保返回统一的友好错误页:import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.RequestDispatcher; import javax.servlet.http.HttpServletRequest; @Controller public class CustomErrorController implements ErrorController { @RequestMapping("/error") public String handleError(HttpServletRequest request, Model model) { Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); if (statusCode != null && statusCode == HttpStatus.BAD_REQUEST.value()) { model.addAttribute("msg", "请求参数不符合规范,请检查后重试"); return "error/400"; } // 其他错误类型的处理 model.addAttribute("msg", "服务器暂时无法处理请求,请稍后再试"); return "error/500"; } @Override public String getErrorPath() { return "/error"; } }然后在
src/main/resources/templates/error目录下创建400.html和500.html,写好友好的提示内容就行。
需要注意的是:如果是外部Tomcat部署的场景,非法字符的请求是Tomcat先拦截的,所以优先配置Tomcat的web.xml和server.xml,确保这类请求的错误信息不会泄露。
备注:内容来源于stack exchange,提问作者Tushar Arora

