Pull to refresh

Rails params & GC

Reading time2 min
Views6.4K
У нас тут в Rails комьюнити опять драма. Первоначальный репорт. Есть методы типа find_by_* которые проецируются на модели в find_by_title например и find_by_id.
Их можно использовать так
find_by_id(params[:id], select: «CUSTOM SQL»)
Но обычно их используют вот так
find_by_id(params[:id])
И происходит SQL Injection если в params[:id] лежит {:select => «CUSTOM SQL»} — опции могут быть и в первом аргументе.

Обратите внимание — :select это символ а не «select»(строка). Это значит что трюк ?id[select]=SQL не пройдет т.к. ключ окажется строкой. И вообще params это хеш типа HashWithIndifferentAccess. Те у него ВПРИНЦИПЕ не может быть символов в ключах т.к. они все уничтожаются при создании.

Есть такой gem authlogic, в общем виде он использует find_by_token(token) где token это объект из сессии(которая хранится в куках и подписана session_secret). Чтобы в него записать :select => «SQL» вам нужно знать session_secret, поэтому уязвимость крайне редкая.
Весь этот SQL Injection CVE не стоит выеденного яйца! И ради чего пост? DoS!

Я лишь начал копать дальше, ибо давно использую альтернативные инпуты. Рельсы по умолчанию принимают три вида request.body: XML, JSON, x-www-form-urlencoded. Абсолютное большинство приложений использует последний, это строка вида key=val&key2=val2 Но если клиент вышлет нужные Content-Type автоматически будет исользован другой парсер — XML/JSON и даже YAML но он выключен по умолчанию.
А XML штука гибкая. Пример — если вы пошлете
<id type="symbol">all</id>

то код find(params[:id]) выполнится так же как и find(:all)
Или
<id type="yaml">---....</id>

Пользовательский инпут превращается в символы — символы не убираются GC-ом. Вот таким скриптом из консоли браузера можно «обижать» рельс приложения(скрипт удалил чтобы скрипткиддисы не использовали). Попробуйте на локалхосте и следите за памятью процесса ruby.

патч для application.rb который выключит альтернативные парсеры
ActionDispatch::ParamsParser::DEFAULT_PARSERS={}

P.S. но и это еще не все(есть возрождение старого CVE с [1, nil] через JSON/XML payload)
Tags:
Hubs:
Total votes 54: ↑42 and ↓12+30
Comments20

Articles