【解决去除springboot-内嵌tomcat的异常信息显示】去掉版本号和异常信息

news/2025/1/15 21:57:59/

调用这个,能复现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包。

解决!
在这里插入图片描述
在这里插入图片描述
修复完成


http://www.ppmy.cn/news/1429826.html

相关文章

SpringBoot多数据源(二)

SpringBoot多数据源AbstractRoutingDataSource&#xff08;二&#xff09; 1.多数据源配置2.多数据源调用流程3.实现 1.多数据源配置 spring-jdbc模块提供AbstractRoutingDataSource,其内部可以包含了多个DataSource&#xff0c; 然后在运行时来动态的访问数据库 2.多数据源…

知攻善防应急靶场-Windows(Web1-2-3)

知攻善防应急靶场-Web1 1.要求 2.过程 直接扫网站根目录 发现后门 <?php error_reporting(0); session_start();$key"e45e329feb5d925b"; //该密钥为连接密码32位md5值的前16位&#xff0c;默认连接密码rebeyond$_SESSION[k]$key;session_write_close();$postf…

Android集成Sentry实践

需求&#xff1a;之前使用的是tencent的bugly做为崩溃和异常监控&#xff0c;好像是要开始收费了&#xff0c;计划使用开源免费的sentry进行替换。 步骤&#xff1a; 1.修改工程文件 app/build.gradle apply plugin: io.sentry.android.gradle sentry {// 禁用或启用ProGua…

Week7-LeetCode

2923.找到冠军(简单) 法1&#xff1a; class Solution:def findChampion(self, grid: List[List[int]]) -> int:Winner 0n len(grid)loser [0 for _ in range(n)] for i in range(n):for j in range(n):if grid[i][j] 1 and i ! j:loser[j] 1for index in range(n):i…

笔记 | 编译原理L2:词法分析(lexical analysis)

1 概述 词法分析(lexical analysis)&#xff0c;也称scanning, 编译程序的第一阶段,其作用是识别单词(程序意义上)并找出词法错误. 读入源程序的输入字符、将它们拆分成词素&#xff0c;生成并输出一个词法单元序列&#xff0c;每个词法单元对应于一个词素 回顾词法分析在整个…

2024年04月18日优雅草便民tools开源-git以及dcloud同步-长期更新

优雅草小工具-数据来自优雅草api赋能 优雅草小工具-数据来自优雅草api赋能-优雅草便民工具是一款由成都市一颗优雅草科技有限公司打造的便民查询公益工具&#xff0c;2024年1月17日正式发布v1.0.0版本&#xff0c;本工具为了方便大众免费使用&#xff0c;本生活小工具会陆续加入…

状态模式(状态和行为分离)

状态模式 文章目录 状态模式什么是状态模式状态模式好处与用处什么时候考虑使用状态模式通过示例了解状态模式 什么是状态模式 状态模式(State),当一个对象的内在状态改变时允许改变其行为&#xff0c;这个对象看起来像是改变了其类 状态模式主要解决的是当控制一个对象状态转换…

aws挂载s3

安装 yum update -y yum install automake fuse fuse-devel gcc-c git libcurl-devel libxml2-devel make openssl-devel -y git clone https://github.com/s3fs-fuse/s3fs-fuse.git cd s3fs-fuse ./autogen.sh ./configure make make install 配置path vi ~/.bash_profile …