I am creating a forum to which I only want img tags to be displayed and all other tags to be securely escaped, but not deleted. What is the best method to accomplish this task other than creating a function from scratch?
I have tried using HTML Purifier, but it strips all the unwanted tags and only keeps the desired ones. Furthermore, I tried other functions such as strip_tags and htmlentities
and also the escape operator used in blaede ( {{ }}
) but these functions will either strip the unwanted tags (which I want them to be escaped instead) or escape all the tags (which I also don't want to because I want to keep the <img>
and <br>
tags. I seen other similar asked questions, but none of them really helped me unfortunately.
So far what I do is using: $post->content = Purifier::clean($request->content);
To remove the unwanted tags temporary to prevent XSS.
I expect after the data the user has inserted to be displayed like the following:
Hi all
<script>alert('hi all')</script>
<img src='sun.png'/>
While now the following is being displayed
Hi all
hi all
<img src='sun.png'/>
UPDATE:
My question is not duplicated to the question which was marked. Hopefully a moderator will resolve this.
You need to replace <img>
and <br>
tags with some string placeholders first, do the escaping with htmlentities()
and then restore original <img>
and <br>
tags back. Here's how you can do the trick:
$string = "Hi<br> all<script>alert('hi all')</script><img src='sun.png'/>";
// First we cleanup our string from possible pre-existing placeholders (like $$0, $$1 etc).
$string = preg_replace('~\$\$[0-9]+~', '', $string);
// Then we replace all <img> and <br> tags with such placeholders while
// storing them into $placeholders array.
$placeholders = [];
$i = 0;
$string = preg_replace_callback('~(<img[^>]*>(</img>)?|<br[^>]*>)~', function ($matches) use (&$placeholders, &$i) {
$key = '$$'.$i++;
$placeholders[$key] = $matches[0];
return $key;
}, $string);
// Our string no longer has <img> and <br> tags so we can safely escape
// the rest.
$string = htmlentities($string);
// Lastly we restore <img> and <br> tags by swapping them back instead of their respective placeholders.
foreach ($placeholders as $key => $placeholder) {
$string = str_replace($key, $placeholder, $string);
}
echo $string;
This code will produce the result:
Hi<br> all<script>alert('hi all')</script><img src='sun.png'/>
This solution heavily relies on using regular expressions, so I highly advise you learning on this topic in case later on you will have a need to tweak the code.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.