Опасности использования open-uri

OpenURI в руби это стандартная библиотека сильно упрощающая работу с URL так как она объеденяет в себе Net: HTTP/HTTPS/FTP и представляет из себя всего лишь метод open. Насколько я знаю это самый популярный способ для скачивания файла, GET запроса или чтения данных.Но на деле 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).

Мои прошлые размышления о проблеме магии в рельсах.

© Habrahabr.ru