rails:如何以二进制模式打开ENV?

时间:2018-12-16 22:31:58

标签: ruby-on-rails ruby utf-8

有一天,我的应用程序宣布所有密码无效。

经过繁琐的搜索后,发现了问题:通过ENV将密码初始化向量(只是一堆随机位)提供给应用程序。 Rails决定将该字符串(任意二进制数据)转换为UTF-8。

在服务器启动之前,我基本上是在这样做:

ENV["RAILS_ACC_VEC"] = "\xB3n%-\x9E^\xE1\x93 \x17\xEER\x1B\n\x84S"
Rack::Server.start( ...

及以后

  if Rails.env != "production"
    salt = "dummy"
  else
    salt = ENV["RAILS_ACC_VEC"]
  end

位串的长度应为128位。但是它恰好是176位长,包含有效的UTF-8。 (很明显,加密例程确实完全失败了。)

该应用程序当前在Rails 4.2.8和ruby 2.4上运行,并且使用默认编码。

可能会发现问题的原因:通常,应用程序是从服务器启动或从部署启动的,环境中没有语言环境。这次是从控制台启动的,而该控制台恰好设置为ISO 8859。

结果也很清楚:必须注意应用程序始终以ENV中的确定语言环境启动-LC_CTYPE=C(相当于无语言环境),或者-可能更好-UTF-8(如果应用程序具有默认的config.encoding)。

我现在想弄清楚的是,什么时候以及为什么红宝石/铁轨会做这种事情? 我知道IO对象可能会发生转码,但是打开时可以在其中指定预期的字符集。

如果系统似乎在ISO 8859中运行并且rails本身以UTF-8运行,则从某种意义上讲可能是ENV从外到内移动时可能需要转码。但这仅在涉及语言时才适用,并非所有ENV内容都可能是语言。

那么,ENV如何以二进制模式打开?

那么,更雄心勃勃的问题是,使用编码功能是否还会有更多类似的危险危险?

1 个答案:

答案 0 :(得分:2)

您不应在系统环境中存储二进制数据。操作系统并非旨在在其环境中存储二进制数据。我不相信有任何功能可以提供。所有环境变量都应为文本。也许一个操作系统可以在环境中存储二进制数据,但是我不认为这是一个标准。我怀疑它们是否可以存储空字节(\x00)。这可能是操作系统的安全风险,从而导致读取环境的其他程序遭受缓冲区溢出攻击。尝试搜索“ posix env binary”。

每当将IV存储为文本时,都应将其存储为base64编码的数据。

ENV['IV'] = 'VGhpcyBjYW4gYmUgYmluYXJ5Lg=='
export IV=VGhpcyBjYW4gYmUgYmluYXJ5Lg== # or from the shell
...
iv = Base64.decode64 ENV['IV']