调用这个,能复现tomcat的报错
http://localhost:8182/defaultroot/DownloadServlet?modeType=2&path=html&FileName=…\login.jsp&name=123&fiewviewdownload=2&cd=inline&downloadAll=2
springboot项目如何隐藏?
springboot内嵌了tomat,比如这个版本:tomcat-embed-core-8.5.96
找到这个tomcat-embed-core的源码,
将showReport=true,修改为showReport=false
将showServerInfo=true ,修改为showServerInfo=false
方法一:
在项目中增加ErrorReportValve.java ,实现覆盖内嵌中的类。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package org.apache.catalina.valves;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.servlet.ServletException;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.util.ErrorPageSupport;
import org.apache.catalina.util.IOTools;
import org.apache.catalina.util.ServerInfo;
import org.apache.coyote.ActionCode;
import org.apache.tomcat.util.ExceptionUtils;
import org.apache.tomcat.util.descriptor.web.ErrorPage;
import org.apache.tomcat.util.res.StringManager;
import org.apache.tomcat.util.security.Escape;/*** 解决调试信息泄露漏洞,修改showReport=false,showServerInfo=false*/
public class ErrorReportValve extends ValveBase {private boolean showReport = false;private boolean showServerInfo = false;private final ErrorPageSupport errorPageSupport = new ErrorPageSupport();public ErrorReportValve() {super(true);}public void invoke(Request request, Response response) throws IOException, ServletException {this.getNext().invoke(request, response);if (response.isCommitted()) {if (response.setErrorReported()) {AtomicBoolean ioAllowed = new AtomicBoolean(true);response.getCoyoteResponse().action(ActionCode.IS_IO_ALLOWED, ioAllowed);if (ioAllowed.get()) {try {response.flushBuffer();} catch (Throwable var5) {ExceptionUtils.handleThrowable(var5);}response.getCoyoteResponse().action(ActionCode.CLOSE_NOW, request.getAttribute("javax.servlet.error.exception"));}}} else {Throwable throwable = (Throwable)request.getAttribute("javax.servlet.error.exception");if (!request.isAsync() || request.isAsyncCompleting()) {if (throwable != null && !response.isError()) {response.reset();response.sendError(500);}response.setSuspended(false);try {this.report(request, response, throwable);} catch (Throwable var6) {ExceptionUtils.handleThrowable(var6);}}}}protected ErrorPage findErrorPage(int statusCode, Throwable throwable) {ErrorPage errorPage = null;if (throwable != null) {errorPage = this.errorPageSupport.find(throwable);}if (errorPage == null) {errorPage = this.errorPageSupport.find(statusCode);}if (errorPage == null) {errorPage = this.errorPageSupport.find(0);}return errorPage;}protected void report(Request request, Response response, Throwable throwable) {int statusCode = response.getStatus();if (statusCode >= 400 && response.getContentWritten() <= 0L && response.setErrorReported()) {AtomicBoolean result = new AtomicBoolean(false);response.getCoyoteResponse().action(ActionCode.IS_IO_ALLOWED, result);if (result.get()) {ErrorPage errorPage = this.findErrorPage(statusCode, throwable);if (errorPage == null || !this.sendErrorPage(errorPage.getLocation(), response)) {String message = Escape.htmlElementContent(response.getMessage());String reason;if (message == null) {if (throwable != null) {reason = throwable.getMessage();if (reason != null && reason.length() > 0) {Scanner scanner = new Scanner(reason);try {message = Escape.htmlElementContent(scanner.nextLine());} catch (Throwable var17) {try {scanner.close();} catch (Throwable var15) {var17.addSuppressed(var15);}throw var17;}scanner.close();}}if (message == null) {message = "";}}reason = null;String description = null;StringManager smClient = StringManager.getManager("org.apache.catalina.valves", request.getLocales());response.setLocale(smClient.getLocale());try {reason = smClient.getString("http." + statusCode + ".reason");description = smClient.getString("http." + statusCode + ".desc");} catch (Throwable var16) {ExceptionUtils.handleThrowable(var16);}if (reason == null || description == null) {if (message.isEmpty()) {return;}reason = smClient.getString("errorReportValve.unknownReason");description = smClient.getString("errorReportValve.noDescription");}StringBuilder sb = new StringBuilder();sb.append("<!doctype html><html lang=\"");sb.append(smClient.getLocale().getLanguage()).append("\">");sb.append("<head>");sb.append("<title>");sb.append(smClient.getString("errorReportValve.statusHeader", new Object[]{String.valueOf(statusCode), reason}));sb.append("</title>");sb.append("<style type=\"text/css\">");sb.append("body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}");sb.append("</style>");sb.append("</head><body>");sb.append("<h1>");sb.append(smClient.getString("errorReportValve.statusHeader", new Object[]{String.valueOf(statusCode), reason})).append("</h1>");if (this.isShowReport()) {sb.append("<hr class=\"line\" />");sb.append("<p><b>");sb.append(smClient.getString("errorReportValve.type"));sb.append("</b> ");if (throwable != null) {sb.append(smClient.getString("errorReportValve.exceptionReport"));} else {sb.append(smClient.getString("errorReportValve.statusReport"));}sb.append("</p>");if (!message.isEmpty()) {sb.append("<p><b>");sb.append(smClient.getString("errorReportValve.message"));sb.append("</b> ");sb.append(message).append("</p>");}sb.append("<p><b>");sb.append(smClient.getString("errorReportValve.description"));sb.append("</b> ");sb.append(description);sb.append("</p>");if (throwable != null) {String stackTrace = this.getPartialServletStackTrace(throwable);sb.append("<p><b>");sb.append(smClient.getString("errorReportValve.exception"));sb.append("</b></p><pre>");sb.append(Escape.htmlElementContent(stackTrace));sb.append("</pre>");int loops = 0;for(Throwable rootCause = throwable.getCause(); rootCause != null && loops < 10; ++loops) {stackTrace = this.getPartialServletStackTrace(rootCause);sb.append("<p><b>");sb.append(smClient.getString("errorReportValve.rootCause"));sb.append("</b></p><pre>");sb.append(Escape.htmlElementContent(stackTrace));sb.append("</pre>");rootCause = rootCause.getCause();}sb.append("<p><b>");sb.append(smClient.getString("errorReportValve.note"));sb.append("</b> ");sb.append(smClient.getString("errorReportValve.rootCauseInLogs"));sb.append("</p>");}sb.append("<hr class=\"line\" />");}if (this.isShowServerInfo()) {sb.append("<h3>").append(ServerInfo.getServerInfo()).append("</h3>");}sb.append("</body></html>");try {try {response.setContentType("text/html");response.setCharacterEncoding("utf-8");} catch (Throwable var18) {ExceptionUtils.handleThrowable(var18);if (this.container.getLogger().isDebugEnabled()) {this.container.getLogger().debug("Failure to set the content-type of response", var18);}}Writer writer = response.getReporter();if (writer != null) {writer.write(sb.toString());response.finishResponse();}} catch (IllegalStateException | IOException var19) {}}}}}protected String getPartialServletStackTrace(Throwable t) {StringBuilder trace = new StringBuilder();trace.append(t.toString()).append(System.lineSeparator());StackTraceElement[] elements = t.getStackTrace();int pos = elements.length;int i;for(i = elements.length - 1; i >= 0; --i) {if (elements[i].getClassName().startsWith("org.apache.catalina.core.ApplicationFilterChain") && elements[i].getMethodName().equals("internalDoFilter")) {pos = i;break;}}for(i = 0; i < pos; ++i) {if (!elements[i].getClassName().startsWith("org.apache.catalina.core.")) {trace.append('\t').append(elements[i].toString()).append(System.lineSeparator());}}return trace.toString();}private boolean sendErrorPage(String location, Response response) {File file = new File(location);if (!file.isAbsolute()) {file = new File(this.getContainer().getCatalinaBase(), location);}if (file.isFile() && file.canRead()) {response.setContentType("text/html");response.setCharacterEncoding("UTF-8");try {OutputStream os = response.getOutputStream();InputStream is = new FileInputStream(file);IOTools.flow(is, os);return true;} catch (IOException var6) {this.getContainer().getLogger().warn(sm.getString("errorReportValve.errorPageIOException", new Object[]{location}), var6);return false;}} else {this.getContainer().getLogger().warn(sm.getString("errorReportValve.errorPageNotFound", new Object[]{location}));return false;}}public void setShowReport(boolean showReport) {this.showReport = showReport;}public boolean isShowReport() {return this.showReport;}public void setShowServerInfo(boolean showServerInfo) {this.showServerInfo = showServerInfo;}public boolean isShowServerInfo() {return this.showServerInfo;}public boolean setProperty(String name, String value) {ErrorPage ep;if (name.startsWith("errorCode.")) {int code = Integer.parseInt(name.substring(10));ep = new ErrorPage();ep.setErrorCode(code);ep.setLocation(value);this.errorPageSupport.add(ep);return true;} else if (name.startsWith("exceptionType.")) {String className = name.substring(14);ep = new ErrorPage();ep.setExceptionType(className);ep.setLocation(value);this.errorPageSupport.add(ep);return true;} else {return false;}}public String getProperty(String name) {String result;ErrorPage ep;if (name.startsWith("errorCode.")) {int code = Integer.parseInt(name.substring(10));ep = this.errorPageSupport.find(code);if (ep == null) {result = null;} else {result = ep.getLocation();}} else if (name.startsWith("exceptionType.")) {String className = name.substring(14);ep = this.errorPageSupport.find(className);if (ep == null) {result = null;} else {result = ep.getLocation();}} else {result = null;}return result;}
}
方法二:
将修改好的.class文件替换tomcat-embed-core.jar的源码
重新编译,将生成的ErrorReportValve.class替换掉原始的tomcat-embed-core的jar包。
解决!
修复完成