There are hundreds of methods to exploit a php script, but there is one, that many people just don’t pay much attention to.
The real problem happens when your script can upload files.

First of all, if your script just uploads ANY file, an attacker can upload a php shell and gain access to the server. But what if you just allow uploading image files? say .gif and .jpg only.

Well, it is possible to make a full functioning .gif file with php code inside it. And if the filename is changed to image.php.gif, and it can be accessed directly: http://server.com/image.php.gif the php code will be executed !!!.
There are several ways to protect from this:

+ Change the filename to a randomly generated filename and use a new extension. That is, if user’s file is .php.gif, the script should detect that it is a GIF file and rename it to image.gif.
+ Inserting the file into a database. This is not the best way of protecting, but it works. If your image file is generated by another script that retrieves data from a database the attacker won’t be able to execute the script (As long as you use header(’Content-Type: image/gif’); to show the file).

Posted by freenity, filed under General, PHP Curious Stuff. Date: March 24, 2008, 1:32 pm | 3 Comments »

It’s a web 2.0 era, so why would you use a normal gray button when you can make custom ones to fit your website style?

Well a button is just like any xhtml tag, you can customize most of it’s properties: font, color, size, background, etc.

Have a look at this:

  1.  
  2. <style>
  3. .mybtn
  4. {
  5.         width: 200px;
  6.         height: 70px;
  7.         background: url(btn.jpg);
  8.         font-size: 20px;
  9.         font-weight: bold;
  10.         color: #ee4444;
  11.         border: 0;
  12.         outline: none;
  13. }
  14.  
  15. .mybtn:active
  16. {
  17.         font-size: 30px;
  18. }
  19. </style>
  20. <input class="mybtn" value="Click Here" type="button" />

This is just a simple button with a background image, that how this gradient is made. It also sets the font size to 30px when the button is clicked. This is done with :active pseudo-class.
And here is the button itself:

csscustombutton.html

Enjoy :)

Posted by freenity, filed under CSS, Tableless design. Date: March 16, 2008, 7:00 pm | 2 Comments »

As in everything we can make mistakes, and when you develop a site using multiple technologies (PHP, MySQL, JavaScript, CSS…, etc) there will be more placed to make mistakes/errors. So CSS is not an exception.

  1. p .a
  2.  
  3. {
  4.  
  5. ….
  6.  
  7. }
  1. p.a
  2.  
  3. {
  4.  
  5. ….
  6.  
  7. }

Take a look at these 2 codes. What is the difference?? Got it? the space between ‘p’ and ‘.a’ in the first code. This can lead to unexpected results if you only wanted to apply the style for

  1.  
  2. <p class="a"></p>
  3.  

So when you have a space it means that ALL class=”a” after the first p

tag will have this style. Example:

  1.  
  2. <p class="a">Hi</p>
  3. <p class="b">First div</p>
  4.  

In this case the second AND the first paragraph will be applied the style.

But if we apply the second style (the one without a space) to the same code the style will be applied ONLY to the first paragraph (class=”a”).
So here you are, a simple space making huge differenced.

Posted by freenity, filed under CSS. Date: March 12, 2008, 8:11 pm | No Comments »

Hundreds if not thousands of vulnerabilities have been discovered in php based application because of the lack of filtering of input data. You can never trust a user, and verify what you are receiving.

The lack of securing input data can lead to sql injections, php injections, path disclosures, and more vulnerabilities. Some of these can be a serious risk not only for your website or a database but also to the whole server where your site is hosted. For example using mysql injection and path disclosure it’s possible to read and even write files (of course it depends on the server configuration.)

Making a quick google search I found many sites vulnerable to sql injection, for example. Searching for this in Google: inurl:”news.php?id=” will show more than half a million of sites, and about 60% of them are vulnerable at least to sql injection or path disclosure.

All these can be prevented by filtering all the input data, from $_GET, $_POST and $_COOKIE. And the most important thing is disable error reporting, as it can show a lot of information to a potential attacker.

  1. ini_set("display_errors", 0);

