Новый синтаксис <%: %> для HTML-кодирования в ASP.NET 4 и ASP.NET MVC 2

Автор оригинала: Scott Gu
  • Перевод
image
Это девятнадцатая статья из серии, посвященной выходу VS 2010 и .NET4.

Сегодняшний пост охватывает маленькую, но очень полезную возможность, новый функционал синтаксиса, представленный в ASP.NET 4, позволяет автоматически кодировать HTML прямо в блоке кода.

Кодирование HTML


Межсайтовый скриптинг (XSS) и атаки по слабому HTML-кодированию являются двумя самыми распространенными проблемами безопасности, которые досаждают веб-сайтам и приложениям. Они происходят, когда хакеры находят способ внедрить клиентский скрипт, который крадет данные cookie-файлов или используют личность пользователя на сайте для нанесения вреда.

Единственный способ устранить межсайтовые атаки – быть уверенным, что все на выходе HTML-закодировано. Все это дает уверенность, что содержимое введенное или отданное пользователю, не может быть возвращено с такими тегами, как <script> и <img>.

Как происходи HTML-кодирование в наши дни

ASP.NET приложения (особенно те, которые использую ASP.NET MVC) часто полагаются на выражение в блоке кода <%= %>. Сегодня, разработчики чаще всего используют вспомогательные методы Server.HtmlEncode() или HttpUtility.Encode() для кодирования HTML до его вывода на экран. Вот вам пример кода:

image

Код будет работать без проблем, но всегда есть “но”:
  1. Выражение многословно
  2. Разработчики частенько забывают вызвать метод Server.HtmlEncode и не существует простого способа убедиться, что кодирование использовано.

Новый блок кода <%: %>


C ASP.NET 4 мы представляем новое выражение кода (<%:  %>), которое работает, как и блок <%= %>, но дополнительно автоматически кодирует HTML. Новый блок устраняет надобность явно HTML-кодировать содержимое, как мы это проделали в примере выше. Вместо этого вы просто пишете сжатый код, как показано ниже:

image

Мы выбрали синтаксис <%: %>, так что будет достаточно просто заменить существующие экземпляры блоков кода <%= %>.

Избегаем повторного кодирования


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

ASP.NET 4 представляет новый интерфейс IHtmlString (наряду с конкретной реализацией: HtmlString), который вы можете реализовать над типами, определяя было ли закодировано значение для отображения, как HTML, а следовательно значение не должно быть повторно HTML-кодировано. Блок кода <%: %> проверяет присутствие  интерфейса IHtmlString и не будет повторно HTML-кодировать результат, если значение реализует этот интерфейс. Что позволяет разработчикам избежать проблемы выбора, что использовать <%= %> или <%: %>.

Используем HTML-вспомогательные методы ASP.NET MVC с <%: %>

Сейчас я хочу показать практическое применение HTML-кодирования, рассмотрим сценарий, где вы используете HTML-вспомогательные методы в ASP.NET MVC. Данные методы чаще всего возвращают HTML. Например, вспомогательный метод Html.TextBox() возвращает следующую разметку <input type=”text”/>. В ASP.NET MVC 2 данные вспомогательные методы стали по умолчанию возвращать HtmlString, которое указывает, что возвращаемое содержимое безопасное для отрисовки и не должно быть кодировано в <%: %>

Это позволяет вам использовать методы одинаково, как в <%= %>:

image

Так и в блоке <%: %>:

image

В любом случае HTML-содержимое возвращенное вспомогательным методом будет отрисовано на клиенте, как HTML и <%: %> не будет повторно его кодировать.

Если вы же реальный хардкорщик, то у вас есть возможность создать правило сборки, которое ищет в вашем приложении места использования <%= %> и помечает их, как ошибки, тем самым принудительно заставляя использовать HTML-кодирование.

Скаффолдинг в ASP.NET MVC 2 представлениях


Когда вы используете VS 2010 (или бесплатную Web Developer 2010 Express) для построения ASP.NET MVC 2 приложений, то обнаружите, что представления, сгенерированные  с помощью “Add View”, по умолчанию используют <%: %> для текстовых меток, полей и сообщений об ошибках (все, что выводится с помощью HTML-вспомогательных методов):

image

Итоги


Новый <%: %> синтаксис предоставляет компактный вариант автоматического HTML-кодирования содержимого и вывода на экран. Он позволяет сделать код менее многословным и быть уверенным, что все данные проходящие через ваш сайт HTML-кодированы. Все это позволит защитить ваше приложение от XSS и HTML инъекций.

