这里:https: //logging.apache.org/log4j/2.x/manual/getting-started.html#best-practice-concat
关于在 log4j 中使用字符串连接,他们是这样说的:
更重要的是,这种方法很容易受到攻击!想象一下用户提供的 userId 包含以下内容:不存在的参数的占位符会触发失败:{} {} {dangerousLookup}
有人能解释一下为什么这很危险吗?我不明白字符串连接与这个“dangerousLookup”有什么关系。
我认为文档非常清楚
如果你有以下记录器并且通过了上面的
userId
代码执行将会中断,因为记录器将以内容的形式出现,
"failed for user ID: placeholders for non-existing args to trigger failure: {} {} "
并且记录器将引发异常,即未提供所需的 2 个参数。此外,正如评论者Violet所提到的,有人甚至可以传递带有动态评估的连接参数。某些内容不应该打印在日志中,例如,
${env:SECRET_ENV_VAR}
危险查找中提到的情况。您还可以将以上两者结合起来,看看某人如何使用记录器中抛出的异常,该记录器向用户提供异常的信息,以获取原本应该隐藏的信息。
这就是为什么他们建议要求信息的布局是具体的,而不是控制论点。例如
现在,记录器将仅打印布局中描述的提供的参数
userId
,并且不会将其与布局混合,以便保护您免受上述和其他几个问题的影响。如果您使用字符串连接(如链接的示例所示),并且连接的变量的值可能来自您无法控制的外部源,则攻击者可以使该值具有占位符,log4j 的日志记录方法将照常处理这些占位符,并且该占位符可能包含利用 log4j 中的漏洞的恶意代码。然后,该恶意代码将被执行,攻击者将获得利用该漏洞的好处。这就是其含义
{dangerouslookup}
,大概是指 log4j 中过去使用 JNDI 查找作为攻击媒介的漏洞。文档令人困惑,感谢您报告问题。字符串连接和参数化日志记录本身都没有安全隐患。但是,当您将两者混合使用时,就会出现问题:
如果攻击者
{}
以用户身份发送,您将收到类似以下消息:这是一个轻微的日志注入漏洞,但它可能会给自动日志解析器带来问题或使管理员感到困惑。如果您使用参数化日志记录,则格式字符串应该是编译时常量。
如果仅使用字符串连接或参数化日志记录,则不会出现此类问题:
两者都将返回:
注意:如果日志文件被自动解析,并且日志消息的参数有意义,建议使用结构化的日志布局和地图消息。