I suggest making a function that will handle the security check and return the needed value. Let’s see:

  1. define("AL_HTML",1);            //allows html tags as they are
  2. define("AL_NUMERIC",2);         //only numeric. If the string contains not numbers will return 0
  3. define("AL_TEXT",4);            //alfanumeric text but without html tags.
  4. define("AL_QUOTE",8);           //allow ‘ and " quotes
  5. define("AL_ALL",15);            //allow everything.
  6.  
  7. /**
  8. * getvar($name, $from, [$allow=AL_ALL]);
  9. * Read the input variable (name = $name) from $from, and filters it according to flags ($allow)
  10. * @param string $name - Name of the variable.
  11. * @param string $from - where this variable is comming from (get, post or cookie)
  12. * @param integer $allow - Flags. Can be AL_HTML - allows html tags. Doesn’t strip them
  13. *                                       AL_NUMERIC - only numbers. If the variable contains other symbols, returns 0
  14. *                                       AL_TEXT - Returns as a string but stripping the html tags.
  15.                                         AL_ALL - Allows everything. Doesn’t strip html tags. Same as AL_HTML
  16. * @return variable Can be integer or string. Depends on the flags and the variable. Returns the variable or 0 if fails.
  17. */
  18. function getvar($name, $from, $allow=AL_ALL)
  19. {
  20.         switch($from)
  21.         {
  22.                 case ‘get’:
  23.                         $var = $_GET[$name];
  24.                 break;
  25.  
  26.                 case ‘post’:
  27.                         $var = $_POST[$name];
  28.                 break;
  29.  
  30.                 case ‘cookie’:
  31.                         $var = $_COOKIE[$name];
  32.                 break;
  33.         }
  34.  
  35.         if (empty($var) || is_array($var))
  36.                 return 0;
  37.  
  38.         $result = trim($var);
  39.  
  40.         if (!($allow & AL_QUOTE))
  41.                 $result = addslashes($result);
  42.         if (!($allow & AL_HTML))
  43.                 $result = htmlentities($result);
  44.         if (($allow & AL_NUMERIC) && (!($allow & AL_TEXT)))
  45.                 $result = (int)$result;
  46.  
  47.         return $result;
  48. }
  49. ?>


Save this function into a file “funcs.php” and let’s try some tests:

  1. include(‘funcs.php’);
  2.  
  3. $_POST[‘a’] = "asdasd123";
  4. $_POST[‘b’] = "432235";
  5. $_COOKIE[‘c’] = "asd aksdjakjwd ‘asd’";
  6. $_GET[‘d’] = "4 92 asdasd <script></script>alert(’asd’);";
  7.  
  8. echo "Allow everything: ".getvar(‘a’, ‘post’)."\n";
  9. echo "Allow NUMERIC only: ".getvar(‘a’, ‘post’, AL_NUMERIC)."\n";
  10. echo "Allow HTML: ".getvar(‘a’, ‘post’, AL_HTML)."\n";
  11. echo "Allow TEXT only without HTML: ".getvar(‘a’, ‘post’, AL_TEXT)."\n";
  12.  
  13. echo "\nAllow everything: ".getvar(‘b’, ‘post’)."\n";
  14. echo "Allow NUMERIC only: ".getvar(‘b’, ‘post’, AL_NUMERIC)."\n";
  15. echo "Allow HTML: ".getvar(‘b’, ‘post’, AL_HTML)."\n";
  16. echo "Allow TEXT without HTML: ".getvar(‘b’, ‘post’, AL_TEXT)."\n";
  17.  
  18. echo "\nAllow everything: ".getvar(‘c’, ‘cookie’)."\n";
  19. echo "Allow NUMERIC only: ".getvar(‘c’, ‘cookie’, AL_NUMERIC)."\n";
  20. echo "Allow HTML: ".getvar(‘c’, ‘cookie’, AL_HTML)."\n";
  21. echo "Allow TEXT without HTML: ".getvar(‘c’, ‘cookie’, AL_TEXT)."\n";
  22.  
  23. echo "\nAllow everything: ".getvar(‘d’, ‘get’)."\n";
  24. echo "Allow NUMERIC only: ".getvar(‘d’, ‘get’, AL_NUMERIC)."\n";
  25. echo "Allow HTML: ".getvar(‘d’, ‘get’, AL_HTML)."\n";
  26. echo "Allow TEXT without HTML: ".getvar(‘d’, ‘get’, AL_TEXT)."\n";
  27. ?>

And this is the output:

