Но на деле require "open-uri"
патчит Kernel.open и вызывает разный код для разных аргументов, что может привести к удаленному выполнению кода или чтению любого файла на сервере!
open(params[:url])
это выполнение кода для url=|ls
Все что начинается с | рассматривается как системный вызов.
open(params[:url]) if params[:url] =~ /^http://
не лучше для url=|touch n;\nhttp://url.com
(сломанные регулярки могут привести к RCE, используйте \A\z).
open(URI(params[:url]))
читает любой файл на сервере. url=/etc/passwd это валидный URL но open-uri вызывает оригинальный Kernel.open так как аргумент не начинается с http://
open-uri это отличная демонстрация как Ruby создает проблемы на пустом месте — патчит критический системный метод только чтобы читать внешние URL которые скорее всего содержат юзер инпут. И никого об этом не предупреждает, как Rails когда то шли с XML парсером по умолчанию что привело к RCE на абсолютно всех рельс сайтах.
Еще пример: open(params[:url]) if URI(params[:url]).scheme == 'http'
. Выглядит уже лучше, но если получится создать папку http: атакующий сможет прочитать любой файл с помощью http:/../../../../../etc/passwd
(привет, CarrierWave!). Конечно, маловероятно что такую папку получится создать но это хорошая демонстрация почему парсить URL сложно и какой плохой идеей было расширять системный метод open вместо создания отдельного openURI(url).
Мои прошлые размышления о проблеме магии в рельсах.
This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.
Комментариев нет:
Отправить комментарий