☰
Brakeman 的 Session Setting 警告详解:HTTP Only、密钥长度与版本控制泄露检测
2026/9/29 7:02:54 网站建设 项目流程
  • SAST
  • 应用安全
  • 开发工具

【免费下载链接】brakeman

A static analysis security vulnerability scanner for Ruby on Rails applications

项目地址:https://gitcode.com/gh_mirrors/br/brakeman
点击查看免费下载

本篇文章围绕 Brakeman(Ruby on Rails 应用的静态安全漏洞扫描器)中的Session Setting警告类型展开,系统说明该检查覆盖的三类会话安全问题:会话 Cookie 未设置http-only、会话密钥长度过短、以及会话密钥被纳入版本控制。读完本文,你将掌握 Session Setting 警告的触发条件、不同 Rails 版本下的检测目标,以及如何在项目中修复这些隐患。

Session Setting 警告是什么

Brakeman 会针对应用中与 Session(会话)配置相关的安全隐患发出"Session Setting"类型的警告。从源码注释看,这一检查的目的非常明确:"Checks for session key length and http_only settings"(检查会话密钥长度与 http_only 设置),对应实现位于 lib/brakeman/checks/check_session_settings.rb。

该检查主要覆盖三类问题:

  1. HTTP Only:会话 Cookie 未设置为http-only,存在被跨站脚本(XSS)窃取的风险;
  2. Secret Length:会话 Cookie 的密钥长度不足 30 个字符;
  3. Session Secret in Version Control:config/initializers/secret_token.rb等密钥文件被纳入版本控制。

官方文档对这三类问题的完整说明见 docs/warning_types/session_setting/index.markdown。

检查一:HTTP Only 设置

为什么需要 http-only

Brakeman 建议将会话 Cookie 设置为http-only。该属性使得浏览器禁止 JavaScript 读取该 Cookie,从而有效阻止攻击者通过跨站脚本(XSS)窃取会话 Cookie、进而劫持用户会话。

触发警告的代码形态

在检查器中,check_for_issues方法会从会话配置中查找:session_http_only、:http_only、:httponly三个键,只要发现某个键的值是false(false? value判断),就会触发警告:

if value = (hash_access(settings, :session_http_only) || hash_access(settings, :http_only) || hash_access(settings, :httponly)) if false? value warn_about_http_only value.line, file end end

对应的测试样例位于 test/apps/rails2/config/initializers/session_store.rb,其中:session_http_only => false正是会触发 HTTP Only 警告的写法:

ActionController::Base.session = { :key => '_rails2_session', :secret => 'secret!', :session_http_only => false }

Rails 3.x 应用则是在config.session_store :cookie_store, { ... }中通过:httponly键配置,test/apps/rails3/config/initializers/session_store.rb 中的写法同样会触发警告:

Rails3::Application.config.session_store :cookie_store, :key => '_rails3_session', :httponly => false, :secure => false

在 test/tests/rails3.rb 中,测试用例test_http_only_session_setting验证了该场景:警告类型为 "Session Setting",消息为 "Session cookies should be set to HTTP only",置信度为 0(高),文件指向session_store.rb。

检查二:会话密钥长度

30 字符阈值

Brakeman 会在会话 Cookie 的密钥长度小于30 个字符时发出警告。过短的密钥容易被暴力破解或字典攻击,因此官方建议密钥"至少 30 个字符且完全随机,不能是常见单词"——这一建议也写在了 Rails 应用的 session_store 模板注释中:

# Make sure the secret is at least 30 characters and all random, # no regular words or you'll be exposed to dictionary attacks.

上述 rails2 测试样例中的:secret => 'secret!'只有 7 个字符,明显低于阈值,且是普通单词,属于典型的不安全配置。

触发位置

在check_for_issues中,检查器从会话配置哈希中读取:secret键,若其值为字符串,则调用warn_about_secret_token发出 "Session secret should not be included in version control" 警告。从源码结构看,该警告与"密钥泄露"归为同一类问题处理(见下文警告码一节)。

检查三:Session Secret 被纳入版本控制

风险说明

Brakeman 会警告config/initializers/secret_token.rb被纳入版本控制。会话密钥一旦进入 Git 等版本控制系统,就可能随代码公开泄露,攻击者可据此伪造签名 Cookie、解密会话数据。官方建议将该文件从版本控制中排除,并加入.gitignore:

# It is recommended to exclude secret_token.rb from version control # and include it in .gitignore.

版本控制的忽略判定

检查器在run_check中遍历config/initializers/session_store.rb与config/initializers/secret_token.rb两个文件,并调用ignored?方法判定它们是否已被.gitignore排除。ignored?的实现会依次读取./.gitignore、config/.gitignore、config/initializers/.gitignore,只要任一文件中包含该文件名,就认为已忽略、不再报警:

def ignored? file [".", "config", "config/initializers"].each do |dir| ignore_file = @app_tree.file_path("#{dir}/.gitignore") if @app_tree.exists? ignore_file input = ignore_file.read return true if input.include? file end end false end