Allow everything: asdasd123
Allow NUMERIC only: 0
Allow HTML: asdasd123
Allow TEXT only without HTML: asdasd123

Allow everything: 432235
Allow NUMERIC only: 432235
Allow HTML: 432235
Allow TEXT without HTML: 432235

Allow everything: asd aksdjakjwd ‘asd’
Allow NUMERIC only: 0
Allow HTML: asd aksdjakjwd \’asd\’
Allow TEXT without HTML: asd aksdjakjwd \’asd\’

Allow everything: 4 92 asdasd alert(’asd’);
Allow NUMERIC only: 4
Allow HTML: 4 92 asdasd alert(\’asd\’);
Allow TEXT without HTML: 4 92 asdasd <script>alert(\’asd\’);</scirpt>

As you can see it filters exactly every dangerous character and you can use this function to filter your variables. Example:

  1. $id = getvar(‘id’,‘get’,AL_NUMERIC); //accept only numeric values. Automatically adds slashes before single and double quotes, so it’s secure for the database.
  2. $message = getvar(‘msg’,‘post’,AL_TEXT); //strips html tags and adds slashes. Remember to strip slashes just before showing the msg after retrieving it from the db.

That’s all :)

Posted by freenity, filed under General PHP Programming. Date: March 6, 2008, 11:23 pm | 1 Comment »

I’m pretty sure you have already heard about var_dump() or print_r(). These 2 great functions are very useful to debug the code by seeing what each var, array, class or whatever has inside it….

Well the only problem is how to “save” their content to a variable or wherever, maybe to later insert it into a database for logging or debugging purposes.

As you might know var_dump() and print_r() prints the content of a var, array or class that you send them as an parameter. You don’t have to put echo nor print, they print everything by themselves. So it looks like a bit impossible to save the info in a var, but it isn’t.

You can use what is called output buffer. The output buffer is a memory that php uses to send every echo, print, var_dump, etc to. It doesn’t send the output to the browser! all the output goes to this buffer. But at the end you can get the contents of this buffer, or send it to the browser, so everything that was written there will be printed. Have a look at these functions Using them you can actually control this buffer, and that’s exactly what is used to save the output of var_dump() or print_r(). Let’s see the example:

  1. $test = array(1,2,3,4,5,6,99);
  2.  
  3. ob_start(); //start the buffer. All the output will go to this buffer.
  4. var_dump($test); //print the array using var_dump()
  5. $result = ob_get_contents(); //copy this buffer to $result.
  6. ob_end_clean(); //clean and close (remove) this buffer. From now on, the output will go to the browser.
  7.  
  8. echo "The array is: ".$result; //so we echo it to the browser.

And it works :)
But the real use for this is not to print, but insert it into a database, save in a file, or wherever. Really great for debugging and logging purposes.
Enjoy.

Posted by freenity, filed under General PHP Programming, PHP Curious Stuff. Date: March 4, 2008, 10:11 am | 1 Comment »

Ever wanted to make something like this with PHP ?

Graph

Well, today I will show and explain the script that generated this beautiful graphic.

PHP supports drawing functions with the GD library which provides many necessary image manipulation functions.

