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

news2024/11/28 5:34:00

调用这个,能复现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.coloradmin.cn/o/1603678.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【IoTDB 线上小课 02】开源增益的大厂研发岗面经

还有友友不知道我们的【IoTDB 视频小课】系列吗&#xff1f; 关于 IoTDB&#xff0c;关于物联网&#xff0c;关于时序数据库&#xff0c;关于开源...给我们 5 分钟&#xff0c;持续学习&#xff0c;干货满满~ 5分钟学会 大厂研发岗面试 之前的第一期小课&#xff0c;我们听了 I…

康耐视visionpro-CogHistogramTool操作操作工具详细说明

CogHistogramTool]功能说明&#xff1a; 对图像区域中的像素值进行灰度值统计 CogHistogramTool操作说明&#xff1a; ①.打开工具栏&#xff0c;双击或点击鼠标拖拽添加CogHistogramTool工具 2.添加输入图像&#xff0c;点击鼠标右键“链接到”或以连线拖拽的方式选择相应输入…

Dual-AMN论文阅读

Boosting the Speed of Entity Alignment 10: Dual Attention Matching Network with Normalized Hard Sample Mining 将实体对齐速度提高 10 倍&#xff1a;具有归一化硬样本挖掘的双重注意力匹配网络 ABSTRACT 寻找多源知识图谱(KG)中的等效实体是知识图谱集成的关键步骤&…

Real3DPortrait照片对口型,数字人,音频/视频驱动数字人

先看效果 上传一张图片和一段音频&#xff0c;照片如下&#xff1a; 合成后效果如下&#xff1a; 照片对口型-音频驱动 支持音频驱动和视频驱动&#xff0c;视频可以使照片有参照视频中的口型和和动作。 项目地址 https://github.com/yerfor/Real3DPortrait 我的环境 win…

【C语言回顾】函数

前言1. 函数的概念和分类2.库函数3. 自定义函数3.1 自定义函数的简单介绍3.2 自定义函数举例 4. 形参和实参4.1 形参4.2 实参4.3 形参和实参的关系4.3.1 理解4.3.2 举例代码和调试 5. 嵌套函数和链式访问5.1 嵌套函数5.2 链式访问 6. 函数的声明和定义6.1 单个文件6.2 多个文件…

【活动通知】COC 成都 CMeet 系列:2024 WTM 社区(国际妇女节)IWD 活动!

文章目录 前言一、关于 2024 WTM IWD 社区活动二、时间地点三、活动议程及报名方式四、分享嘉宾及主题信息4.1、李然——点燃创造力&#xff0c;重塑未来4.2、何静——乘风破浪&#xff0c;与 AI 的过去、现在、未来式4.3、晓丽老师——用 AI 给女性插上飞翔的翅膀 五、CSDN 成…

小成本搏大流量:微信/支付宝小程序搜索排名优化

随着移动互联网的快速发展&#xff0c;小程序已成为企业和个人开发者重要的流量入口和业务承载平台。而小程序搜索排名则是影响小程序曝光量、用户获取及业务转化的关键因素。小柚在本文和大家探讨如何制定有效的优化方案&#xff0c;提升小程序在搜索结果中的排名。 首先跟我…

2023年图灵奖颁发给艾维·维格森(Avi Wigderson),浅谈其计算复杂性理论方面做出的重要贡献

Avi Wigderson是一位以色列计算机科学家&#xff0c;他在计算复杂性理论方面做出了重要的贡献&#xff0c;并对现代计算产生了深远的影响。 Wigderson的主要贡献之一是在证明计算复杂性理论中的基本问题的困难性方面。他证明了许多经典问题的困难性&#xff0c;如图论中的图同构…

如何使用Postgres的扩展(如PostGIS)来支持地理空间数据

文章目录 解决方案1. 安装PostGIS扩展2. 创建地理空间数据表3. 插入地理空间数据4. 进行地理空间查询 示例代码 在PostgreSQL中&#xff0c;我们可以使用扩展来增强数据库的功能。对于地理空间数据&#xff0c;PostGIS是一个特别有用的扩展&#xff0c;它提供了对地理对象&…

SpringMVC 常用注解介绍

Spring MVC 常用注解介绍 文章目录 Spring MVC 常用注解介绍准备1. RequestMapping1.1 介绍2.2 注解使用 2. 请求参数2.1 传递单个参数2.2 传递多个参数2.3 传递对象2.4 传递数组 3. RequestParam3.1 注解使用3.2 传入集合 4. RequestBody5. PathVariable6. RequestPart7. Rest…

