protect_from_forgery не защищает PUT / DELETE запросы - PullRequest
1 голос
/ 02 апреля 2011

Я сделал демонстрационное приложение с rails new demo, а затем сгенерировал пользовательский контроллер в скаффолде с rails generate scaffold User name:string email:string.Код скаффолда имеет ApplicationController с protect_from_forgery, так же как и UserController, который происходит от ApplicationController.

Я запускаю webrick, добавляю пользователя, круто.Токен подлинности работает, как и было обещано с помощью POST на / users.

И все же с Rails 3.0.5 я могу сделать:

niedakh@twettek-laptop:~$ telnet 10.0.0.4 3000
PUT /users/3 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 39

user[name]=vvvvv&user[email]=shiaus.pl

И изменить пользователя 3 без указания токена:

Started PUT "/users/3" for 10.0.0.4 at 2011-04-02 14:51:24 +0200
  Processing by UsersController#update as HTML
  Parameters: {"user"=>{"name"=>"vvvvv", "email"=>"shiaus.pl\r"}, "id"=>"3"}
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 3 LIMIT 1
', "updated_at" = '2011-04-02 12:51:24.437267' WHERE "users"."id" = 3s.pl
Redirected to http://10.0.0.4:3000/users/3
Completed 302 Found in 92ms

ТакжеЯ могу сделать то же самое с DELETE:

DELETE /users/3 HTTP/1.1

Что дает мне:

Started DELETE "/users/3" for 10.0.0.4 at 2011-04-02 15:43:30 +0200
  Processing by UsersController#destroy as HTML
  Parameters: {"id"=>"3"}
  SQL (0.7ms)   SELECT name
 FROM sqlite_master
 WHERE type = 'table' AND NOT name = 'sqlite_sequence'

  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 3 LIMIT 1
  AREL (0.5ms)  DELETE FROM "users" WHERE "users"."id" = 3

Redirected to http://10.0.0.4:3000/users
Completed 302 Found in 180ms

Не могли бы вы объяснить мне, почему я могу делать такие вещи, когда я никогда не отправляю токен вместе с этими запросами?

1 Ответ

10 голосов
/ 09 апреля 2011

Очень короткая версия : protect_from_forgery предназначена для защиты от XSRF-атак от поддельных элементов HTML FORM. PUT и DELETE не уязвимы для атак XSRF, потому что HTML-формы не могут использовать PUT или DELETE.

Атака XSRF (подделка межсайтовых запросов) - это когда браузер жертвы обманным путем отправляет поддельный запрос на сервер без взаимодействия с пользователем.

Более длинная версия : причина, по которой вы можете сделать это, вы либо:

  • Не требуется безопасность / логин или
  • Уже вошли в систему и делаете запросы от скрипта, размещенного в том же домене, или
  • Делать запросы через Fiddler или аналогичные (в обход встроенной защиты браузера).

Это не сценарий protect_from_forgery предназначен для защиты от

.

Цель protect_from_forgery - защита от атак XSRF - подделка межсайтовых запросов. Это происходит, когда пользователь, посещающий злой сайт (или хороший сайт с добавленным злом), вынужден отправить запрос на другой сайт. Например, вы можете заставить посетителя сделать любой запрос GET, например:

<img src="http://victim.com/victimPage?action=delete&id=ID12345" />

Как только жертва заходит на злой сайт, его браузер автоматически попытается получить изображение. Это, очевидно, не будет извлекать изображение, но пока жертва выполнит запрос на удаление элемента ID12345. POST может быть подделан аналогичным образом, просто создайте форму и отправьте ее на иностранный сайт с помощью скрипта, либо обманом заставьте пользователя щелкнуть по нему для отправки.

Вот тут и приходит protect_from_forgery: сервер отправляет токен клиенту в скрытом поле с формой. Если действительный токен не появляется, сервер приходит к выводу, что отправленная форма не является отправкой подлинной формы, отправленной сервером, поэтому запрос отклоняется как потенциально подделанный.

Но вы знали это.

Дело в том, что формы HTTP могут использовать только методы GET и POST, а не PUT или DELETE. Это имеет два эффекта:

  • Во-первых, если вы получаете PUT или DELETE, поставить токен protect_from_forgery некуда. PUT или DELETE не являются результатом отправки формы, поэтому сервер не может отправить токен клиенту, поэтому у клиента нет токена для отправки обратно.
  • Во-вторых, поскольку HTML-формы могут использовать только POST и GET, если запрос представляет собой PUT или DELETE, злоумышленник не может использовать HTML-форму, чтобы заставить или заставить пользователя отправить запрос. Они могут использовать XMLHttpRequest, но XMLHttpRequest не разрешает межсайтовые запросы (если это не разрешено настройками безопасности на обоих сайтах).

Это означает, что, если домен, на котором вы его размещаете, не содержит самого вредоносного кода, нет необходимости защищать PUT и DELETE от подделки. Если сервер содержит злой код, злоумышленник может сделать произвольные запросы XMLHttpRequest для получения действительного токена и, следовательно, легко обойти защиту от подделки.

Для быстрого описания XSRF попробуйте здесь:

...