Однажды мое приложение объявило все пароли недействительными.
После утомительного поиска была обнаружена проблема: вектор инициализации шифра (просто набор случайных битов) передается приложению через 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
).
То, что я сейчас пытаюсь выяснить, это когдаи почему ruby / rails делает такие вещи?Я знаю, что транскодирование может происходить с объектом ввода-вывода, но там может быть указана предполагаемая кодировка при открытии.
Может иметь смысл, если система работает в ISO 8859, а сама rails работает с UTF-8, что ENV при перемещении снаружи внутрь может нуждаться в транскодировании.Но это справедливо только в том случае, если речь идет о языке, и не весь контент ENV может быть языком.
Итак, как ENV открывается в двоичном режиме?
Чем больше амбициозный вопрос, так этоЕсть больше злых опасностей такого рода с функцией кодирования?