Comments 44
Извините, но это всё, что надо знать о вашем шаблонизаторе на данный момент.
Переделывайте архитектуру — все подставляемые переменные должны экранироваться по умолчанию, как минимум.
Но все равно, спасибо за хорошее критическое замечание, правда какое-то категоричное )
Кроме того, вы легко можете это и предотвратить средствами шаблонизатора, добавив обработчик к соответствующей модели.
Неверно (если речь действительно про конкретную модель, а не про включение глобального флага «экранировать всё везде»).
Так можно предотвратить только частный случай, но это не решает проблемы в целом — рано или поздно у вас в проекте окажется какая-то модель, где вы забыли поставить условную галочку «убрать xss» (как в этом примере).
Это та же самая причина, по которой никогда не стоит использовать ручную конкатенацию для построения SQL запросов — люди ошибаются, и в проекте больше хелловорлда у вас с достаточно большой вероятностью будет уязвимость.
Категорично — именно поэтому. Для реальных проектов это нельзя использовать как минимум пока не будет исправлена эта проблема (выше я написал, почему). «На данный момент» — потому что я всё-таки надеюсь, что вы проблему исправите =).
А по поводу архитектуры — в таких случая можно сделать opt-out из автоматического экранирования, например по коду шаблона или по типу передаваемой переменной (по-разному делают).
И да — даже глобальная галочка будет являться проблемой для новичков, если экранирование будет по умолчанию выключено.
В допущении, что фреймворк станет популярным — появятся люди, которые будут забывать её включать в своём проекте и будут наступать на грабли.
Поэтому, пожалуйста, сделайте подстановку значений в шаблон безопасной из коробки =).
ЗЫ
Документацию обновлю позже )
Если вы про https://github.com/DmitryAstafyev/Patterns/commit/3cdd1ba89, то этого будет недостаточно — вы экранируете только <
и >
.
Ничто не мешает <input value="{{value}}" />
превратиться в <input value="" onmouseover="…">
, если я правильно понимаю.
И ещё — этот коммит сломал поля ввода: когда я тут в поле набираю <3
и убираю фокус, видимое содержимое поля превращается в <3
.
Вы точно хорошо подумали над архитектурой?
Экранизацию я как-то из виду упустил. Но это не вопрос архитектуры.
Это вопрос именно архитектуры. Шаблонизатор, работающий строго через DOM в принципе не подвержен этой атаке.
все подставляемые переменные должны экранироваться по умолчанию
Зачем же так строго? Программисты достаточно умны, чтобы понять какие переменные опасны в модели, а какие опасными быть не могут впринципе.
— template helloWorld(name = 'world')
< .hello
Hello {name}!
буээээ
«зацените как мы извращаемся чтобы вывести Hello world! в div»
Да, есть возможность вставки шаблонов в HTML, но опять же и сборка шаблона, и вся работа по его анализу – все на клиенте.
Кроме того, все началось с простой и банальной задачи. Я опишу, если позволите. Было приложение, со множеством разных «окошек» (админка в общем). И там была куча разных контролов. Почти все создавалось на серверной стороне. Потом пришла в голову мысль – а не перенести ли нам все это на клиента – нехай он сам парится, а на сервере все почистить, минимизировать и в идеале оставить только API. Посчитали количество контролов, вышли на несколько десятков очень простых элементов, которые могут работать автономно (то есть не зависят от какой-либо библиотеки и/или фреймвока). Тогда и пришла в голову мысль, а не распихать ли эти контролы по папочкам с JS и CSS, которые к ним относятся. Ну а на клиенте просто их подключать по мере необходимости.
В результате всего этого сервер стал передавать лишь базовую разметку, а вся рутина по рендерингу ушла на клиента вместе с нагрузкой. Мне не удалось, безусловно, превратить серверную часть просто в API сервис, но представлений с серверной стороны было убрано очень много. Ну разве что базовая разметка осталась, как я уже отметил.
Потом была еще пара подобных проектов, где перенос представлений на клиента прошел довольно успешно.
Ну а потом я решил, что пора это все привести в достойный вид (более ли менее) и выложить, может кому и полезным будет.
Иными словами, вот эта штука, которую я тут на ваш суд выставил – это такой инструмент, который позволяет представления вытаскивать с back-end на front-end. И главное, это позволяет проводить отладку каждого шаблона в отрыве от всего проекта. И такого рода инструмент он не универсален, безусловно, он для определенного круга задач.
Автору не надо учить React, вот какое преимущество.
Для меня (я могу судить только по себе :)) главное приимущество: это возможность открывать шаблоны в отрыве от проекта, отлаживать их, править стили. Мне это удобно. Даже если компонент стал сложный, с логикой какой-то, то на создание тестовой страницы (что бы открыть его отдельно) уходит 3-и минуты и все, я снова могу отлаживать копмонент в отрыве от всего приложения.
Ещё замечание: у вас в единственном файле исходника количество строчек почти дошло до 10 тысяч (9820).
Наверное, надо что-то разбить на более мелкие файлы и затем собирать их в один.
То что вы видите на github, да и на промо сайте — это уже результирующий файл.
Ну так выложите на гитхаб реальные исходники и скрипт для сборки из них тогда =).
Просто я искренне полагал (и полагаю), что рабочий «мусор» на паблике ни к чему. Есть файл, есть история с которой видны изменения ну и так далее.
Если вам интересен какой-то отдельный модуль, то просто сверните код до второго уровня вложенности и вы увидите все девять модулей по отдельности. Да и станет очевидным то, как все это собирается.
Поясните, пожалуйста, зачем выкладывать «расковырянную» версию и почему то, что лежит сейчас на github нереальные исходники? )
Исходники — предпочтительная для внесения изменений форма программы. Вам же самому удобнее вносить изменения в «расковыренную» версию, а эту вы собираете (или я не так понял?). Остальные люди тоже обычно не любят ковырять файлы на 10 тысяч строк, а разбивают на более мелкие куски.
Следовательно, исходники — именно «расковырянная» версия.
Edit: промазал с ответом, извините. Переношу на нужный уровень.
<pattern src="/patterns/popup/pattern.html" style="display:none;">
Я не понял, а чем плох тег template?
https://developer.mozilla.org/en/docs/Web/HTML/Element/template
Тем, что автор последние пять лет просидел в танке и не знает про существующие решения.
Потому что тег TEMPLATE часть стандарта, а мне не хотелось свое «нестандартное» решение смешивать со стандартами. Однако в patterns предусмотрена простая возможность переопределения корневого тега шаблона.
«DOM. {{$name_of_reference}}. Указав с помощью этой метки на узел, вы получите возможность очень быстро обращаться к данному узлу, изменять его, прикреплять события и делать прочие рутинные вещи.»
Особенно при работе с DOM.
Из всего спектра комментариев лишь одно дельное замечание, про экранирование (упущенное из виду). Спасибо.
На все остальное (там, где я проигнорировал) я могу ответить парой абзацев, потому как обсуждать, например, то, как проект выложен на github’е я смысла не вижу.
Я писал свое решение, не потому что других решений не существует, а потому что хотел разобраться как это работает. Для меня это здоровая (от слова здоровье) мотивация разработчика. И если собственник проекта не против экспериментов, то для программиста – это находка и глупость упускать подобный шанс; шанс понять, как оно работает изнутри; шанс проверить себя – смогу / не смогу сделать работящее самостоятельное решение. Не пригодится в будущем? Возможно. Кому-то не понравится? Конечно! Но, хвала Зевсу, для меня это не главное и практически не важно.
Видимо часть людей просто стала забывать, что разработка – это прежде всего творчество, искусство, возможность дать своей мысли форму. По крайне мере для меня – это именно так и именно по этой причине я пришел в эту профессию. Поэтому что я могу сказать? «Велосипедил» и буду «велосипедить» дальше, даже несмотря на то, что рядом лежит ReactJS, AngularJS, Jade, EJS и прочие тысячи инструментов.
Еще раз спасибо за Ваше время.
Гораздо логичнее рендерить класическим способом на сервере, пользуясь копеечной стоимостью облачных решений.
А если уже делать это на клиенте то гораздо эффективнее затащить всю разметку одним запросом — а там и старый добрый Mustache (с декларативной, кстати, разметкой без всяких for и if else) вполне справится.
Чуть выше в комментарии я рассказал с чего все началось (как этот шаблонизатор был выделен в отдельное решение). Оба тех проекта, где всецело применено это решение – это админки. То есть по существу – это одинаковый набор элементов управления, где разница есть в их компоновке и данных. В такой ситуации перенос представлений на клиента дал хороший результат. Первая загрузка подольше будет, зато вторая и последующие ощутимо шустрее. В свою очередь разбиение разметки на компоненты дало возможность их отладки в отрыве от приложения, что было очень удобным. Кроме того, после реализации первого проекта к началу работы над вторым уже была хорошая коллекция контролов, которые просто брали и использовали.
Таким образом, идея переноса представлений на клиента состояла в том, чтобы очень большую часть разметки, банально повторяющуюся от страницы к странице перенести на клиента. Перенеся все это на клиента, уменьшили отклик от сервера. А разбив все по элементам управления добились переносимости между подобными проектами.
Требования к мобильным устройствам в данных проектах практически не выставлялись, хотя и на них работает (но не тестировалось так глубоко и основательно, как десктоп).
Посмотрите на доступе hiccup
github.com/weavejester/hiccup
— В чем его плюсы. Фантастическая композабельность. Решение с вечными скобочками через paredit
Front-end шаблонизатор