Java PDF文件流传输过程中速度很慢,如何解决?

专栏集锦&#xff0c;大佬们可以收藏以备不时之需&#xff1a; Spring Cloud 专栏&#xff1a;http://t.csdnimg.cn/WDmJ9 Python 专栏&#xff1a;http://t.csdnimg.cn/hMwPR Redis 专栏&#xff1a;http://t.csdnimg.cn/Qq0Xc TensorFlow 专栏&#xff1a;http://t.csdni…

Kimichat炒股:7个提示词案例

●了解股票投资基本概念和知识 什么是有息负债率&#xff1f;用浅显明白的话语针对没有财务会计基础的小白进行解释 Kimi的回答&#xff1a; 有息负债率是一个财务指标&#xff0c;用来衡量一家公司在其负债中有多少是需要支付利息的。简单来说&#xff0c;就是公司借的钱中&…

Scratch四级:第02讲 字符串

第02讲 字符串 教练:老马的程序人生 微信:ProgrammingAssistant 博客:https://lsgogroup.blog.csdn.net/ 讲课目录 运算模块:有关字符串的积木块遍历字符串项目制作:“解密”项目制作:“成语接龙”项目制作:“加减法混合运算器”字符串 计算机学会(GESP)中属于三级的内…

PotPlayer 图像截取

PotPlayer 图像截取 1. PotPlayer2. PotPlayer 下载2.1. PotPlayer 240305 3. 图像截取References 1. PotPlayer http://www.potplayercn.com/ PotPlayer 是 KMPlayer 原作者姜勇囍进入新公司 Daum 之后推出的&#xff0c;继承了 KMPlayer 所有的优点&#xff0c;拥有异常强大…

go语言并发实战——日志收集系统(三) 利用sarama包连接KafKa实现消息的生产与消费

环境的搭建 Kafka以及相关组件的下载 我们要实现今天的内容&#xff0c;不可避免的要进行对开发环境的配置&#xff0c;Kafka环境的配置比较繁琐&#xff0c;需要配置JDK,Scala,ZoopKeeper和Kafka&#xff0c;这里我们不做赘述&#xff0c;如果大家不知道如何配置环境&#x…

全国产化无风扇嵌入式车载电脑农耕车辆/钢厂天车行业应用

农耕车辆行业应用 背景介绍 当前农耕车车载电脑主要的功能&#xff0c;是要实现农耕车的精确的定位和导航&#xff0c;更加先进的系统则要实现农耕车自动驾驶&#xff0c;与农耕车上相关传感器的通讯(例如耕土深度的传感器, 油量存量传感器…)来实现更多的自动化、信息化的功能…

28岁转行嵌入式适合转嵌入式吗?

转行到嵌入式领域是一个很好的选择&#xff0c;特别是如果你对电子技术、嵌入式系统和软硬件交互感兴趣的话。我这里有一套嵌入式入门教程&#xff0c;不仅包含了详细的视频 讲解&#xff0c;项目实战。如果你渴望学习嵌入式&#xff0c;不妨点个关注&#xff0c;给个评论222&a…

Java面试八股之JDK和JRE的区别

JDK和JRE的区别 定义&#xff1a;JDK&#xff08;Java Development Kit&#xff09;是Java开发工具包的缩写&#xff0c;它是Java开发人员必备的工具。JDK包含了编译器(javac)、Java虚拟机(JVM)和Java类库等开发工具和资源。它提供了开发、编译、调试和运行Java程序所需的一切…

NLP学习(1)-搭建环境

前言 仅记录学习笔记&#xff0c;如有错误欢迎指正。 环境搭建 一、环境软件安装&#xff1a; 1、Anaconda安装&#xff08;一款可以同时创建和管理多个python环境的软件&#xff09; (1) 安装链接&#xff1a; https://blog.csdn.net/m0_61531676/article/details/126290…

适用于Windows电脑的最佳数据恢复软件是哪些?10佳数据恢复软件

丢失我们系统中可用的宝贵信息是很烦人的。我们可以尝试几种手动方法来重新获取丢失的数据。然而&#xff0c;当我们采用非自动方法来恢复数据时&#xff0c;这是一项令人厌烦和乏味的工作。在这种情况下&#xff0c;我们可以尝试使用一些正版硬盘恢复软件进行数据恢复。此页面…