2015-08-31 3 views
1

Это то, что происходит в rails console (Rails v4.0.4):Rails, почему '.to_json' является выделяющимся HTML сущность

irb(main):020:0> "pepe&pepe <juan>".to_json 
=> "\"pepe\\u0026pepe \\u003Cjuan\\u003E\"" 

Это то, что происходит в irb console (Рубин 2.0.0p247):

irb(main):014:0> "pepe&pepe <juan>".to_json 
=> "\"pepe&pepe <juan>\"" 

Я знаю, что я могу изменить это поведение, но мое беспокойство почему Rails делает это по умолчанию? что может быть следствием не делать этого ?, потому что для меня это выглядит хорошей идеей, чтобы переопределить это поведение, а не избегать html-сущностей, но я уверен, что что-то не хватает.

ответ

3

JSON написан на HTML-контексты - скрипты и атрибуты - много в Rails.

Это по умолчанию побега избегает инъекции в таких случаях: символов, которые имеют смысл в определенном контексте и не сбежавшие представляют собой/XSS риск инъекции.

Если, и только тогда, когда дело в контексте, где такое не так, то его можно смело отключить: по умолчанию просто в пользу «безопасность». Поскольку этот HTML-безопасное преобразование может быть сделан без нарушения какого-либо стандарта и без Цепочки JSON-Equivalency это то, что рассверлить рейл сделал - хорошо для них!

В частности, это позволяет избежать неприятную 'JSON' как:

var x = {"foo": "</script><script>alert('owned')</script>"}; 

JSON встраивается в другие HTML-конструкций, например. атрибуты данных также могут быть проблематичными. Даже с использованием JSON.parse, что потребует дополнительного шага кодирования, оставляет ту же потенциальную проблему.


стандартные методы вывода безопасные кодированный применяются к HTML-PCDATA контекстах, но в случае излучающих JSON к элементу скрипта (CDATA) это не желательно и целенаправленно пропущен (например. С raw) ,

Вот another answer of mine где я писал о том, почему такое Экранирование всегда действует, а также предостережение, используя JSON как JavaScript литерал. В отличие от пресловутой и плохо разработанной «добавленной косой черты», безопасный для HTML JSON представляет собой идентичную информацию.

JavaScriptSerializer от Microsoft и json_encode в PHP имеет аналогичное поведение по умолчанию. Контекст по умолчанию, в котором используются эти библиотеки/функции, вероятно, играет большую роль в конфигурациях с безопасным HTML-кодом по умолчанию.

+0

Я очень ценю и принимаю расширенный ответ, который вы предложили. Но я не могу согласиться с высокомерием Rails в этом отношении. Эта перезапись '.to_json' добавила проблемы в общую библиотеку, загружаемую в тот же контекст приложения Rails.Приложение Rails решает, что стандартный способ Ruby для разбора объектов на _json_ теперь изменится и поэтому он изменится на любую библиотеку, загруженную Rails: /. Я принимаю переписывание стандартных методов, это хорошая идея и очень полезно, но я думаю, что первоначальное поведение должно оставаться дефолтным. – fguillen

+1

@fguillen JavaScriptSerializer от Microsoft и json_encode от PHP оба придерживаются аналогичной HTML-безопасной кодировки по умолчанию. Синус закодированный JSON эквивалентен, но не текстовый контент равен *, который никогда не был гарантирован * - У меня нет проблемы с преобразованием. В любом случае такие проблемы будут лучше ориентированы на соответствующий проект дома/списка рассылки. – user2864740

+0

@fguillen: Но '' \ u003C "' * является * '" <"' как в JSON, так и в JavaScript. Никакой совместимый декодер JSON не должен заботиться о разнице, потому что на самом деле нет никакой разницы. Да, Rails имеет тенденцию быть высокомерным, свинговым и самоуверенным, но на этот раз они действительно не так уж плохи, они все еще производят полностью совместимый JSON. –