Средняя зарплата в IT

113 000 ₽/мес.
Средняя зарплата по всем IT-специализациям на основании 5 381 анкеты, за 2-ое пол. 2020 года Узнать свою зарплату
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 45

    0
    не прошло и года :)
      –1
      Не прошло и пятнадцати лет (с момента появления asp) ;)
    • НЛО прилетело и опубликовало эту надпись здесь
        +8
        Как сказать, тут аж три «но»
        1.Использование коротких тегов является плохой практикой и их можно отключить (даже нечаянно)
        2.В PHP6 все короткие теги будут удалены.
        3.Он не делает никакого HTML-кодирования.
          –1
          > В PHP6 все короткие теги будут удалены.
          А можно пруф? Вроде как только ASP-like-тэги собирались убрать.
            0
            Да asp-like уберут, про short tags что-то я не могу найти ссылку на исходное сообщение, только на блогах людей.
            –2
            1. Ложь.
            2. Ложь.

            Возможно по пункту 2 вы имеете ввиду asp-теги, но снова ложь: их тоже не уберут. Хотя хотели убрать. Но передумали.
              +1
              1.Я знаю о чем говорю, я разрабатываю на php, короткие теги <? считаются дурным тоном, не нужно строить для себя иллюзий «мне нравится, значит можно».Zend Coding Standard
              PHP-код должен всегда обрамлятся полными PHP-тегами:
              <?php

              ?>

              Короткие теги не допустимы.

              2.PHP6 порос мхом, столько слухов о нем, что следить нет смысла, все равно релиза нет и когда будет не известно
                –1
                1. Это рекомендации лишь для конкретного фреймворка. Многие пункты отличаются от гайдлайна PHP.
                Более того, в Zend_View есть даже специальная приблуда, преобразующая короткие теги при отключенной опции в настройках.

                2. Скачайте текущий релиз и посмотрите. Он наиболее точног отражает положение дел.
            +2
            вы не поняли чем отличается <%: %> от <%= %>

            а <%= %> было еще в ASP
            • НЛО прилетело и опубликовало эту надпись здесь
                0
                Снимаю с тебя заклятие! Ибо такая редкость, когда человек признает свою ошибку :-)
                • НЛО прилетело и опубликовало эту надпись здесь
          • НЛО прилетело и опубликовало эту надпись здесь
            • НЛО прилетело и опубликовало эту надпись здесь
              –14
              Статья для Хабра, Microsoft way. Тьфу.
                +2
                Конечно, когда в python или ruby придумают новую фичу, никто об этом рассказывать не будет. Вообще зачем разработчикам рассказывать, что нового в продуктах? В статье даже никто не говорил «уникальная функция», я бы на вашем месте просто подумал прежде, чем писать. Здесь не фанаты собрались МС, а разработчики, в отличии от вас, фаната линукса
                  –5
                  Я за разумный прогресс всего и вся, но зачем код картинками показывать?
                    –1
                    Ну я уж не знаю, спросите Скотта Гатри…
                      +1
                      Это не тот код, который нужно копировать и вставлять. Он сделать как иллюстрация.
                        –1
                        Я бы предпочел самостоятельно решать, любоваться мне на код или скопировать/вставить.
                      –1
                      Фанаты не фанаты, но
                      1) очень многие ASP.NET разработчики мало знают что такое HTML, а вы про XSS :)
                      2) каждый разработчик по-разному выполняет методику, о которой вы расказываете.
                      3) и главное — все-таки мне лично кажется что с точки зрения ООП все эти кодирования, перекодирования, а еще обработки переносов и другие операции надо выполнять на уровне пропертей(get), хотя каждый пляшет как хочет.
                        0
                        Не перегибайте.
                        В любой веб разработке в какой-то момент нужно будет посмотреть на html код. И это становится нужным очень скоро, какой бы высокоуровневый инструмент вы бы не использовали.

                        А то, что Web Forms позволяет быстро собирать стандартные front-end к базе данных, не обращаясь к html — это только плюс.
                          –1
                          Если вы про пункт 1 — то я не перегибаю, а констатирую факт из своего опыта руководителя и то, что я видел в веб-разработке на ASP.NET в немалом кол-ве мест. Большинство аспнет программистов считает себя программистами, которым до уровня HTML опускаться — это же моветон по их мнению :)
                          Заметьте — я не говорю про всех! а про процентво 80!

                          Я говорю, про то — что новая конструкция от МС — очередной пример для книг, а в реальности — это как правило зашивают в BL (или у кого как называется).

                          Вообще п.1 отдельная тема — про квалификацию современных разработчиков, методики пропагандируемые МС, подход бизнеса к разработке и готовым решениям.

                          ЗЫ: плюс для чего? для быстроразработки и показа макету клиенту — да :) только после таких разработок все работает для двух юзеров, а когда приходит третий — все валится, как это обычно бывает со всем — что написано в книжках у МС в качестве примера.
                            0
                            Я тоже не люблю HTML. Мне лучше всего писать логику программы, javascript, чем разбираться с html и css и выяснять а почему там поплыла верстка. Пускай будет работа и у верстальщиков тоже :)
                        +1
                        > Конечно, когда в python или ruby придумают новую фичу, никто об этом рассказывать не будет.

                        А как же OpenNet?
                      0
                      Может кто объяснить, чем отличается <%= %> от <% %>?
                        0
                        <%= "Hello World!" %> — это <% Response.Write("Hello World!") %>
                          0
                          Т.е. с "=" это специализированный тег для текста, как ":" для кодирования?
                            0
                            Вам дали исчерпывающее определение.

                            «Тип выражения», если так можно выразиться, для первого — string. А для второго — void.
                            0
                            <%= varOrMethod %> — что-то типа препрцессора, вставляет в респонз значение переменной или значение, которе вернёт метод
                            <% %> — можно сипользовать, если есть нужна смещать html-код и логику. Например:

                             
                            <% if (someBoolFlag) {%>
                            someBoolFlag  = <b>True</b> 
                            <%} else {%>
                            someBoolFlag = <b>False</b> 
                            <%}%>
                            


                            а есть еще и <%# %> :-)
                              0
                              А как же <%@ %> =)
                                0
                                а еще :)
                                  0
                                  <%-- --%>
                                  парсер, блин :)
                                  а что делает <%# %>?
                                    0
                                    это Binding
                            –1
                            костыли плодятся и размножаются х)
                              0
                              Приходит Мулла Насреддин к соседу и просит у него кастрюлю:
                              — Слушай, сосед, у меня гости завтра придут, дай взаймы кастрюлю побольше на пару дней.
                              Сосед дал. Через несколько дней Мулла Насреддин приносит соседу его большую кастрюлю и еще вдобавок маленькую:
                              — Вот, твоя кастрюля родила за это время!
                              Сосед удивился сильно, но ничего не сказал, взял и маленькую кастрюлю. Проходит время, и Мулла Насреддин снова приходит к соседу:
                              — Дай еще раз кастрюлю, снова гости будут.
                              Сосед пошел, достал свою самую большую кастрюлю и дал ее Мулле.
                              Проходит несколько дней, Мулла не появляется. Сосед думает: «Большая кастрюля, долго рожает, наверное…» Проходит еще неделя. Забеспокоился сосед и пошел сам к Мулле.
                              — Мулла, послушай, дай мою кастрюлю, а то у меня тоже гости на днях будут.
                              Мулла отвечает:
                              — А ее нет… Она умерла.
                              — Как умерла?! Как кастрюля может умереть?! – опешил сосед.
                              А Мулла как ни в чем ни бывало:
                              — Рожать может, а умереть не может?!
                                –1
                                да когда ж они наконец помрут-то? х)
                                  0
                                  Никогда, потому что это не костыли, а удобный и лаконичный синтаксис.
                                    0
                                    о да, очень лаконичный х))

                                    <a href="<%: model.link %>">click me</a>
                                      0
                                      Ссылки должны генерироваться html-хелперами, а не руками
                                      з.ы. в php никто еще от такого не умер
                                        0
                                        ссылки как и вся остальная вёрстка должны находиться в шаблонах, а не быть размазанными по «html-хелперам»

                                        а ты думаешь для пхп столько шаблонизаторов написано от хорошей жизни? х)
                                        0
                                        Вы можете записать это еще короче, не потеряв при этом гибкость?
                                          0
                                          конечно <a href="{model.link}">click me</a>
                                0
                                В нашем шаблонизаторе эта фича существует с 2-го мая 2001 года. Между прочим, с моей точки зрения это достаточно критическая фича: игнорирование лени разработчиков ведёт к тому, что почти на всех сайтах кучи XSS-дыр. Явно вызывать функции экранирования для каждой выводимой в шаблоне переменной — лениво всем. С другой стороны, использование разных placeholder-ов для вывода экранированных и не экранированных данных сильно облегчает аудит кода при поиске тех же XSS.

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                Самое читаемое