Automatically closing tags

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

Post Reply
fragmer
Forum Newbie
Posts: 2
Joined: Mon Jun 26, 2006 8:36 pm

Automatically closing tags

Post by fragmer »

Hello; I'm creating a guestbook-like system for my site, and so far I had no trouble creating code to prevent various injections. But there are is one problem that I don't know how to approach: unclosed tags. I know that phpBB does it with javascript; is there an efficient way of implementing this in server-side PHP? I'm allowing simple <b/i/u/s/code> tags only by converting them to phpBB-style square brackets tags.

Edit: the best I could come up with is

Code: Select all

$txt = trim($_POST["txt"]); // message text

$pat = array(); $rep = array();

$pat[0] = '/((http|https|ftp|mailto|steam):\/\/\S*?)(\s|$)/i'; // find URLs with protocols
$rep[0] = '[url]$1[/url]$3';

$pat[1] = '/(www\.\S*?)(\s|$)/i'; // find URL's starting with "www."
$rep[1] = '[url]http://$1[/url]$2';
	// 
$pat[2] = '/<(\/?[buis])>/i';	// allowed tags: <b>, <u>, <i>, <s>
$rep[2] = '[$1]';

$pat[3] = '/<(\/?code)>/i';	// allowed tag: <code>
$rep[3] = '

Code: Select all

';

$txt = strip_tags( preg_replace( $pat, $rep, $txt ) );

$tags = array( "url", "b", "u", "i", "s", "code" );
foreach( $tags as $tag ){
	// if more tags of one kind are opened then closed,
	// append the missing closing tags in the very end
	while( substr_count( $txt, "[$tag]" ) > substr_count( $txt, "[/$tag]" ) ){
		$txt.= "[/$tag]";
	}
}

$txt = mysql_real_escape_string( htmlspecialchars( $txt ) ); // final precautions before sending off to SQL
I don't know how well does this protect from HTML/CSS/JS evilness though.
Last edited by fragmer on Tue Jun 27, 2006 2:44 am, edited 1 time in total.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

Without getting to wrapped up into it, I would guess that you would regex search the post data and look for all open tags that do not have a match. For those, add the closing matched tag when the data is posted. I know this seems so unhelpful, but I am hoping one of the regex gurus can pick this up and carry on with it.
Robert Plank
Forum Contributor
Posts: 110
Joined: Sun Dec 26, 2004 9:04 pm
Contact:

Post by Robert Plank »

I don't know how well does this protect from HTML/CSS/JS evilness though.
Oh, so you also want to remove attributes from the tags also, onclick and style and all that?
fragmer
Forum Newbie
Posts: 2
Joined: Mon Jun 26, 2006 8:36 pm

Post by fragmer »

Yes, that, and also make sure that if comment poster forgets to close a tag (like <code>), it does not affect anything on the page. Basically, make sure all tags are closed. Note that I first convert selected tags (b,u,i,s,code) to have [square brackets], then use PHP's strip_tags() to remove all other tags. I was wondering if there's some software that would elegantly (XHTML-compliantly) close any open tags in the correct order.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Yep, I'm working on it, but it's not finished yet. If you're using BBCode, I strongly recommend you use a prewritten class (like PEAR) because you're bound to miss something unless you go hardcore.
Post Reply