V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
461da73c
V2EX  ›  程序员

为啥一个打日志的要去访问网络

  •  
  •   461da73c · 2021-12-10 11:51:11 +08:00 · 6251 次点击
    这是一个创建于 1111 天前的主题,其中的信息可能已经有所发展或是发生改变。

    看到大家热传的 log4j 打日志爆了严重漏洞,本人不写 java ,不太理解打日志能打出个什么名堂,要去访问网络? 烦请各位 JAVA 大佬解答一下小弟的疑惑。

    31 条回复    2021-12-13 09:51:46 +08:00
    Kasumi20
        1
    Kasumi20  
       2021-12-10 12:08:23 +08:00   ❤️ 1
    不清楚,只会 System.out.println 的路过。
    aguesuka
        2
    aguesuka  
       2021-12-10 12:52:25 +08:00   ❤️ 3
    作者想去访问 "java:comp/env/" 中的环境变量比如 "logging/context-name", 但是实际调用的 JNDI 相当于 Java 中的 eval
    unco020511
        3
    unco020511  
       2021-12-10 14:28:52 +08:00   ❤️ 4
    java 的东西哪个不是复杂的一笔哈哈,打日志也能打出花来
    hfc
        4
    hfc  
       2021-12-10 14:41:09 +08:00
    类似 SQL 注入吧,出现了预期外的行为
    xuanbg
        5
    xuanbg  
       2021-12-10 14:52:36 +08:00
    目的是调用 JNDI 实现获取外部信息的功能,但没有充分考虑这个功能的安全性。

    怎么说呢,调用 JNDI 这个需求是存在的,但不应该由日志组件或者其他第三方组件来实现。自己来调用 JNDI 是可控的,第三方实现了这个功能,就变得不可控了。
    gadfly3173
        6
    gadfly3173  
       2021-12-10 14:53:40 +08:00
    访问网络是传入的不合法参数,也就是脚本执行的。这个漏洞本质是因为 log4j 不止日志能打进文件、console ,还可以调用各种本地服务打进各种地方,比如 ES 之类的,但是 log4j 又没有对恶意代码有什么防范,就像 SQL 注入一样被利用了。
    461da73c
        7
    461da73c  
    OP
       2021-12-10 16:16:34 +08:00
    @gadfly3173 不是很理解,不搞骚操作怎么有机会注入执行,例如最简单的日志:System.out.println 。
    ohwind
        8
    ohwind  
       2021-12-10 17:01:40 +08:00
    @461da73c out 是标准输出,有时候你不一定想写到 out 里,也可能想写到 err 里,或者数据库里,又或者其他机器上。
    sujin190
        9
    sujin190  
       2021-12-10 17:10:08 +08:00 via Android   ❤️ 4
    没必要解释有没有需求这种问题,java 这些东西本来就有过度设计的问题,不需要解释,一个打日志组件做这种解析居然不是个可选功能,毫无疑问过度设计了,但重点是一直搞不懂干 java 的都有种盲目的把过度设计当系统牛逼的依据而完全不管自己的业务场景业务需求,真是不明所以
    gadfly3173
        10
    gadfly3173  
       2021-12-10 17:17:13 +08:00   ❤️ 1
    @461da73c #7 因为就是搞了骚操作。。。github 上有个针对这玩意的 patch 就是干脆直接在 log4j2 试图走 JNDI 的时候直接抛异常
    wanguorui123
        11
    wanguorui123  
       2021-12-10 17:20:51 +08:00
    @GetMapping("test")
    public BaseResponse submit(@RequestParam("test")String test){
    logger.error(test);//logger.error("${jndi:ldap:/ /127.0.0.1:13}")
    }
    4771314
        12
    4771314  
       2021-12-10 17:34:06 +08:00
    打日志走网络也有的,通过 agent 将日志输出到统一的中心机器,进行日志的分析和处理
    不过更多的还是日志打印到本地,配置代理采集本地的日志文件
    zmxnv123
        13
    zmxnv123  
       2021-12-10 17:42:41 +08:00   ❤️ 18
    虽然我是写 Java 的,但我也不懂为啥要去访问网络,今天专门搜了下 JNDI ,心想不就是个统一配置,为什么这都要出个规范...。不说了,来个段子吧,
    ---------------------------------
    作者:Damon DanceForMe
    链接: https://www.zhihu.com/question/277243683/answer/393676961
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    这问题你应该去问企业级 Java 架构师。
    就比如 print 一句 hello world 吧。
    main 函数里 print 一下?太面向过程,太 low 了。
    得封装一个类。叫 Printer. Printer 有个成员方法,叫 print 。
    但是!光一个类太 low 了,以后要是有不同的实现怎么办?
    所以得加一个接口。PrinterInterface 。
    但是! interface 是没有实现的,还是要有默认实现才行。
    所以得加个虚拟类,AbstractPrinter 实现 PrinterInterface ,然后 Printer 继承 AbstractPrinter 。
    但是!你有了那么一套,该怎么创建实例呢?直接 new Printer()?太 low 了,那叫实现依赖。
    肯定不行的,所以要搞一个工厂类,PrinterFactory ,PrinterFactory 用 PrinterInterface 返回实例,这样就隐藏了实现细节了。但是! PrinterFactory 本身也是实现类啊,太 low 了,所以得有 PrinterFactoryInterface, AbstractPrinterFactory. 而且在 PrinterFactory 里面该怎么写呢?直接 new Printer()? 太 low 了。还是实现依赖。
    最后,你要把这一堆玩意在代码里组装起来,也太难看了,各种 new 实现类。太 low !好在我们有个高级玩意,叫依赖注入!把程序对象结构全写到配置文件里面。这一套当然是不能自己造轮子的。配置 Spring 吧。搞了那么多 lib ,靠命令行或者 IDE 的项目管理肯定不够啊,得有依赖管理。Maven 啊 Gradle 啊使劲上。最最后,要 print 的东西怎么传给程序呢?硬编码?命令行传参数?太 low !当然得写在 XML 里头。光是 XML 当然还不够企业级,再加上 DTD 验证吧。然后就涉及到了 XML 解析的问题了。代码里直接操起 parser 吗?太 low! 当然要写个 parser 的包装类,interface, abstract class, implementation class, factory class 再来一套。毕竟,不能依赖实现啊,以后我要是换 parser 了怎么办。所以最后是成品是一堆配置文件,一堆 jar ,compile 出来的程序 200MB 。IDE 得装上 300 个插件,打开项目硬盘响老半天吃掉 2GB 内存,然后一堆插件弹提示要求升级。哦对了,在这一切发生之前,还得画 UML 图呢。三年后项目完工了,部署到客户的服务器上一跑,立马崩溃,一地的 stack trace 。原来客户服务器上用的是 JDK 5 而新项目需要 JDK 6. 然后问客户你们不能升级吗,答案是不行,因为另外一个企业级开发组给做的企业级解决方案只支持 JDK 5 。接着客户把你们的架构师臭骂了一顿,你搞了那么多设计就没有想过可能会换 JDK 吗?——
    gadfly3173
        14
    gadfly3173  
       2021-12-10 17:52:16 +08:00
    @zmxnv123 #13 虽然但是,最后一条 jdk 是可以多版本共存的,启动的时候指定一下用哪个就行了,不放心还可以用 docker (
    litchinn
        15
    litchinn  
       2021-12-10 17:55:59 +08:00   ❤️ 1
    @gadfly3173 那这篇回答还能续上,docker 解决 jdk 的问题,k8s 解决 docker 的弹性伸缩问题🐶🐶🐶
    gadfly3173
        16
    gadfly3173  
       2021-12-10 17:58:33 +08:00
    @litchinn #15 太草了 我是很粗暴的直接 pm2 管理所有要保持启动的服务(不用 supervisor 是因为我不喜欢),其实一般的 springboot 不配置的话,usedheap 也就 150MB 左右,不算很吃内存(
    whyso
        17
    whyso  
       2021-12-10 18:03:02 +08:00
    @zmxnv123 虽然我不会 Java ,但是。。。哈哈哈。。。
    darkengine
        18
    darkengine  
       2021-12-10 18:04:05 +08:00
    @zmxnv123 我顺着你这个链接摸了半天鱼
    Jooooooooo
        19
    Jooooooooo  
       2021-12-10 18:04:50 +08:00
    这个灵魂发问看 hn 上也有人说

    我估摸肯定是某个很小众的需求, 提出了来然后就实现了
    gadfly3173
        20
    gadfly3173  
       2021-12-10 18:05:06 +08:00
    其实 java 里这些过度设计也不算很奇怪,比如一般一些 sdk 之类的里面会提供多种 http client 、json 解析器的实现,如果公司有要求必须要用阿里系的 fastjson ,或者不许用 okhttp ,必须用 spring 自带的 resttemplate 的话,想切换很容易,不需要的依赖 exclude 掉也不会影响体积
    sagaxu
        21
    sagaxu  
       2021-12-10 18:06:13 +08:00 via Android
    http 接口输出一个 hello world ,调用栈能几十层,老传统了
    passerbytiny
        22
    passerbytiny  
       2021-12-10 18:22:00 +08:00 via Android
    “不该访问网络”,这是在业务层(高层)面的隔离,日志打印是底层工具,它不该考虑上层的东西,除非到了不得不考虑的时候。

    真考虑了反而出问题,比如你在底层隔离了网络访问,然后来了一个打印到内网网络位置的需求。
    2i2Re2PLMaDnghL
        23
    2i2Re2PLMaDnghL  
       2021-12-10 23:21:04 +08:00
    https://issues.apache.org/jira/browse/LOG4J2-313

    这是提供了相应 java 文件的 commit 的对应 Bug 编号
    sujin190
        24
    sujin190  
       2021-12-11 00:08:40 +08:00
    @passerbytiny #22 java 生态的问题就是在这,老是瞎想万一要啥啥所以一开始就要这样那样,且不说真后面有这需求了改起来也未必有多高成本,更不用说现实绝大部份情况根本不会出现一开始预测的情况,基于瞎想和技术装逼症滥用且过度设计,反而导致现实情况下很多时候既不能了解基础原理亦不能完全了解设计逻辑,然后实际依然一堆问题,而且大多数时候既弄不清底层又不理不清设计原理,也就各种加班自己辛苦了

    固然这个世界还是有少部分头部公司确实会把各种只在想象中的需求踩一遍,但也不妨碍基础组件设置为可选递进选择模式的吧,最后更重要的是,大公司有足够人力物力滥用设计也就滥用了吧,反正人家有钱,但是中小公司不看业务场景不看自己成本,也学大公司喜欢技术牛逼症滥用设计模式这种思维模式才是坑死个人
    muzuiget
        25
    muzuiget  
       2021-12-11 13:46:14 +08:00
    @zmxnv123 血压已经上来了。
    securityCoding
        26
    securityCoding  
       2021-12-11 16:23:47 +08:00 via Android
    @unco020511 写了六年 java 深有同感 233 ,太复杂了一环套一环
    mingl0280
        27
    mingl0280  
       2021-12-11 23:10:31 +08:00 via Android
    @passerbytiny 为什么打印到网络的需求不是依赖项目实现的?底层库干这个纯粹脑残。哪怕是挂个允许 IO 重定向估计这次这事也不会发生了。
    agagega
        28
    agagega  
       2021-12-12 02:30:27 +08:00 via iPhone
    有人记得 sgml 吗
    ruanimal
        29
    ruanimal  
       2021-12-12 19:07:22 +08:00
    @xuanbg 这种功能默认启用就离谱,而且好像没多少人说这样不对。。。
    MrVito
        30
    MrVito  
       2021-12-12 21:03:48 +08:00
    应该是为了满足某些集群里面,需要集中把某些日志集中到一台机器上这种需求吧?
    qiany
        31
    qiany  
       2021-12-13 09:51:46 +08:00
    @sagaxu 其他语言有多少层呢 我只会 java
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1084 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 19:00 · PVG 03:00 · LAX 11:00 · JFK 14:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.