roldahayes Posted June 18, 2009 Share Posted June 18, 2009 Hi, Im having a problem with a "continue shopping" button on a site - When a security test has been run on the site, one of the errors was; "Possible cross site scripting " the line of code in question is; <a href="<?php echo $_SESSION['returnTo']; ?>"><img src="2003/continue2.gif" alt="CLICK HERE TO CONTINUE SHOPPING" width="212" height="39" border="0"></a> Any suggestions why this is classed not secure? Quote Link to comment https://forums.phpfreaks.com/topic/162731-possible-cross-side-sripting/ Share on other sites More sharing options...
Adam Posted June 18, 2009 Share Posted June 18, 2009 In that context there's absolutley nothing anyone can tell you about it. Need more information about where the 'returnTo' session var comes from, what code's used, etc. Quote Link to comment https://forums.phpfreaks.com/topic/162731-possible-cross-side-sripting/#findComment-858761 Share on other sites More sharing options...
roldahayes Posted July 2, 2009 Author Share Posted July 2, 2009 Ok, still having problems with this - the stripped down code for the page is: <?php session_start (); //include header code include_once("head.php"); // use the user_connection include file's connectDB function include_once("usr_conn.php"); if(!connectDB()) { echo "<p>Unable To Connect To Database</p>"; return; } if (isset ($_GET['src'])) { $_SESSION['returnTo'] = $_GET['src']; } // assign variables //echo "ref1:" . $HTTP_REFERER . "<br>"; //$temp = (string)$HTTP_REFERER; //$urlref2 = substr($temp,0,6); //echo "ref:" . $urlref; $urlref = $HTTP_REFERER; $prodID = $_GET['productID']; $delete = $_GET ['delete']; $quantity = $_GET['quantity']; $updateQuantity = $_GET['updateQuantity']; $update = $_GET ['update']; $currency = "£"; // maximum querys per user basket $MAXBASKETQUERY = 25; // start the html table ?> <!-- start header graphic html --> <table width="770" border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td background=""><!-- end header graphic html --> <!-- start Nav html --> <!-- end nav html --> <table width="800" border="0" align="center" cellpadding="0"> <tr> <td height="170" valign="top"> <div align="center"> <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td height="71"> <div align="center"> <table width="100%" border="0" cellspacing="0" cellpadding="7"> <tr> <td width="72%"><font size="2" face="Arial, Helvetica, sans-serif">The following products have been added to your shopping basket. </font></td> </tr> </table> <table width="98%" border="0" align="center" cellpadding="5" cellspacing="0"> <tr> <td width="28%" valign="top"><a href="<?php echo $_SESSION['returnTo']; ?>"><img src="2003/continue2.gif" alt="CLICK HERE TO CONTINUE SHOPPING" width="212" height="39" border="0"></a></td> <td width="72%"><div align="right"><a href="checkout.php"><img src="2003/proceed.gif" alt="CLICK HERE TO SUPPLY PAYMENT AND SHIPPING INFORMATION" width="212" height="39" border="0"></a></div></td> </tr> </table> </div></td> </tr> <tr> <td align=center> <!--begin basket output--> <table width="98%" border="1" align="center" cellpadding="2" cellspacing="0" bordercolor="#FFFFFF"> <!--start tableheaders--> <tr class="headertable"> <td width="111" height="25"> <div align="center">FOR VEHICLE:</div></td> <td width="75" height="25"> <div align="center">REF NO.</div></td> <td width="292" height="25"> <div align="center">DESCRIPTION</div></td> <td width="42" height="25"> <div align="center">QTY</div></td> <td width="71" height="25"> <div align="center">ex vat</div></td> <td width="71"> <div align="center">inc vat<br> </div></td> <td width="57" height="25"> <div align="center">TOTAL<br> PRICE</div></td> <td width="59" height="25" bgcolor="#FFFFFF"> <div align="center"><font face="Verdana, Arial, Helvetica, sans-serif"></font></div></td> </tr> <!--end table headers--> <tr class="stdtable"> <td colspan="6" align="center"> <?php // check if user has no cookie set if ($userID == "") { ?> <table border="0" align="center" cellpadding="0" cellspacing="0"> <tr class="stdtable" align="center"> <td colspan="6">No Product Querys made yet </td> </tr> </table> <p> <?php return; } //if the updated quantity is 0 or blank remove item from basket if ($updateQuantity == '0'){ $delete = 'yes'; } if (($update == 'yes')&& ($updateQuantity == '')){ $delete = 'yes'; } // if delete parameter set to yes run the delete code if ($delete == 'yes') { // if prodID is set, delete that specific product from this userID's basket if ($prodID != "") { $sqlquery = "DELETE FROM basket WHERE userID = '" . $userID . "' AND productID = '" . $prodID . "'"; $result = mysql_query($sqlquery); if ($result) { ?> </p> <p> </p> <table border="0" align="center" cellpadding="15" cellspacing="0"> <tr class="stdtable" align="center"> <td width="564" colspan="6"><font size="5" face="Arial, Helvetica, sans-serif"><strong>Item Deleted. Click <a href="basket.php"><font color="#990000">Here</font></a> to refresh the basket </strong></font></td> </tr> </table> <?php } else { ?> <table border="0" align="center" cellpadding="0" cellspacing="0"> <tr class="stdtable" align="center"> <td width="368" colspan="6">Unable To Delete <br> Item Click <a href="basket.php">Here</a> to refresh the basket </td> </tr> </table> <?php } // close the database connection mysql_close(); return; } } //update the shopping basket quantity if ($update == 'yes') { // if prodID is set, delete that specific product from this userID's basket if ($prodID != "") { $sqlquery = "UPDATE basket SET quantity = '" . $updateQuantity . "' WHERE productID = '" . $prodID . "'AND userID = '" . $userID . "'"; $result = mysql_query($sqlquery); if ($result) { ?> <table border="0" align="center" cellpadding="0" cellspacing="0"> <tr class="stdtable" align="center"> <td colspan="6">Your basket has been updated</td> </tr> </table> <?php } else { ?> <table border="0" align="center" cellpadding="0" cellspacing="0"> <tr class="stdtable" align="center"> <td colspan="6">Your basket has NOT been updated</td> </tr> </table> <?php } // close the database connection //mysql_close(); //return; } } // find the number of rows in this userID's basket $sqlquery = "SELECT * FROM basket WHERE userID = '" . $userID . "'"; $result = mysql_query($sqlquery); if (!$result) { echo "<p><font class=error>Could not find any entrys for this Basket</small></p>"; mysql_close(); return; } else $rowCount = mysql_num_rows($result); // if prodID is set new product is passed in, add/update the userID's basket if ($prodID != "") { // find if the prodID already exists in this userID's basket $sqlquery = "SELECT * FROM basket WHERE userID = '" . $userID . "' AND productID = '" . $prodID . "'"; $result = mysql_query($sqlquery); $rowCount = mysql_num_rows($result); // if no matches insert the product into the userID's basket if ($rowCount == 0) { // find number of items in basket $sqlquery = "SELECT * FROM basket WHERE userID = '" . $userID . "'"; $result = mysql_query($sqlquery); $rowCount = mysql_num_rows($result); // check if the maxquery's has been reached if ($rowCount > ($MAXBASKETQUERY - 1)) { echo ("<p><font class=error>Only $MAXBASKETQUERY overall orders are allowed, your product could not be added to basket</font></p>"); } else { $expiretime = time() + 7200; $sqlquery = "INSERT INTO basket" . $basketFields . "VALUES ('" . $prodID . "', '1', '" .$userID . "', '" . $expiretime . "')"; $result = mysql_query($sqlquery); if (!$result) echo "<font class=error><p>Could not add item to Basket</p></font>"; } } } // select the userID's basket query and the Product Reference relating to each of the basket's productID's $sqlquery = "SELECT products.Prod_REF, basket.productID, basket.quantity, products.Prod_Make, products.Prod_Model, products.Prod_Type, products.Car_Make, products.Car_Model, products.Price_ExVat, products.Post_ID, Product_Desc FROM basket INNER JOIN products ON basket.productID = products.Prod_ID WHERE ((basket.userID) = '" . $userID . "')"; $result = mysql_query($sqlquery); $rowCount = mysql_num_rows($result); // echo $sqlquery; // *debug // assign the table headers //$dbFields = array( "Reference", "Product Query"); // check if no entries in basket if (!$result || (mysql_num_rows($result) == 0)){ ?> <table border="0" align="center" cellpadding="0" cellspacing="0"> <tr class="stdtable" align="center"> <td colspan="6" class="error">No Product Queries In Basket. </td> </tr> </table> <?php } else //*************display contents of basket////////////////////////////////////////////////////// { // echo each header from array //foreach ($dbFields as $headIndex) // echo an extra blank header for the delete item column // fetch each row as an associative array $counter = 1; $price = 0; //set default postage value outside loop $postagerate = 10.00; while ($row = mysql_fetch_assoc($result)) { //decide which postage value is the highest and use that to calculate overall price //get the postage values for each product $sqlpostquery = "SELECT * FROM postage WHERE Post_ID = '" . htmlspecialchars($row['Post_ID']) . "'"; //get the postage values from the database $postresult = mysql_query($sqlpostquery); $rowpost = mysql_fetch_assoc($postresult); // check if postage value was available if ($postresult || !(mysql_num_rows($postresult) == 0)) { $rawpostage = htmlspecialchars($rowpost['Post_Cost']) ? htmlspecialchars($rowpost['Post_Cost']) : 0.00; //get the lowest postage rate. if ($postagerate > $rawpostage) { $postagerate = $rawpostage; } } else { $postagerage = 0.00; } //round postage rate of 2 decimal places $postagerate = $postagerate; //release the postage resultset array mysql_free_result($postresult); echo "<form action=basket.php method=get name=form".$counter."> <input name=update type=hidden value=yes> <input name=productID type=hidden value=". $row['productID'] ."><tr class=stdtable>"; echo("<td align=center> " . htmlspecialchars($row['Car_Model']) . "</td>"); echo("<td align=center> " . htmlspecialchars($row['Prod_REF']) . "</td>"); echo("<td align=left>" . htmlspecialchars($row['Product_Desc']) . "</td>"); //echo("<td align=center>". htmlspecialchars($row['Prod_REF']) ."</td>"); // for the final column echo an hyperlink to delete the product entry //settype($row["Price_ExVat"], "integer"); echo "<td align=center><input name=updateQuantity onchange=submit(); type=text size=2 value=". htmlspecialchars($row['quantity'])."></td><td align=center>". $currency . number_format(htmlspecialchars($row['Price_ExVat']), 2) ."</td><td align=center>". $currency . number_format(calcVAT($row["Price_ExVat"]), 2) ."</td><td align=center>". $currency . number_format((calcVAT (htmlspecialchars($row['Price_ExVat'] * $row['quantity']))), 2) ."</td>"; echo "<td align=center><a href=\"basket.php?delete=yes&productID=" . $row['productID'] . "\"><img src=2003/remove.gif border=0></a></td>"; echo "</tr></form>"; $counter ++; //get a cumulative value of the price as items are added to the basket and multiply by quantity as we go. $price = $price + (calcVAT (htmlspecialchars($row['Price_ExVat']))) * htmlspecialchars($row['quantity']); } //assign subtotal and round to 2 decimal places $subtotal = $price; $total = $subtotal + $postagerate; //pick overall postage type if ($postagerate == 5) $postage = 3; else if ($postagerate == 9) $postage = 2; else if ($postagerate == 10) $postage = 1; } //update shopper table with new/changed info $sqlshopper = "SELECT * FROM shopper WHERE User_ID = '" . $userID . "'"; //echo "query: " . $sqlshopper; $result = mysql_query($sqlshopper); $rowCount2 = mysql_num_rows($result); //add shopper if ($rowCount2 == 0) { $sqladd = "INSERT INTO shopper" . $shopperFields . "VALUES ('" . $userID . "', '" . $total . "', '" . $postage . "')"; //echo "noshopper: " . $sqladd; $shopadd = mysql_query($sqladd); if (!$shopadd) echo "<font class=error><p>Your basket has not been processed</p></font>"; } else { //update details $sqlupdate = "UPDATE shopper SET Basket_total = '" . $total . "', Postage = '" . $postage . "' WHERE user_ID = '" . $userID . "'"; //echo "shopper: " . $sqlupdate; $shopupdate = mysql_query($sqlupdate); if (!$shopupdate) echo "<font class=error><p>Your basket has not been updated</p></font>"; } // finish table ?> </td> </tr> <?php ?> </table> <table width="100%" border="0" cellspacing="0" cellpadding="1"> <tr> <td width="69%"><div align="right"> <table width="100%" border="0" cellspacing="0" cellpadding="5"> <tr> <td width="90%"><div align="right"><a href="#"><img src="2003/update2.gif" alt="CLICK HERE TO UPDATE BASKET IF YOU CHANGE QUANTITIES" width="81" height="34" border="0"></a></div></td> <td width="10%"><div align="right"></div></td> </tr> </table> </div></td> <td width="31%"><table width="161" border="1" cellpadding="1" cellspacing="0" bordercolor="#FFFFFF"> <tr bordercolor="#FFFFFF"> <td width="55%" height="25" align="right" bgcolor="#EBEBEB" class=small><font color="#000000"><strong>SUB TOTAL</strong></font></td> <td width="45%" height="25" align="center" bgcolor="#EBEBEB" class=header> <?php echo $currency; echo number_format($subtotal, 2); ?> </td> </tr> <tr bordercolor="#FFFFFF"> <td height="25" align="right" class="small"><font color="#000000">POSTAGE</font></td> <td height="25" align="center" class="header"> <?php echo $currency; echo number_format($postagerate, 2); ?> </td> </tr> <tr bordercolor="#FFFFFF" bgcolor="#EAEADB"> <td height="25" align="right" class="small"><font color="#000000"><strong>TOTAL</strong></font></td> <td height="25" align="center" class="header"> <?php echo $currency; echo number_format($total, 2); ?> </td> </tr> </table></td> </tr> </table> <!--end basket output--> </td> </tr> </table> <hr width="600" size="1"> <div align="left"></div> <table width="100%" border="0" cellspacing="0" cellpadding="15"> <tr> <td align="center"> </td> </tr> </table> <br> </div></td> </tr> </table></td> </tr> </table> <!--end basket htm--> <?php //include footer code //release the postage resultset array mysql_free_result($result); // close the database connection mysql_close(); ?> Quote Link to comment https://forums.phpfreaks.com/topic/162731-possible-cross-side-sripting/#findComment-867770 Share on other sites More sharing options...
PFMaBiSmAd Posted July 2, 2009 Share Posted July 2, 2009 You are setting $_SESSION['returnTo'] to whatever has been provided on the end of the URL when the page is requested - $_SESSION['returnTo'] = $_GET['src']; You MUST validate ALL external data (get/post/cookie) to INSURE it ONLY contains expected values. All external data cannot be trusted. A hacker can set get/post/cookie variables to anything he wants when he requests your page. Quote Link to comment https://forums.phpfreaks.com/topic/162731-possible-cross-side-sripting/#findComment-867774 Share on other sites More sharing options...
roldahayes Posted July 2, 2009 Author Share Posted July 2, 2009 Ok I (think) I understand that... ??? Do you have any suggestions on how to fix this? Quote Link to comment https://forums.phpfreaks.com/topic/162731-possible-cross-side-sripting/#findComment-867786 Share on other sites More sharing options...
PFMaBiSmAd Posted July 2, 2009 Share Posted July 2, 2009 Put a list of the permissible values that $_GET['src'] can have into an array and use the in_array function to validate that it only contains one of the values. Throw in a strtolower function to insure that anything entered with any upper-case letters will match the contents of the array (which should all be in lower-case.) Quote Link to comment https://forums.phpfreaks.com/topic/162731-possible-cross-side-sripting/#findComment-867798 Share on other sites More sharing options...
roldahayes Posted July 2, 2009 Author Share Posted July 2, 2009 Ok, NOW I'm lost! Im assuming that the problem is that when the buy button is clicked, the url has basket.php?src=%2Fproduct_page.php&productID=1240332 so I need to make it ignore that part? Quote Link to comment https://forums.phpfreaks.com/topic/162731-possible-cross-side-sripting/#findComment-867815 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.