Page 1 of 1

Working Script w/text input, examples of to attack?

Posted: Thu May 08, 2008 3:52 pm
by JAB Creations
I just posted this working hexadecimal validation PHP script on my blog as an example of how to implement functions, regex, and how to determine if a hexadecimal value is valid or not (based on the regex rules).

It contains text inputs and eventually (in maybe about half a year) I'll be using my own in-house built PHP/MySQL database so I'm interested in learning and applying defenses against various attack methods.

So essentially what sort of funky stuff can I type in to the text forms to emulate an attack? How else can an attack occur if at all besides undesirable characters in the text forms during post method request(s)? Right now it's not utilizing a MySQL database but it eventually will. It would help to clarify if an attack is targeting the PHP and/or the MySQL for vulnerabilities.

Here is the script I wrote...

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>PHP Serverside Validation of Hexadecimal post data</title>
<style type="text/css">
body,html {font-family: monospace;}
b {color: #00f;}
b.bad {color: #f00;}
b.good {color: #0f0;}
</style>
</head>
<body>
 
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
<fieldset>
<p>This page's <b>GET request</b> will use values that start with <b>#</b>.</p>
 
<p>To test custom values follow the label directions below to test validation; all default values are valid examples.</p>
<label for="ce1">Use <b class="good">3</b> characters, don't use <b class="bad">#</b>: <input id="ce1" name="ce1" value="abc" /></label>
<br />
<label for="ce2">Use <b class="good">6</b> characters, don't use <b class="bad">#</b>: <input id="ce2" name="ce2" value="abcdef" /></label>
<br />
<label for="ce3">Use <b class="good">3</b> characters, do use <b class="good">#</b>: <input id="ce3" name="ce3" value="#123" /></label>
<br />
<label for="ce4">Use <b class="good">6</b> characters, do use <b class="good">#</b>: <input id="ce4" name="ce4" value="#789456" /></label>
<br style="clear: both;" />
<input style="display: block; width: 60%;" type="submit" value="Validate Hexadecimal Values" />
</fieldset>
</form>
 
<div>
<?php
// For values that do *not* start with #
$regex_a = '/^[a-f0-9]{3}$/';
$regex_b = '/^[a-f0-9]{6}$/';
 
// For values that *do* start with #
$regex_c = '/^#[a-f0-9]{3}$/';
$regex_d = '/^#[a-f0-9]{6}$/';
 
/*
1.) Regular Expressions are encased with slashes //.
2.) Since they are assigned to variables they are obviously encased within quotes.
3.) ^ == 'Starts with, $regex_c and $regex_d must start with # to match.
4.) [a-f] == Range, only the letters a,b,c,d,e,f match.
5.) [a-f0-9] == Multiple ranges, a,b,c,d,e,f,0,1,2,3,4,5,6,7,8,9 match.
6.) [a-ce-f0-35-8] == Three ranges, a,b,c,e,f,0,1,2,3,5,6,7,8 match in example.
7.) {3} == *Exact length number* of characters, only three characters allow.
8.) {6} == Exact length number of characters allowed is six, not 5/less or 7/more.
9.) {3,6} == Exact length allowed is between 3 and 6, 123, 1234, 12345, 987654 match.
10.) {3,} == Exact or greater length; allowed number of characters here is *three or more*.
11.) $ == Ends with matching characters, which will match in my regex ranges a-f and 0-9.
 
So $regex_a = '/^[a-f0-9]{3}$/' reads as...
'Starts with any a-f0-9 and must be exactly 3 characters in length.'
 
So $regex_b = '/^[a-f0-9]{6}$/'; reads as...
'Starts with any a-f0-9 and must be exactly 6 characters in length.'
 
So $regex_c = '/^#[a-f0-9]{3}$/'; reads as...
'Must starts with #, can contain the characters a-f0-9, and must be exactly 3 characters in length.'
 
So $regex_d = '/^#[a-f0-9]{6}$/'; reads as...
'Must starts with #, can contain the characters a-f0-9, and must be exactly 6 characters in length.'
*/
 
if ($_SERVER['REQUEST_METHOD'] == 'GET')
{
 $var_a = '123';
 $var_b = '123456';
 $var_c = '#abc';
 $var_d = '#abcdef';
}
else if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
 $var_a = $_POST['ce1'];
 $var_b = $_POST['ce2'];
 $var_c = $_POST['ce3'];
 $var_d = $_POST['ce4'];
}
 
function my_function($regex, $var)
{
 if (preg_match($regex, $var)) {echo '<b class="good">'.$var.'</b> is a <b class="good">match</b>!</b><br />';}
 else {echo '<b class="bad">'.$var.'</b> not a <b class="bad">match</b>!</b><br />';}
}
 
my_function($regex_a,$var_a);
my_function($regex_b,$var_b);
my_function($regex_c,$var_c);
my_function($regex_d,$var_d);
?>
</div>
</body>
</html>

Re: Working Script w/text input, examples of to attack?

Posted: Thu May 08, 2008 9:13 pm
by nowaydown1
I'm no security expert, but from my standpoint it looks like it -could- become vulnerable to a cross site scripting attack. You aren't doing any cleaning on your $_POST variables before outputting them to the page. You should never trust any data given to you by your users.

You can check out a little more info about XSS here:
http://phpsec.org/projects/guide/2.html

The security consortium has good stuff all around, so I would encourage you to spend some time poking around there.

Re: Working Script w/text input, examples of to attack?

Posted: Fri May 09, 2008 1:04 am
by Mordred
Security related:
Another classic XSS: <?php echo $_SERVER['PHP_SELF'];?>
You don't check if $_POST['something'] exists.

Logic flaws:
'abcd' is a valid color
'ABC' too

Re: Working Script w/text input, examples of to attack?

Posted: Fri May 09, 2008 9:29 am
by JAB Creations
Ultimately all this revolves around a cookie and a stylesheet; which brings me to another question...

I could theoretically reduce the server load by imploding the selectors, properties, and values in to a single value in the cookie (provided it's within the 4KB limit) and then merely echo the cookie's value in the stylesheet per request instead of refiltering everyone for every request. My initial thought was once the data is validated I could store only the CSS values in the cookie (and I'd still probably have to scan them for each and every request).

However I would presume this would put trust in the client where I would need to refilter incoming data again? Or is there a way I can only "dump" the data and force it to stop executing any PHP after that point though *just* in that file and serve the file as-is? I'd like to find a nice balance between minimizing unnecessary amounts of server load and the minimize if not altogether close any vulnerabilities.

Re: Working Script w/text input, examples of to attack?

Posted: Mon May 12, 2008 9:08 am
by Bruno De Barros
Like it was referred above, I could XSS you, because you don't do any value checking.

Besides, there is another thing. Imagine you are the administrator of the website, logged in as such, and the input is to edit some of your website's pages. You don't check the form referrer, so I could make a "Search my website" form, then tell you to go there. You would, and when you searched, it would send a post request, with hidden form fields to fake a true request, to your website. You would have $_POST['ce1']...ce4, so you would accept the request and the page would edited properly. The result on a critical web application would catastrophic. Imagine this forum, and me doing some XSS to delete one of the boards.

I don't seem to understand what you are trying to do with the stylesheet, but there's a huge problem with keeping it in cookies. Imagine your website calls 10 URLs. The HTML, 1 stylesheet, and 8 images. Multiply 10 for the size of the stylesheet. If it was exactly 4kb, you would have spent 40kb, just in cookies. This just for ONE page view. Now think of a more popular website, where there are, let's say, 10 users at the same time, each viewing 1 page per minute. That means 10 page views per minute, 600 page views per hour. It's not that much for a website, but it would mean 2.3MB in cookies per hour. ;) Think of that, for your users, and your server.
If you really want to have different stylesheet values per user, it's better to keep them on the SESSION variable, where information is kept within files on the server, not the client, or on the database. But big cookies means every HTTP request gets big. My HTML is often smaller than 4KB (without the content), so it would mean the headers would be bigger than the document. How weird is that???

Re: Working Script w/text input, examples of to attack?

Posted: Mon May 12, 2008 11:02 am
by Mordred
Bruno, what you are talking about is CSRF, not XSS. Do read some theory, CSRF is irrelevant here.

The point for the cookies is valid, +1 on that.

Re: Working Script w/text input, examples of to attack?

Posted: Mon May 12, 2008 1:34 pm
by Bruno De Barros
Mordred, whenever I read about this kind of attack, it was always called XSS. But I have done as you advised, and wikipedia clarified the difference ;). Sorry about that. But I disagree with you, it is not irrelevant.
Jab Creations:

It contains text inputs and eventually (in maybe about half a year) I'll be using my own in-house built PHP/MySQL database so I'm interested in learning and applying defenses against various attack methods.
So he wants to know what kind of stuff can be done with his text input. I was just being anal, as the forum description advises ;).

Re: Working Script w/text input, examples of to attack?

Posted: Mon May 12, 2008 1:40 pm
by JAB Creations
I was not sure at the time I originally posted how to skip keys in an array. It was that function that I left out (checking for an invisible post that verified what form is being submitted) that I had omitted...is this one of the points trying to be made?

In that case I think your other point was that if I don't look for a post/name request from a form that the code would execute per file request (thus 4 files=4 cookies, 5 files=5 cookies)...if say I had PHP handle images, my JavaScript, all my CSS, etc?

So let's say the form 'validation' post key is in $POST_['ce002'], how much better does my current code work as far as security is concerned?

Code: Select all

if ($_POST['formis'] == "ce002") {
$regex_a = '/^(([0-9a-f]{1,2}){3}|transparent|none)?$/';
function validate_array($regex, $var)
{
 if ($validity != '1' && $key != 'ce002')
 {
  if (preg_match($regex, $var)) {echo '<b class="good">'.$var.'</b> is a <b class="good">match</b>!</b><br />'."\n";}
  else {echo '<b class="bad">'.$var.'</b> not a <b class="bad">match</b>!</b><br />'; return false;}
 }
 return true;
}
 
foreach($_POST as $key => $value) {if(!validate_array($regex_a,$value)) {$validity = '1'; break;}}
 
}

Re: Working Script w/text input, examples of to attack?

Posted: Tue May 13, 2008 12:59 am
by Mordred
JAB, I'm not sure what you mean, but I think you should keep in mind that cookies are sent by the browser for all requests to the server, including those that are not handled by PHP (which is, after all, a server setting which the client knows nothing about). So Bruno's point is valid regardless of whether you serve css through a PHP proxy script or not.

@Bruno: Okay, I concur. Being an anal nitpick is a must in the security field :)

