首页 > 其他分享 >不校验参数的后果

不校验参数的后果

时间:2023-03-10 23:33:45浏览次数:34  
标签:String 删除 后果 路径 校验 参数 path sb 报错

故事起因

一个和往常一样的下午,听着音乐,敲着代码。突然客户群里报案说系统好像挂了,好多请求都报错。看到消息的我,不慌不忙在客户群里回复了一句"收到,我看看",就连上了客户的服务器,查看日志。

日志里大量请求在报错,有报类未定义的,有报类文件找不到的,还有一些见都没见过的报错。想着最近也没上什么新代码啊,再说了,改出的新 bug 也不至于导致这么多问题吧,所以打算看看当前的 jar 是什么时候上线的。

进入程序部署的目录一看,好家伙,当前路径下文件数为 0。程序包,启动脚本,版本备份,配置文件统统不见了。

由于我们一般都是远程连接到客户的电脑上的,在问题发生之前,组内的人都在忙其他的事,于是就把锅甩给了客户自己,是不是你们那边的人误删了呀。客户也很无奈,让我查查能不能找到操作记录。

一番检索下来,发现只能查看当前登录用户的操作记录,其实也有办法查看所有用户的记录,只是需要提前做监控。

这次问题就以我方重新部署程序而告终。确实摸不着头脑,第一次碰见这样的问题。

故事再来就是事故

就当大家都以为只是谁误删导致的事故时。事故,它又来了。

同样的一个平常的下午,客户又在群里报案,系统好像又挂了,好多请求都报错。我回以一个同样的答复,又开始看日志,嚯,和上次一样的报错。再到程序部署目录一看,又被删了。

这次用户也恼了,究竟是谁在恶作剧。然后提议改系统登录密码,能不能找到操作记录等等。

我只是无奈得回复,我先恢复现场再说吧。

恢复之后,觉得同样的事情发生两次,是恶作剧或者误删的可能性也太小了,会不会是程序删的,或者是什么脚本删掉。

于是想起之前注意到,被删除的目录的最后修改时间为 16:37, 然后就到日志里看对应时间的系统行为。结果,在这个时间点之前,果真有一个删除文件的操作。这个接口接收前端传来的一个文件路径,然后删除服务器上这个路径下保存的文件。16:37 的这次请求里,前端传来的路径是一个空字符……

功能背景

系统需要实现一个公共盘功能,具有对文件基本的 CRUD 操作。具体实现是,将公共空间挂载到 AP 服务器的目录上,这样程序直接操作本机文件系统就可以实现对公共盘的操作。

其中有一个删除文件的操作,代码大概是这样的:

public void deleteFileByPath(String url) {
    Path path = Paths.get(url);
    Files.list(path).forEach(f -> {
        // 递归删除文件
    })
}

这段代码有什么问题吗?就算会递归删除指定的路径,那前端不可能知道后端程序部署的路径的啊。是怎么把部署所在目录下的文件删除的?

于是开始 debug,把空字符串传进来,一步一步。

path.toStirng() => "", 没问题;path.toAbsolutePath() => /path/to/user/dir, 嗯?咋回事,咋就是我本地程序的根目录了呢?

破案了,根本原因找到了。

哭笑不得,赶紧对传入的参数进行校验,规则如下:

  1. 不能为空
  2. 不能包含 ..
  3. 必须以指定目录开头,如:/ftp

于是赶紧发布修复版本。

事后复盘

本次事故的直接原因就是没有对传入的路径做任何的校验,更别说是否是安全路径的校验了。严重点,可以被传入系统根目录或者带 .. 的上级目录,而导致系统被删除,那就真的是 rm -rf / 从删库到跑路了。

线上已经修复了,相关开发者也沟通过了,就要看看为什么 Paths.get("") 能够返回当前的运行目录,这不是很不合理吗,是不是设计失误?

翻翻代码

public static Path get(String first, String... more) {
    return FileSystems.getDefault().getPath(first, more);
}

可以看到,获取到默认的 fileSystem 类,通过 fs 的 getPath 获得路径。兵分两路:

  1. getPath

