2016-05-09 10 views
1

исследуемыми ссылки:Применить htmlentities к раздели теги

How do you apply htmlentities selectively? и PHP function to strip tags, except a list of whitelisted tags and attributes

Они близки, но не как ожидалось.

Что я пробовал?

<?php 
define('CHARSET', 'UTF-8'); 
define('REPLACE_FLAGS', ENT_HTML5); 

function htmlcleaned($string) { 
    $string = htmlentities($string); 
    return str_replace(
    array("&lt;i&gt;", "&lt;b&gt;", "&lt;/i&gt;", "&lt;/b&gt;", "&lt;p&gt;", "&lt;/p&gt;"), 
    array("<i>", "<b>", "</i>", "</b>", "<p>", "</p>"), $string); 
} 

echo htmlcleaned("<p>How are you?</p><p><b>This is bold</b></p><p><i>This is italic</i></p><p><u>This is underline</u></p><p><br></p><ul><li>This is list item 1</li><li>This is list item 2</li></ul><p><br></p><ol><li>This is ordered list item 1</li><li>This is ordered list item 2</li></ol><p><a target='_blank' style='color: #1c5c76;' href='http://www.google.com'>http://www.google.com</a></p><p>This is plain text again.<br></p><script>alert('attempt csrf');</script><p><p>This is P tag example</p></p>"); 
?> 

Что я хочу достичь?

если вход:

<b><script>alert("something");</script></b> 

, то выход будет:

<b>&lt;script&rt;("something");&lt;/script$rt;</b> 

Там нет конкретного черного списка, но есть определенный белый список.

+1

По какой причине вы указали «исследуемые ссылки», если 2-й содержит решение, которое вы можете попробовать адаптировать? –

+0

http://stackoverflow.com/a/36840765/476 – deceze

+0

@MarcinOrlowski Читайте мой вопрос снова, и вы, возможно, знаете :) – Karma

ответ

2

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

function html_entity_decode_matches($matches){ 
    return html_entity_decode($matches[0]); 
} 
function htmlentities_exclude($string, $exclude_array){ 
    $string = htmlentities($string); //htmlentities all 
    $ent_sl = "&gt;"; //> 
    if (is_array($exclude_array) AND !empty($exclude_array)){ 
     foreach($exclude_array as $exc){ 
      $exc = str_replace(array("<", ">"), "", $exc); 
      $ent = str_replace("/", "\/", htmlentities("<{$exc}")); 
      $ent_e = str_replace("/", "\/", htmlentities("</{$exc}>")); 
      //do decode on <tag...> 
      $string = preg_replace_callback("/{$ent}(.*?){$ent_sl}/", "html_entity_decode_matches", $string); 
      //do decode on <\tag> 
      $string = preg_replace_callback("/{$ent_e}/", "html_entity_decode_matches", $string); 
     } 
    } 
    return $string; 
} 

echo htmlentities_exclude('<b><script>alert("something");</script></b>', array("<b>")); 

Output: 
<b>&lt;script&gt;alert(&quot;something&quot;);&lt;/script&gt;</b> 
+0

Я немного подкорректирую его, но да .... логика неоспорима :) Спасибо ... +1 – Karma

1

Вы можете использовать PHP DOM объекты для достижения этой цели, сначала создать элемент (в вашем случае это < б>) и предоставить закодированную строку в качестве тела (внутренний HTML), как показано ниже,

<?php 
     define('CHARSET', 'UTF-8'); 
     define('REPLACE_FLAGS', ENT_HTML5); 
     function htmlcleaned($string) { 
      return str_replace(array("<", ">"), array("&lt;", "&gt;"), $string); 
     } 
     $dom = new DOMDocument('1.0', 'utf-8'); 
     $element = $dom->createElement('b', htmlcleaned('<script>alert("something");</script>')); 
     $dom->appendChild($element); 
     $html = $dom->saveXML(); 
     echo $html; 
    ?> 

Вы можете использовать встроенную функцию вместо создания функции, как это,

<?php 
    define('CHARSET', 'UTF-8'); 
    define('REPLACE_FLAGS', ENT_HTML5); 
    $dom = new DOMDocument('1.0', 'utf-8'); 
    $element = $dom->createElement('b', htmlspecialchars('<script>alert("something");</script>', ENT_NOQUOTES)); 
    $dom->appendChild($element); 
    $html = $dom->saveXML(); 
    echo $html; 
?> 
+0

Хороший ответ .. Однако это больше похоже на дезинфекцию ввода пользователя ... но что, если тэг