Jump to content

XSS vulnerability when user logged in (htmlentities)


r0b

Recommended Posts

I have a problem which I've been trying to fix for a while now with htmlentities.

 

I've written my own small cms which is available for the public, and recently I recieved a report that it's vulnerable to an XSS attack:

 

http://host/editText.php?fieldname=slogan&content=slogan<img src=x onerror=alert("XSS")>

This vulnerability only works if the user is logged in. I want to secure it anyway to give the security companies contacting me about this a break.

 

I've been rolling around the internet trying to find a simple answer how to prevent this XSS attack with HTMLENTITIES.

 

I've even tried writing my own solutions with the htmlentities and it doesn't seem to solve the problem/stop the attack.

 

I'm thinking something like

htmlEntities($content); //but again, this won't do the job.

 

Here's the editText.php

<?php

   session_start();

function getSlug( $page ) {
   $page = strip_tags( $page );
   preg_match_all( "/([a-z0-9A-Z-_]+)/", $page, $matches );
   $matches = array_map( "ucfirst", $matches[0] );
   $slug = implode( "-", $matches );
   return $slug;
}

   $fieldname = $_REQUEST['fieldname'];
   
   $encrypt_pass = @file_get_contents("files/password");
   if ($_COOKIE['wondercms']!=$encrypt_pass)
   {
   echo "You must login before using this function!";
   exit;
   }
   
   $content = rtrim(stripslashes($_REQUEST['content']));
   // if to only allow specified tags
   if($fieldname=="title")    $content = strip_tags($content);
   else	$content = strip_tags($content,"<audio><source><embed><iframe><p><h1><h2><h3><h4><h5><h6><a><img><u><i><em><strong><b><strike><center><pre>");

   $content = trim($content);
   $content = nl2br($content);

   if(!$content) $content = "Please be sure to enter some content before saving. Just type anything in here.";

   $content = preg_replace ("/%u(....)/e", "conv('\\1')", $content);

   if($fieldname>0 && $fieldname<4) $fname = "attachment$fieldname";
   else $fname = $fieldname;
   $file = @fopen("files/$fname.txt", "w");
   if(!$file)
   {
	echo "<h2 style='color:red'>*** ERROR *** unable to open content_$fieldname</h2><h3>But don't panic!</h3>".
"Please set the correct read/write permissions to the files folder.<br/>
Find the /files/ folder and CHMOD it to 751.<br /><br />
If this still gives you problems, open up the /files/ folder, select all files and CHMOD them to 640.<br /><br />
If this doesn't work, contact me <a href='http://krneky.com/en/contact'>right here</a>.";
   exit;
   }
   fwrite($file, $content);
   fclose($file);

   echo $content;
   
   // convert udf-8 hexadecimal to decimal
   function conv($hex)
   {
   $dec = hexdec($hex);
   return "&#$dec;";
   }
?>

 

There are only 3 files altogether, if someone needs index I'll post that too.

This is a dirty way to do it, but I don't have the time to go through every instance of using $_REQUEST and fixing it.

 

Add this to the top of your page -

 

foreach( $_REQUEST as $key => $val )
$_REQUEST[$key] = htmlentities($val);

 

Assuming you aren't using GET/POST arrays, this SHOULD work. It will automatically sanitize all user input.

 

An alternative, because I'm a freak and don't trust htmlentities

<?php

foreach( $_REQUEST as $key => $val )
$_REQUEST[$key] = preg_replace('/[^A-z0-9]/', '', $val);

?>

 

That regex will remove anything from request variables that's not a letter or number.

 

That will TOTALLY screw up form submission though, and I suggest using $_GET over $_REQUEST

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.