Jump to content

Recommended Posts

hi all

 

how does one prevent problems like this

 

http://www.phpfreaks.com/forums/index.php/topic,162912.msg714035.html#msg714035

 

I been looking for some explanation of how to prevent this but I haven't found anything particularly helpful

 

starting really simple how would I create a secure include ??

 

consider a typical include

 

<?php include("Introduction.php"); ?>

 

which creates a url like this

 

http://www.some-web-page/Index.php?page=Introduction

 

obviously this is insecure due to the lack of input validation & filtering question is how do I secure it ??

 

I've see a lot of different articles describing various methods but I'm lost there seems to be 1001 different ways to deal with this i just want something simple and secure and reusable that I could put in to an independent script and then just link to using an include

 

so something like

 

<?php if (Valid input)
include("Introduction.php"); 
else
include("Filter.php"); 
?>

 

the next question after that is how do I actually define what is acceptable input I figurer its probably easer to block everything and then define what is allowed rather than trying to do it the other way round

 

I guess the next question after that wound have to be how do you block all user input obviously the strip tags and trim commands that where suggested in one of my other threads would be a good place to start

Link to comment
https://forums.phpfreaks.com/topic/72725-web-site-security-help/
Share on other sites

????

 

this is not regarding the contact form this is regarding the general security of the rest of the site if you go to the thread i linked to above you will see that my code has some issues due to lack of input validation

 

so presently anyone can type what ever they like in to the address bar and possibly cause some nasty things to happen for instance Cross Site Scripting: attacks or deliberately inputting invalid urls to try and gain information that can be used to hack the site

 

I would like to fix these issues

 

however i'm not quite sure how and this is what I'm trying to find out

 

so to start simply how does one creates a secure include that is not susceptible to Cross Site Scripting attacks

 

for instance with out input validation all you need do is to change ?page=Introduction and conceivably you could make my site load your nasty script if you see what i'm saying

do you have mysql_real_escape_string in your sql query? this will  protect against SQL injection

 

also try this function

 

 

<?php