Using these functions we can actually transform the array to this graphic. The array must have no more than 30 elements, and every element is transformed to %, and printed.

  1.  
  2. /**
  3. * @param mixed $ar - Data array. Max elements = 30;
  4. * @return mixed Returns the image on success or FALSE on error.
  5. */
  6. function arraytograph($ar)
  7. {
  8.         if (!isset($ar) || empty($ar) || count($ar) > 30)
  9.         {
  10.                 return FALSE;
  11.         }
  12.  
  13.         //convert values to %. This is done by getting the maximum value of this array that will be 100%.
  14.         $hundredp = max($ar);
  15.         $newarray = array();
  16.         foreach ($ar as $el)
  17.         {
  18.                 $newarray[] = intval($el / $hundredp * 100);
  19.         }
  20.  
  21.         //create 300×150 image
  22.         $im = imagecreatetruecolor(300, 150);
  23.  
  24.         //create colors.
  25.         $col_background = imagecolorallocate($im, 0, 0, 0);
  26.         $col_grid = imagecolorallocate($im, 0×53, 0×44, 0×01);
  27.         $col_bars = imagecolorallocate($im, 0xb7, 0×6b, 0×1a);
  28.         $col_text = imagecolorallocate($im, 200, 200, 200);
  29.  
  30.         //fill with background color
  31.         imagefill($im, 0, 0, $col_background);
  32.  
  33.         //draw grid
  34.         //horizontal lines
  35.         for ($i=1; $i<=10; $i++)
  36.         {
  37.                 imageline($im, 0, $i*10+40, 300, $i*10+40, $col_grid);
  38.         }
  39.  
  40.         //vertical
  41.         $space = intval(300 / count($newarray));
  42.         for ($i=1; $i<=count($newarray); $i++)
  43.         {
  44.                 imageline($im, $i*$space, 40, $i*$space, 150, $col_grid);
  45.         }
  46.  
  47.         //and now lets draw the graphics.
  48.         for ($i=0; $i<count($newarray);>
  49.         {
  50.                 $x1 = intval($space/2) -1 + $space*$i;
  51.                 imagefilledrectangle($im, $x1, 150, $x1+3, 150-$newarray[$i], $col_bars);
  52.                 imagestringup($im, 2, $x1-5, 150-$newarray[$i]-10, $newarray[$i].‘%’,$col_text);
  53.         }
  54.  
  55.         //tell the browser that this will be a png image.
  56.         header("Content-type: image/png");
  57.  
  58.         //finally generate the image;
  59.         imagepng($im);
  60.         imagedestroy($im);
  61. }

OK, now I will explain the whole code. Here we go:

First of all we check if the array is not empty, is not null or has more than 30 elements.
Then with a for we transform the elements of the array into percentage. To do this, the max() function returns the highest element in the array, that will be 100%, and the rest is some maths =)

  1. $hundredp = max($ar);
  2. $newarray = array();
  3. foreach ($ar as $el)
  4. {
  5.         $newarray[] = intval($el / $hundredp * 100);
  6. }

Doing this the new array is generated, $newarray. This array will be used to print the info.

  1. //create 300×150 image
  2. $im = imagecreatetruecolor(300, 150);

Create an image of 300px width and 150px height.

  1. $col_background = imagecolorallocate($im, 0, 0, 0);
  2. $col_grid = imagecolorallocate($im, 0×53, 0×44, 0×01);
  3. $col_bars = imagecolorallocate($im, 0xb7, 0×6b, 0×1a);
  4. $col_text = imagecolorallocate($im, 200, 200, 200);

Here we assign 4 different colors that will be used to generate the graph. The color assignment is made using imagecolorallocate() function. This function receives the created image as the first parameter, and receives R G and B values for the color. So a RGB #534401 is converted into 0×53, 0×44, 0×01. Remember that writing 0x indicates that the number is in hex format.

  1. imagefill($im, 0, 0, $col_background);

Here the whole image is filled with $col_background color, that was previously assigned with imagecolorallocate() function.

Now the most interesting part starts, the drawing procedures.

  1. //draw grid
  2. //horizontal lines
  3. for ($i=1; $i<=10; $i++)
  4. {
  5.         imageline($im, 0, $i*10+40, 300, $i*10+40, $col_grid);
  6. }
  7. //vertical
  8. $space = intval(300 / count($newarray));
  9. for ($i=1; $i<=count($newarray); $i++)
  10. {
  11.                 imageline($im, $i*$space, 40, $i*$space, 150, $col_grid);
  12. }

