PHP Security - Combining functionality of strip_ta

2019-08-29 10:57发布

问题:

I want my forum users to be able to insert links and other allowed tags. For example I would like the following HTML in a post to display as the writer intended (i.e. as a functioning link):

<a href="http://www.example.com" rel="nofollow">A page</a>

However, I want to maintain some level of security and have been reading up on strip_tags() and htmlspecialchars(). I thought at first that I could use strip_tags with something like:

<?php $link_string = strip_tags($link_string, '<a>'); ?>

But strip_tags doesn't protect me like htmlspecialchars does if I understand correctly. For example, incorrect HTML code using special characters can leave me vulnerable. And so can the style and onmouseover attributes for the link tag.

What is the most simple solution to allow the above link in the post while cleaning out potentially harmful characters and code? Is there anyway I can combine these two PHP functions to do this in a simple manner?

回答1:

You pretty much need to use a full-featured HTML parser and sanitizer. The overall workflow is the following:

  1. The user enters their HTML
  2. You parse it with the parser
  3. You sanitize what was parsed by keeping only what you want (<a> tags, but be wary of onclick attributes, and similar).

You could look into HTML Purifier, and if it doesn't fit your needs, the HTML Purifier website has a comparison of other PHP sanitizers. I believe the default HTML Purifier configuration will retain links.


Obligatory reference: please refrain from using regex to parse HTML.



回答2:

I would suggest using stripslashes(), and if this is going to a database, also mysql_real_escape_string().

// without SQL.
       function safeData($data) {
        $returnData = stripslashes(strip_tags(htmlspecialchars(trim($data))));
        return $returnData; 
    }

// with SQL.
       function safeDataMySQL($data) {
        $returnData = mysql_real_escape_string(stripslashes(strip_tags(htmlspecialchars(trim($data)))));
        return $returnData; 
    }