CodeQL 文档

日志注入

ID: rb/log-injection
Kind: path-problem
Security severity: 7.8
Severity: error
Precision: medium
Tags:
   - security
   - external/cwe/cwe-117
Query suites:
   - ruby-security-extended.qls
   - ruby-security-and-quality.qls

点击查看 CodeQL 仓库中的查询

如果将未经清理的用户输入写入日志条目,恶意用户可能能够伪造新的日志条目。

当日志输出显示时,如果用户提供了一些在解释时会被解释为字符的输入,则可能会发生伪造。如果日志以纯文本文件形式显示,则恶意用户可以使用换行符。如果日志以 HTML 形式显示,则可以包含任意 HTML 来伪造日志条目。

建议

用户输入应在记录之前进行适当的清理。清理方式取决于日志条目将如何显示或使用。

如果日志条目为纯文本,则应使用 String#gsub 或类似方法从用户输入中删除换行符。还应注意在日志条目中明确标记用户输入。

对于将在 HTML 中显示的日志条目,用户输入应在记录之前进行 HTML 编码,以防止伪造和其他形式的 HTML 注入。

示例

在示例中,使用 `Logger#info` 记录用户提供的用户名。

在第一个案例中,它是直接记录的,没有进行任何清理。如果恶意用户提供 `username=Guest%0a[INFO]+User:+Admin%0a` 作为用户名参数,则日志条目将被拆分为两行,其中第二行将是 `[INFO]+User:+Admin`。

require 'logger'

class UsersController < ApplicationController
  def login
    logger = Logger.new STDOUT
    username = params[:username]

    # BAD: log message constructed with unsanitized user input
    logger.info "attempting to login user: " + username

    # ... login logic ...
  end
end

在第二个示例中,使用 String#gsub 确保用户输入中没有换行符。

require 'logger'

class UsersController < ApplicationController
  def login
    logger = Logger.new STDOUT
    username = params[:username]

    # GOOD: log message constructed with sanitized user input
    logger.info "attempting to login user: " + sanitized_username.gsub("\n", "")

    # ... login logic ...
  end
end

参考资料

  • ©GitHub, Inc.
  • 条款
  • 隐私