Here we draw a grid. It’s made of vertical and horizontal lines, so first we draw 10 horizontal lines, 1 line each 10 pixels, that will represent %; And then we draw vertical lines. The amount of those lines is determined by the amount of elements in the array, they may be 10, 20 or 5, so it’s calculated on the fly.
The interesting part is how the coordinates are calculated, and to draw the line GD provides us with a useful function imageline(). This function receives the image return by imagecreate() as the first parameter. Start x, and y position and Finish X and Y; and the last parameter is the color.
Be aware that the coordinates system in GD is the same as in all other graphic libraries, that is the top right corner is 0,0 and it gets incrementing to the right and bottom. So the most bottom left corner will be 300,150 in this case.

  1. for ($i=0; $i<count($newarray);>
  2. {
  3.         $x1 = intval($space/2) -1 + $space*$i;
  4.         imagefilledrectangle($im, $x1, 150, $x1+3, 150-$newarray[$i], $col_bars);
  5.         imagestringup($im, 2, $x1-5, 150-$newarray[$i]-10, $newarray[$i].‘%’,$col_text);
  6. }

With these lines we calculate and draw the bars, that will make the whole graph, and the legend of how many percents is each bar.
Here there are 2 new functions: imagefilledrectangle() and imagestringup()
The first one draws a filled rectangle, and the parameters are the same as imageline()’s.
imagestringup() is the function that “draws” the text on the image, but it doesn’t draw it in usual way, it draws it vertically. It receives the image returned by imagecreate(), the second parameter is the font size, here we use 2, the third and fourth parameters are the X,Y coordinates. Here I subtract 5, from $x1 just to center the legend; the next parameter is the string itself to be drawn, and at last, the color.

With all these done, we can send the generated image to the browser:

  1. header("Content-type: image/png");
  2.  
  3. //finally generate the image;
  4. imagepng($im);
  5. imagedestroy($im);

The first line send a header to the browser telling him, that it will send a png image. Then with imagepng() All we have drawn is converted into the png format and sent to the browser. The last thing is imagedestroy() the image.

Well, thats all as for the drawing function.
This is an example of how to use this function:

  1. include ‘arraytograph.php’;
  2.  
  3. for ($i=0;$i<16;$i++)
  4.         $ar[] = rand(0,350);
  5.  
  6. arraytograph($ar);
  7. ?>

Posted by freenity, filed under General PHP Programming, Graphics using GD. Date: February 29, 2008, 3:33 pm | 8 Comments »

One day I saw an interesting poll on phpfreaks.com

Basically it is about what is better to use SELECT DISTINCT or SELECT … GROUP BY. Well that’s what I’m going to solve today :) Benchmarking it!

For this test I created 1 table like this:

  1. CREATE TABLE `testing`.`benchmarking` (
  2. `id` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
  3. `value` INT( 10 ) NOT NULL
  4. ) ENGINE = MYISAM

And a php script that inserted 20.000 rows into this table with random values from 1 to 10. I chose only 10 different values because so there will be more equal values and the benchmarking will be more interesting :)

  1. $con = mysql_connect(‘localhost’, ‘user’, ‘pass’);
  2. mysql_select_db(‘testing’,$con);
  3.  
  4. for ($i=0; $i<20000; $i++)
  5. {
  6.         $v = rand(1,10);
  7.         mysql_query("INSERT INTO benchmarking VALUES (”,$v)",$con);
  8. }
  9.  
  10. ?>


After executing this script we have an already ready to be tested table with random values.
What I will do now, is making a php script which will make 2.000 SELECT DISTINCT ’s and of course it will measure the total execution time using time() because it will take several seconds to execute it. The second part of the script will make 2.000 SELECT ’s but with GROUP BY `value` statement, it will measure the execution time of these selects as well and show the comparaison between those 2 times. So here is this script:

  1. $con = mysql_connect(‘localhost’, ‘user’, ‘pass’);
  2. mysql_select_db(‘testing’,$con);
  3.  
  4. $starttime = time();
  5. for($i=0; $i<2000; $i++)
  6. {
  7.         mysql_query("SELECT DISTINCT `value` FROM benchmarking",$con);
  8. }
  9. $endtime = time();
  10.  
  11. $first_test_duration = $endtime - $starttime;
  12.  
  13. echo "First test done. Duration = {$first_test_duration} \n";
  14.  
  15. $starttime = time();
  16. for($i=0; $i<2000; $i++)
  17. {
  18.         mysql_query("SELECT `value` FROM benchmarking GROUP BY `value`",$con);
  19. }
  20. $endtime = time();
  21.  
  22. $second_test_duration = $endtime - $starttime;
  23.  
  24. echo "Second test done. Duration = {$second_test_duration} \n";
  25. ?>

OK, so now all to be done is execute the script several times and look at the results:


[root@localhost Desktop]# php benchmarking.php
First test done. Duration = 37
Second test done. Duration = 31
[root@localhost Desktop]# php benchmarking.php
First test done. Duration = 41
Second test done. Duration = 35
[root@localhost Desktop]# php benchmarking.php
First test done. Duration = 34
Second test done. Duration = 30
[root@localhost Desktop]# php benchmarking.php
First test done. Duration = 30
Second test done. Duration = 28
[root@localhost Desktop]# php benchmarking.php
First test done. Duration = 31
Second test done. Duration = 31