Mac 上找到 FileSystem 的实现类 UnixFileSystem, getPath 的实现如下:

@Override
public final Path getPath(String first, String... more) {
    String path;
    if (more.length == 0) {
        path = first;
    } else {
        StringBuilder sb = new StringBuilder();
        sb.append(first);
        for (String segment: more) {
            if (segment.length() > 0) {
                if (sb.length() > 0)
                    sb.append('/');
                sb.append(segment);
            }
        }
        path = sb.toString();
    }
    return new UnixPath(this, path);
}

可以看到,当执行 Paths.get("") 时,这里的 path 变量实际的值依旧是空字符串。剩下的就是 UnixPath 类实例化时的一些细节,看下来和程序根目录没啥关系。

  1. FileSystems.getDefault()

于是又在 UnixFileSystem 实现类里发现了这个:

private static final String USER_DIR = "user.dir";
private final UnixFileSystem theFileSystem;

public UnixFileSystemProvider() {
    String userDir = System.getProperty(USER_DIR);
    theFileSystem = newFileSystem(userDir);
}

@Override
public final FileSystem getFileSystem(URI uri) {
    checkUri(uri);
    return theFileSystem;
}

真相大白啦。

标签:String,删除,后果,路径,校验,参数,path,sb,报错
From: https://www.cnblogs.com/xiawanxw/p/17204997.html

相关文章

  • 查看CPU性能参数
    Linux中常用的监控CPU整体性能的工具有§mpstat:mpstat不但能查看所有CPU的平均信息,还能查看指定CPU的信息。 §vmstat:只能查看所有CPU的平均信息;查看cpu队列信息; ......
  • 01 函数参数的使用
    """@作者:egon老湿@微信:18611453110@专栏:https://zhuanlan.zhihu.com/c_1189883314197168128"""#一形参与实参介绍#形参:在定义函数阶段定义的参数称之为形式参数,简......
  • easyexcel填坑-校验表头为空,或者不符合预期
    背景:easyexcelv3.1.5实体类已经使用注解@ExcelProperty标注需要导入的属性正文开始关闭忽略空行,防止第一行是空跳过校验 ignoreEmptyRow(false)。此处如果未关闭,第......
  • ASEMI高压MOS管10N65参数,10N65规格,10N65封装
    编辑-ZASEMI高压MOS管10N65参数:型号:10N65漏极-源极电压(VDS):650V栅源电压(VGS):30V漏极电流(ID):10A功耗(PD):65W储存温度(Tstg):-55to150℃静态漏源导通电阻(RDS(ON)):0.9Ω二极......
  • 关于c#泛类型参数T的约束
    c#支持泛式编程,在我们定义泛型类时,可以加入泛类型参数T的约束。为什么需要参数约束呢,官方是这么说的:如果要检查泛型列表中的某个项以确定它是否有效,或者将它与其他某个项......
  • 类型参数的约束(C# 编程指南)
    类型参数的约束(C#编程指南)VisualStudio2005 其他版本 38(共55)对本文的评价是有帮助 - 评价此主题  在定义泛型类时,可以对客户端代码能够在实例......
  • vue如何通过$router.push传参数
    如何通过$router.push传参数下面通过A页面向B页面传值来举个例子://A页面:this.$router.push({name:'页面B',params:{data:'我是要传递的参数'}})//B......
  • Springcloud学习笔记56--SpringBoot之GET请求与Post请求参数偶发性丢失问题
    1.概述最近遇到一个偶现的问题,在向服务端请求的时候,偶尔会出现异常,在请求中的queryString传递了参数,却出现了异常MissingServletRequestParameterException如下所示:or......
  • springboot 全局 Date参数接收 String格式 转换异常报错
    JSONparseerror:Cannotdeserializevalueoftype`java.util.Date`fromString\"2023-03-1010:00:00\":notavalidrepresentation(error:FailedtoparseDa......
  • mongdb.driver UpdateOptions参数解析
    在.NETMongoDB.Driver中,UpdateOptions类是MongoDB集合中更新操作的参数选项类。该类包含以下常用属性:IsUpsert:是否执行upsert操作。如果设置为true,表示文档不存......