也就是说:即便secret_token.rb或session_store.rb中写入了密钥,只要这些文件被.gitignore正确排除,Brakeman 也会放行。

Rails 4 与 secrets.yml 的硬编码检测

在 Rails 4 应用中,会话密钥通过config.secret_key_base=或config/secrets.yml配置。检查器的check_secrets_yaml会解析config/secrets.yml,若production环境下的secret_key_base是硬编码的普通字符串(即不包含<%=这类 ERB 动态取值写法),则发出警告:

if secrets && secrets["production"] and secret = secrets["production"]["secret_key_base"] unless secret.include? "<%=" line = yaml.lines.find_index { |l| l.include? secret } + 1 warn_about_secret_token line, @app_tree.file_path(secrets_file) end end

test/apps/rails4/config/secrets.yml 中的production.secret_key_base: super_duper_secret_key正是这种硬编码密钥的示例;该文件还给出了正确做法的提示:"Do not keep production secrets in the repository, instead read values from the environment",即应从环境变量读取密钥。Rails 3.1/3.2 时代的硬编码示例见 test/apps/rails3.1/config/initializers/secret_token.rb 与 test/apps/rails3.2/config/initializers/secret_token.rb。

不同 Rails 版本下的检测目标

从 lib/brakeman/checks/check_session_settings.rb 的注释和实现可以梳理出,检查器针对不同 Rails 版本设置了不同的检测目标:

Rails 版本检测的配置形态示例文件
Rails 2.xActionController::Base.session = { :secret => ..., :session_http_only => ... }config/initializers/session_store.rb
Rails 3.xApp::Application.config.secret_token = ...与config.session_store :cookie_store, { :httponly => ..., :secure => ... }config/initializers/secret_token.rb、config/initializers/session_store.rb
Rails 4.xApp::Application.config.secret_key_base = ...与config/secrets.yml中的secret_key_baseconfig/initializers/secret_token.rb、config/secrets.yml

检测逻辑分别位于三个方法中:

  • process_attrasgn:处理session=、secret_token=、secret_key_base=赋值;
  • process_call:处理session_store调用,并额外检查:secure键——若:secure => false,会发出 "Session cookie should be set to secure only" 警告(对应warn_about_secure_only,见 test/apps/rails3/config/initializers/session_store.rb 中的:secure => false);
  • check_secrets_yaml:解析 Rails 4 的config/secrets.yml。

会话配置数据本身来自 lib/brakeman/tracker/config.rb 的session_settings方法,它从收集到的 Rails 配置中读取action_controller.session分支。

警告码与 CWE 映射

Session Setting 检查的每个子问题都对应独立的警告码,定义于 lib/brakeman/warning_codes.rb:

警告码对应问题CWE
http_cookies(26)会话 Cookie 未设置 HTTP OnlyCWE-1004(敏感 Cookie 无 HttpOnly 属性)
secure_cookies(27)会话 Cookie 未设置 SecureCWE-614(Cookie 缺少 Secure 属性)
session_secret(29)会话密钥泄露(过短/硬编码/进入版本控制)CWE-798(硬编码凭据)

三者均以high置信度上报(见warn_about_http_only、warn_about_secret_token、warn_about_secure_only三个私有方法的:confidence => :high设置),说明它们被认为是确定存在的配置缺陷,值得优先修复。

如何修复 Session Setting 警告

综合文档与源码给出的判定逻辑,可以按以下方式逐一修复:

  1. 为 Cookie 启用 HTTP Only:在session_store.rb中确保:httponly => true(Rails 2.x 为:session_http_only => true)。现代 Rails 版本默认启用,需显式关闭才会触发警告。
  2. 使用足够长且随机的密钥:密钥长度至少 30 个字符,建议使用rake secret生成 128 位以上随机值,不要使用常见单词。
  3. 将密钥移出版本控制:把secret_token.rb加入.gitignore;Rails 4 的config/secrets.yml中,production 环境的secret_key_base应通过 ERB 从环境变量读取(如<%= ENV["SECRET_KEY_BASE"] %>),而不是硬编码字符串,否则check_secrets_yaml仍会报警。

修复完成后重新运行扫描,若以上配置均已满足,Brakeman 将不再输出 "Session Setting" 类型的警告;相关测试用例(如 test/tests/rails3.rb、test/tests/rails4.rb)可帮助你验证不同场景下的告警与放行行为。

  • SAST
  • 应用安全
  • 开发工具

【免费下载链接】brakeman

A static analysis security vulnerability scanner for Ruby on Rails applications

项目地址:https://gitcode.com/gh_mirrors/br/brakeman
点击查看免费下载

相关推荐

上一篇:如何一键找回QQ空间消失的说说:GetQzonehistory 数据恢复与青春记忆备份完整指南
下一篇:魔兽争霸III终极优化指南:5分钟解锁高帧率宽屏体验

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询