function RemoveXSS($val) { 
   // remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed 
   // this prevents some character re-spacing such as <java\0script> 
   // note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs 
   $val = preg_replace('/([\x00-\x08][\x0b-\x0c][\x0e-\x20])/', '', $val); 
    
   // straight replacements, the user should never need these since they're normal characters 
   // this prevents like <IMG SRC=&#38;#X40&#38;#X61&#38;#X76&#38;#X61&#38;#X73&#38;#X63&#38;#X72&#38;#X69&#38;#X70&#38;#X74&#38;#X3A&#38;#X61&#38;#X6C&#38;#X65&#38;#X72&#38;#X74&#38;#X28&#38;#X27&#38;#X58&#38;#X53&#38;#X53&#38;#X27&#38;#X29> 
   $search = 'abcdefghijklmnopqrstuvwxyz'; 
   $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 
   $search .= '1234567890!@#$%^&*()'; 
   $search .= '~`";:?+/={}[]-_|\'\\'; 
   for ($i = 0; $i < strlen($search); $i++) { 
      // ;? matches the ;, which is optional 
      // 0{0,7} matches any padded zeros, which are optional and go up to 8 chars 
    
      // &#38;#x0040 @ search for the hex values 
      $val = preg_replace('/(&#38;#[x|X]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ; 
      // &#38;#00064 @ 0{0,7} matches '0' zero to seven times 
      $val = preg_replace('/(&#38;#0{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ; 
   } 
    
   // now the only remaining whitespace attacks are \t, \n, and \r 
   $ra1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base'); 
   $ra2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload'); 
   $ra = array_merge($ra1, $ra2); 
    
   $found = true; // keep replacing as long as the previous round replaced something 
   while ($found == true) { 
      $val_before = $val; 
      for ($i = 0; $i < sizeof($ra); $i++) { 
         $pattern = '/'; 
         for ($j = 0; $j < strlen($ra[$i]); $j++) { 
            if ($j > 0) { 
               $pattern .= '('; 
               $pattern .= '(&#38;#[x|X]0{0,8}([9][a][b]);?)?'; 
               $pattern .= '|(&#38;#0{0,8}([9][10][13]);?)?'; 
               $pattern .= ')?'; 
            } 
            $pattern .= $ra[$i][$j]; 
         } 
         $pattern .= '/i'; 
         $replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2); // add in <> to nerf the tag 
         $val = preg_replace($pattern, $replacement, $val); // filter out the hex tags 
         if ($val_before == $val) { 
            // no replacements were made, so exit the loop 
            $found = false; 
         } 
      } 
   } 
   return $val; 
} 

?>

perhaps it would help if i posted the source for one one the files that have been identifiyed as vunrable to cross site scripting

 

here is the page switcher script

 

<?php 

switch ($_GET["page"]) 

{
  default:
  header("Location: Index.php?page=Section-1-Introduction");
  break;

  case "Contact":
  include("Content/Under-Construction.php"); 
  break;

  case "Site-Map":
  include("Navigation/Site-Map.php");
  break;

  /* Section 1 */

  case "Section-1-Introduction":
  include("Content/Section-1-Introduction.php");
  break;

  case "Preparation":
  include("Content/Preparation.php");
  break;
   
  case "Basic-Cleaning":
  include("Content/Basic-Cleaning.php");
  break;
   
  case "Advanced-Cleaning":
  include("Content/Advanced-Cleaning.php");
  break;

  case "Last-Resort":
  include("Content/Last-Resort.php");
  break;

  case "Troubleshooting":
  include("Content/Troubleshooting.php");
  break;

  case "Support":
  include("Content/Support.php");
  break;

  /* Section 2 */

  case "Section-2-Introduction":
  include("Content/Section-2-Introduction.php");
  break;

  case "Internet-Explorer":
  include("Content/Internet-Explorer.php");
  break;

  case "Outlook-Express":
  include("Content/Outlook-Express.php");
  break;

  case "Windows-Media-Player":
  include("Content/Windows-Media-Player.php");
  break;

  case "Disabling-Unnecessary-Processes":
  include("Content/Disabling-Unnecessary-Processes.php");
  break;

  case "Fixing-UnPatched-Security-Holes":
  include("Content/Fixing-UnPatched-Security-Holes.php");
  break;

  case "Additional-Layers-Of-Protection":
  include("Content/Additional-Layers-Of-Protection.php");
  break;

  case "Tweaking-And-Windows-Customisation":
  include("Content/Tweaking-And-Windows-Customisation.php");
  break;

  case "Testing-And-Validation":
  include("Content/Testing-And-Validation.php");
  break;

  /* Section 3 */

  case "Host-File-And-Host-File-Management":
  include("Content/Host-File-And-Host-File-Management.php");
  break;

  case "Pacfile-And-Pacfile-Management":
  include("Content/Pacfile-And-Pacfile-Management.php");
  break;

  case "Proxies-And-Web-Filters":
  include("Content/Under-Construction.php");
  break;

  /* Section 4 */

  case "General-Computer-Maintenance":
  include("Content/General-Computer-Maintenance.php");
  break;

  case "Registry-Maintenance-Backup-And-Restoration":
  include("Content/Registry-Maintenance-Backup-And-Restoration.php");
  break;

  case "System-Backup":
  include("Content/System-Backup.php");
  break;
}

?>

 

now what I need to do is to add a check to make sure that the url is valid if it is then run the script if not then the input needs to be killed

 

try the xss function i use for my guestbook

 

ehh ??

put the following function in a function file and include it on that page ad where it says switch get page call the function it will strip out all XSS.

 

 

<?php 
include('function.php');

switch (RemoveXSS($_GET["page"]) )

{
  default:
  header("Location: Index.php?page=Section-1-Introduction");
  break;

  case "Contact":
  include("Content/Under-Construction.php"); 
  break;

  case "Site-Map":
  include("Navigation/Site-Map.php");
  break;

  /* Section 1 */

  case "Section-1-Introduction":
  include("Content/Section-1-Introduction.php");
  break;

  case "Preparation":
  include("Content/Preparation.php");
  break;
   
  case "Basic-Cleaning":
  include("Content/Basic-Cleaning.php");
  break;
   
  case "Advanced-Cleaning":
  include("Content/Advanced-Cleaning.php");
  break;

  case "Last-Resort":
  include("Content/Last-Resort.php");
  break;

  case "Troubleshooting":
  include("Content/Troubleshooting.php");
  break;

  case "Support":
  include("Content/Support.php");
  break;

  /* Section 2 */

  case "Section-2-Introduction":
  include("Content/Section-2-Introduction.php");
  break;

  case "Internet-Explorer":
  include("Content/Internet-Explorer.php");
  break;

  case "Outlook-Express":
  include("Content/Outlook-Express.php");
  break;

  case "Windows-Media-Player":
  include("Content/Windows-Media-Player.php");
  break;

  case "Disabling-Unnecessary-Processes":
  include("Content/Disabling-Unnecessary-Processes.php");
  break;

  case "Fixing-UnPatched-Security-Holes":
  include("Content/Fixing-UnPatched-Security-Holes.php");
  break;

  case "Additional-Layers-Of-Protection":
  include("Content/Additional-Layers-Of-Protection.php");
  break;

  case "Tweaking-And-Windows-Customisation":
  include("Content/Tweaking-And-Windows-Customisation.php");
  break;

  case "Testing-And-Validation":
  include("Content/Testing-And-Validation.php");
  break;

  /* Section 3 */

  case "Host-File-And-Host-File-Management":
  include("Content/Host-File-And-Host-File-Management.php");
  break;

  case "Pacfile-And-Pacfile-Management":
  include("Content/Pacfile-And-Pacfile-Management.php");
  break;

  case "Proxies-And-Web-Filters":
  include("Content/Under-Construction.php");
  break;

  /* Section 4 */

  case "General-Computer-Maintenance":
  include("Content/General-Computer-Maintenance.php");
  break;

  case "Registry-Maintenance-Backup-And-Restoration":
  include("Content/Registry-Maintenance-Backup-And-Restoration.php");
  break;

  case "System-Backup":
  include("Content/System-Backup.php");
  break;
}

?>

You could do something like...

 

<?php
$valid_page_array = array('Contact', 'Site-Map', 'Support', 'Make sure', 'you put', 'all your', 'valid pages', 'in this', 'really really', 'long array');

if(!in_array($_GET['page'], $valid_page_array) {
    die('That is not a valid url...');
}
?>

 

So much simpler and it works...

ok apparently that code

 

<?php
$valid_page_array = array('Contact', 'Site-Map', 'Support', 'Make sure', 'you put', 'all your', 'valid pages', 'in this', 'really really', 'long array');

if(!in_array($_GET['page'], $valid_page_array) {
    die('That is not a valid url...');
}
?>

 

is wrong

 

Parse error: parse error, unexpected '{' in \\192.168.1.16\webfiles\files\2005-3\275289\demo\Web-Site-Demo\Switch\page-switcher.php on line 6

 

one other problem this doesn't protect the rest of the files that make up the site

Which line of the file is line 6? I can't see any errors with the code I posted... and I thought you just wanted to protect your $-GET[]'s...  ;)

 

EDIT I missed a ")"...

 

<?php
$valid_page_array = array('Contact', 'Site-Map', 'Support', 'Make sure', 'you put', 'all your', 'valid pages', 'in this', 'really really', 'long array');

if(!in_array($_GET['page'], $valid_page_array)) {
    die('That is not a valid url...');
}
?>

 

That will work... make sure you add all your pages to the array...

Most of what was reported in that thread came from Warning messages. When you go to beta test your site (when its ready for live development) You need to change the error reporting to OFF. This will result in white pages for Parse and Fatal errors, and remove any Warning messages.

 

My suggestion:

Create a script that allows you to turn on and turn off error messages easily.

 

Refer to http://php.net/error_reporting

 

A good way to do this is in your configuration script is to either set a variable or set a constant, this is a relatively simple example and yours should probably be more robust:

 

<?php
//debug.php
$dev_mode = 'true'; //change to false when you want to view error messages
if($dev_mode = 'true') {
error_reporting(6135);
} else {
error_reporting(0);
}
?>

 

Then include this file into every script you run.

hi

 

I thought you just wanted to protect your $-GET[]'s..

 

ideally id like to protect all the files that make up my site not just the $-GET[]

 

Most of what was reported in that thread came from Warning messages. You need to change the error reporting to OFF. This will result in white pages for Parse and Fatal errors, and remove any Warning messages.

 

My suggestion:

Create a script that allows you to turn on and turn off error messages easily.

 

I see question is it not possible to just add error_reporting(0); and leave it at that and then if I need to see error message change error reporting from (0) to (6135)

 

Is any particular reason and/or advantage to be gained by getting more complicated and creating a debug script as you suggest because it sounds like unnecessary work

 

unless its actually possible to make the server error reporting more accurate so that the error message actually reflects the real mistake that caused the error

 

one other thing is it possible to have the error reporting viable only to me I'm just thinking that this would be more useful than just turning error reporting off

 

Actually yes. From using the URL to enable debug mode, "/page.php?debug=1" then an if statement in page.php that says if debug is set - to output error messages instead of editing the file and re-uploading it, to disabling any scripts that may interact with the database and cause emails to be sent (they come in mass waves on a larger scale site, ask someone who owns a forum that the database server has gone down on).

If you wanted an approach where you wouldn't have to mess with that file so much you could do something like:

 


if(isset($_GET['page']) && preg_match('/^[a-z0-9_-]+$/', $page) && file_exists('includes/'.$_GET['page'].'.php')) {
     include('includes/'.$_GET['page'].'.php');
}
else {
    include('404.php');
}

 

Edit: this was a response to the end of the first page... lol

Also, please note that I've never used this approach....

hi all

 

I appreciate the efforts to try and help me but I'm really not getting this and im totally absolutely confused none of this is making any sense to me what so ever

 

so I have 3 questions

 

1.) how do detect bad input

2.) how do i make the filter script load upon detection of bad input

3.) upon loading of the filter script how do get it to remove said bad input

 

so for instance if someone was to type the following into the address bar

 

http://h1.ripway.com/Bethrezen/demo/Web-Site-Demo/index.php/%3Cmarquee%3E%3Ch1%3Evulnerable%3Chr%3E

or

http://h1.ripway.com/Bethrezen/demo/Web-Site-Demo/Switch/style-switcher.php/a

 

etc.

 

how would I

 

1.) detect that this is bad input

2.) load the filter file to deal with it

3.) have the filter script to remove the bad input

 

/%3Cmarquee%3E%3Ch1%3Evulnerable%3Chr%3E

or

/a

 

etc.

 

so that the person ends up looking at

 

http://h1.ripway.com/Bethrezen/demo/Web-Site-Demo/index.php

or

http://h1.ripway.com/Bethrezen/demo/Web-Site-Demo/Switch/style-switcher.php

 

etc.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.