Как удалить внутренний HTML из разобранного HTML с помощью DOMDocument? - PullRequest
0 голосов
/ 10 июля 2019

Мне нужно обработать предоставленную пользователем разметку для конкретного типа встраивания, который обычно имеет форму тега <script>, обычно с атрибутом src. Существует множество различных <script> компонентов, которые можно использовать здесь, каждый из которых отличается. Однако, чтобы избежать возможных атак XSS, мы сочли необходимым удалить что-либо внутри тега.

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js">document.write("vinny say something funny"); //This should be sanitized out</script>

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

Ответы [ 2 ]

1 голос
/ 10 июля 2019

Этот код удаляет дочерние узлы из узла <script>.В данном случае это элемент документа:

<?php
$xml = '<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js">document.write("vinny say something funny");</script>';                               

$doc = new DOMDocument();
$doc->loadXml($xml);

$scriptNode = $doc->documentElement;

while ($scriptNode->hasChildNodes()) {
    $scriptNode->removeChild($scriptNode->lastChild);
}

echo $doc->saveXML();

Вывод:

<?xml version="1.0"?>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"/>
0 голосов
/ 10 июля 2019

Как простой метод - сделать мелкое клонирование узла (используя cloneNode()) без необязательного параметра.

Это будет проходить через загруженный документ и заменять каждый скриптузел с новым контентом ...

$html = '<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js">document.write("vinny say something funny");</script>';

$doc = new DOMDocument();
$doc->loadHTML($html);

foreach ( $doc->getElementsByTagName("script") as $script ){
    $script->parentNode->replaceChild($script->cloneNode(), $script);
}
echo $doc->saveHTML();

дает ...

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><head><script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script></head></html>
...