Существует три основных подхода к этой проблеме.
- используйте
h()
в ваших взглядах. Недостатком здесь является то, что если вы забудете, вы получите pwnd.
- Используйте плагин, который экранирует контент при его сохранении. Мой плагин xss_terminate делает это. Тогда вам не нужно использовать
h()
в ваших представлениях (в основном). Есть другие, которые работают на уровне контроллера. Недостатками здесь являются: (а) если в экранирующем коде есть ошибка, вы можете получить XSS в своей базе данных; и (b) Есть угловые случаи, когда вы все еще хотите использовать h()
.
- Используйте плагин, который экранирует контент, когда он отображается. CrossSiteSniper , вероятно, самый известный из них. Это псевдоним ваших атрибутов, так что когда вы вызываете foo.name, он экранирует содержимое. Есть способ обойти это, если вам нужен контент без экранирования. Мне нравится этот плагин, но я не в восторге от того, что XSS впущу в мою базу данных ...
Тогда есть несколько гибридных подходов.
Нет причин, по которым вы не можете использовать xss_terminate и CrossSiteSniper одновременно.
Существует также реализация ERb под названием Erubis , которую можно настроить так, чтобы любой вызов, например <%= foo.name %>
, был экранирован - эквивалент <%= h(foo.name) %>
. К сожалению, Erubis, кажется, всегда отстает от Rails, и поэтому его использование может замедлить вас.
Если вы хотите узнать больше, я написал сообщение в блоге (на которое любезно ссылался Xavor) о с использованием xss_terminate .