Re: Working Script w/text input, examples of to attack?

Posted: Tue May 13, 2008 1:04 am
by JAB Creations
I don't think I asked the question here but essentially the user's custom stylesheet would just have the cookie's string echoed and that's it. I made several attempts to execute code, PHP, echos, slashes, weird stuff, etc and all I ended up doing was screwing up the page's style at best. So...

1.) Is there any way to abuse such a setup and if so how then how can I duplicate this so I can test it out?

2.) Someone mentioned using a session cookie instead though I'm trying to avoid using a database for this feature (right now). I don't follow how this setup would work?

Re: Working Script w/text input, examples of to attack?

Posted: Tue May 13, 2008 2:46 am
by Bruno De Barros
The cookies are like identification papers. They are shown each and every time the browser asks for some file from your website. If you have really big identification papers, your browser will have to send bigger identification papers, spending more of your bandwidth, and making the page browse slower.

To use sessions, the session's data is not kept with the client. It is kept with the PHP server. The only thing the client keeps is the session's ID. To use sessions you must put session_start() in all your pages, before anything happens on the website. That will create a new session or restart an existing one, if the client already had a PHP session started.
Then, it goes as easy as doing:

$_SESSION['stylesheet'] = WHATEVER_YOU_WANT_TO_PUT;

and then to echo...

echo $_SESSION['stylesheet'];

The only thing about this (I don't know if that's a problem with you) is that it's not permanent. Sessions are just that. Sessions. So when the user closes the browser, his session is destroyed.

Re: Working Script w/text input, examples of to attack?

Posted: Tue May 13, 2008 10:37 am
by JAB Creations
In that case I can still keep the original cookie, scan it with my regex filters, then assign it for the session, and when they leave the sign/close the browser/etc the process would repeat. So the regex filter would only need to occur once when they re-establish a new session.

My site currently already sets a session cookie...

Code: Select all

session_name("member");
session_start();
...do I create a second session cookie or?

Re: Working Script w/text input, examples of to attack?

Posted: Thu May 15, 2008 3:40 am
by Bruno De Barros
No, don't keep the original cookie. If you want to, ok. But you must put in your mind that such will make your pages a LOT slower (I can't stress this enough).

What you can do:

>> Set a cookie (that expires whenever you want), with a random ID (eg. setcookie('stylesheetID',$unique_id,$expiry_date);
>> Create a file for example custom_stylesheets/$unique_id and write all the stylesheet values on it.
>> Then, just open custom_stylesheets/$_COOKIE['stylesheetID'] and use the values on that file.

It's easy and it works.