btw. those numbers are seconds.
So here I ran the testing program for 5 times, just to be sure it gives right information and guess what
The winner is … GROUP BY. In 4 tests it had inferior time and only in the last test both group by and distinct had equal times.

Conclusion: of course the difference between those 2 is minimal, only a couple of milliseconds or less, it can make some difference when managing big amounts of data.

Posted by freenity, filed under SQL. Date: February 26, 2008, 2:49 pm | 3 Comments »

I guess I’m not the only one that had this problem. One day I needed to make a registration script that sends confirmation email to the user before activating it. Well, I made that script, the whole confirmation system and of course the mailing function that would send an email to the user. And yes, I tested it with GMail and it worked just fine, but when I tried to test it with my hotmail account…. :s The e-mail didn’t arrive to the inbox, it didn’t even arrive to the spam box. It just didn’t arrive at all :|

After a quick google search (about 2 days) which didn’t help me, there were so many results and no *** working function…. I was wondering how do other people do it??? And I remembered about the phpBB3 forum I have. I rushed there at once and registered with my hotmail account, and guess what!? The e-mail arrived safe and sane to the hotmail inbox. So I decided that those guys definitely knew how to do it this stuff and I just had a quick look at the phpBB3 mailing function :)


So I post it here, just the essential parts, I removed a lot of code, but it still works great. Enjoy:
(Sends plain text messages, no html)

  1. /**
  2. * sendmail($to. $subj, $frommail, $msg);
  3. * @param string $to Email address of the receiver
  4. * @param string $subj Subject
  5. * @param string $frommail E-mail address of the sender
  6. * @param string $msg Message body
  7. * @return bool TRUE - on success; FALSE - on error
  8. */
  9.  
  10. function sendmail($to, $subj, $frommail, $msg)
  11. {
  12.     //Please change these values.
  13.     $domain = ‘mydomain.com’;    //this is your domain name, from where you will be sending emails, without http:// or www
  14.     $mailname = ‘mycoolemail’; //this is the account name of your e-mail address. (mycoolemail@mydomain.com) This is used to send e-mails from this address
  15.  
  16.     $headers = array();
  17.     $headers[] = ‘From: ‘ . $frommail;
  18.     $headers[] = ‘Reply-To: ‘ . $frommail;
  19.     $headers[] = ‘Return-Path: <’.$mailname.‘@’.$domain.‘>’;
  20.     $headers[] = ‘Sender: <’.$mailname.‘@’.$domain.‘>’;
  21.     $headers[] = ‘MIME-Version: 1.0′;
  22.     $headers[] = ‘Message-ID: <’ . md5(time()) . ‘@’.$domain.‘>’;
  23.     $headers[] = ‘Date: ‘ . date(‘r’, time());
  24.     $headers[] = ‘Content-Type: text/plain; charset=UTF-8′;
  25.     $headers[] = ‘Content-Transfer-Encoding: 8bit’;
  26.     $headers[] = ‘X-Priority: 3′;
  27.     $headers[] = ‘X-MSMail-Priority: Normal’;
  28.     $headers[] = ‘X-Mailer: freenity’;
  29.     $headers[] = ‘X-MimeOLE: freenity’;
  30.     $headers = implode("\n",$headers);
  31.  
  32.     if (mail($to, $subj, $msg, $headers))
  33.     {
  34.         return TRUE;
  35.     }
  36.     else
  37.     {
  38.         return FALSE;
  39.     }
  40. }

^^ and know what, the hotmail problem was because of all those headers I didn’t put in my first code :)

Posted by freenity, filed under General PHP Programming. Date: February 25, 2008, 2:37 pm | 1 Comment »

Hello and welcome to this little yet another blog :)

I know you will ask what is special about this blog, well hold on, you will see everything a bit later, but now I will explain some things that I will put here.

Well first of all, this blog will be completely dedicated to web technologies (PHP, MySQL, JavaScript, AJAX, CSS, Tableless designs, etc) and will include some really interesting php and programming topics.

What I need from you is to comment, discuss and participate.

Good luck and enjoy this blog ;)

Posted by freenity, filed under General. Date: February 24, 2008, 4:27 pm | 3 Comments »