Вопрос или проблема
Мне трудно понять, как именно работает этот вид дом-клобы.
Зеленый квадрат в верхней части этого раздела спецификации HTML довольно ясно объясняет, почему я могу получать доступ к элементам HTML как к глобальным переменным в объекте window. Но я не понимаю, почему в Chrome установка атрибута name
для тега переписывает методы JavaScript. Например,
<img name=getElementById>
Я получаю
document.getElementById()
VM5014:1 Uncaught TypeError: document.getElementById is not a function
Может кто-нибудь помочь мне понять, как атрибут name тега img переписывает методы в объекте document?
Спасибо!
Дело в том, что вы смотрите на один и тот же код по-разному до и после атаки:
Если у вас есть:
document.getElementById(id)
Это вызывает getElementById()
на сайте (сравните документацию Mozilla). Это дает вам элемент с конкретным id, если он присутствует.
Но что, если функцию getElementById
можно переписать? Это возможно, если вы создаете HTMLCollection в document
. Вы можете сделать это, используя несколько атрибутов name (сравните DOM-клобы в очищенном MD вызывают ошибки):
<img name="getElementById" src="">
<img name="getElementsByTagName" src="">
После этого document.getElementById()
будет ссылаться ни на что, и сайт может упасть, если эта часто используемая функция будет использована.
Для более глубокого понимания также обратитесь к этому вопросу на Stack Overflow.
Ответ или решение
Понимание методов клонирования DOM в объекте документа
Клонирование DOM (DOM clobbering) — это уязвимость, возникающая в результате неочевидного взаимодействия между свойствами объектов JavaScript и HTML-элементами. Это становится возможным, когда атрибуты элементов HTML перезаписывают существующие методы и свойства объектов в JavaScript, особенно в глобальном контексте, таком как window
. Давайте подробнее рассмотрим, как это происходит, на примере кода и работы с атрибутом name
.
Как это работает?
Когда вы устанавливаете атрибут name
у HTML-элемента:
<img name="getElementById">
Вы создаете новое свойство в объекте window
, поскольку все элементы HTML автоматически становятся свойствами объекта window
. Это означает, что теперь в выбранном вами элементе img
будет доступен атрибут getElementById
, который указывает на этот элемент, а не на оригинальную функцию document.getElementById()
.
Последствия
В результате, когда вы вызываете функцию getElementById
:
document.getElementById('someId');
вы фактически имеете в виду:
window.getElementById('someId');
Так как getElementById
ссылается на ваш элемент img
, вызов прив leads к ошибке:
Uncaught TypeError: document.getElementById is not a function
Это происходит потому, что теперь window.getElementById
указывает на элемент, а не на метод документа, что создаёт потенциальные проблемы в работе сайта, особенно если данный метод используется в коде часто.
Примеры клонирования
Для того чтобы продемонстрировать это явление, вы можете использовать:
<img name="getElementById">
<img name="getElementsByTagName">
С помощью этих строк кода вы создаете не только конфликт с оригинальными методами, но и потенциальные уязвимости в вашем приложении. Например, методу getElementById
больше не удастся выполнить свою задачу, так как он был "перезаписан" на элемент img
.
Почему это важно?
Эта уязвимость особенно опасна в контексте веб-приложений, так как злоумышленники могут использовать клонирование DOM для введения вредоносного кода, создания фишинговых атак или подмены функциональности на сайте. Поэтому важно следить за тем, как вы работаете с динамическими элементами и как атрибуты HTML могут влиять на вашу JavaScript логику.
Заключение
Понимание методов клонирования DOM в объектах документов имеет решающее значение для веб-разработчиков. Это знание не только помогает выявлять ошибки в коде, но и усиливает безопасность веб-приложений. Если вы хотите предотвратить подобные уязвимости, избегайте использования атрибутов name
на элементах, которые могут конфликтовать с методами JavaScript, и всегда проверяйте, что свойства объекта window
не были перезаписаны.
Таким образом, стремитесь использовать уникальные имена для атрибутов HTML и внимательно тестируйте ваше приложение на наличие подобных уязвимостей.