Nginx, SSL & php5-fpm on Debian Wheezy

October 11th, 2014

I decided to take a break from my love affair with Apache and set up a recent development project on Nginx. I’ve seen nothing but good things in terms of speed and performance from Nginx. I decided to set up a LEMP server (Linux, Nginx, MySQL, PHP), minus the MySQL as it’s already installed on my VM host server, and plus SSL. Here’s the full setup tutorial on Debian Wheezy:

Step #1 – Installing the packages

apt-get install nginx-extras mysql-client
apt-get install php5-fpm php5-gd php5-mysql php-apc php-pear php5-cli php5-common php5-curl php5-mcrypt php5-cgi php5-memcached

MySQL can be installed into the mix with a simple:

apt-get install mysql-server

Read the rest of this entry »

MySQL Master-Master Replication, Heartbeat, DRBD, Apache, PHP, Varnish MegaHOWTO

October 8th, 2014

I created this HOWTO while building a new development environment today. The intention is to take a single Apache2/Varnish/MySQL environment and scale it to two servers, with one effectively a “hot-standby” – increase redundancy and continuity whilst maintaining current performance. This HOWTO is based on Linux Debian-76-wheezy-64-minimal 3.2.0-4-amd64 #1 SMP Debian 3.2.60-1+deb7u3 x86_64

Our current server has IP 192.168.201.1/24 and our new server has IP 192.168.201.7.

Section #1: Set up MySQL Master/Master Replication


First, we’ll set up MySQL master to master replication. In this configuration, data can be written and read from either host. Bear in mind that issues may exist with autoincrement fields when written to at the same time. There are other caveats with replication so ensure to research them along with how to deal with corruption and repair before considering this setup for a live application. Also be sure to be using the same version of MySQL on both servers – this may not always be necessary, however unless you are very familiar with any changes between versions, not doing so could spell disaster.

Read the rest of this entry »

Location header is optional not mandatory

September 13th, 2013

I thought I’d write a short post about this issue as I’ve seen it come up a couple of times in PHP code audits. The incorrect assumption is that the Location header somehow forces a browser or forces execution to move elsewhere.

Take a look at the following code sample –

<?php
	$logged_in = 0;

	/* Do login verification routine here */

	if (!$logged_in)
	{
		/* User is not logged in and shouldn't be here */
		header("Location: /index.php");
	}
	/* User is logged in */
	echo "Secret Member Content";
?>

Read the rest of this entry »

mysql_real_escape_string won’t magically solve your SQL Injection problems

August 18th, 2013

Edited: 5th Oct 2014 after bug fixing and reader feedback
Edited: 6th Oct 2014 after reader feedback

I was engaged by an online retailer to test their custom web application CMS and store. I attended their premises and sat down with the tech manager and his lead developer to discuss with them from both a business management and a technical perspective some of the vulnerabilities that should be tested for, as well as to gain a solid understanding of the business needs and logic.

When I came on to SQL injection, I was assured by the lead developer that owing to their secure coding practices, SQL injection is completely impossible. All expected user entered integers are cast as integers, and all expected user entered strings are run through mysql_real_escape_string before being passed back to the database. Once code is committed by a developer to the development Subversion server, the lead developer then manually reviews it before deciding to push it live. Great, I thought, it’s certainly a good start. I did point out that this might not always work, but he didn’t seem too phased, and I didn’t want to get too much into a discussion about why or when that might not always work at that stage.
Read the rest of this entry »

PHP Local and Remote File Inclusion (LFI, RFI) Attacks

August 15th, 2013

PHP supports the ability to ‘include’ or ‘require’ additional files within a script. If unsanitized data is passed to such functions, an attacker may be able to get remote code execution access to the server. A typical include block might look something like this:

<?php
require("config/settings.inc.php");
require("lib/db.lib.php");
require("lib/parser.lib.php");
include("contrib/users/user.contrib.php");
die("This is a test");
?>

Now, it’s also possible to dynamically require or include files based on variables or user input, say for example:
Read the rest of this entry »

Going Retro With PHP – A Hits Counter Step By Step

January 11th, 2012

Going Retro With PHP – A Hits Counter Step By Step

It wasn’t all that long ago that the web was littered with little “number of visitor” indicators. The point of these was either to show how popular your site was, or more likely just because the site owner had no administrator level site statistics program running. Now most sites have a sophisticated statistics system or other means of counting visitors and these visible counters have become less popular. It will still be a good learning experience to try making a script for counting visitors from scratch.

A simple function to detect a valid page load might look like this

function log_page_load(){
    $invalid_list = '/(googlebot|crawler)/i'; //set a regular expression that detects invalid agents like googlebot
    if (preg_match($invalid_list, $_SERVER['HTTP_USER_AGENT'])){
    // it is a bot
    }else{
    // it is probably a browser
    }
}

As you can see we are erring on the side of caution, making browsers the default for most possible strings. That is because there are probably countless possible browsers now with cell phones and other devices included. There’s no easy way to tell bot from human computer user there may be no perfect method that is always right. There definitely are techniques that are pretty accurate compared to what I show above but they are beyond the scope of this article.

Once we have decided the request is a real pageview we can get on with the reading and saving of data.

$filename = "counterfile.dat";
if(file_exists ($counter_file)){
    $counter_file = fopen($filename, 'r+');
    $total_count = trim(fread($counter_file, filesize($filename)));
}else{
    $counter_file = fopen($filename, 'w');
    $total_count = 0;
}
//other code here
...
//save file
ftruncate($counter_file,0);
fwrite($counter_file, $total_count);
fclose($counter_file);

First we opened the file, but since it may not exist we check that, and create it if it doesn’t (opening with w will do that). Otherwise it should work fine to read it. To save it we erase it (ftruncate($counter_file,0)) and write new data, which is just a number. In the next example let’s combine all that we have covered.

function log_page_load(){
    $filename = "counterfile.dat";
    if(file_exists ($counter_file)){
        $counter_file = fopen($filename, 'r+');
        $total_count = trim(fread($counter_file, filesize($filename)));
    }else{
        $counter_file = fopen($filename, 'w');
        $total_count = 0;
    }
    $invalid_list = '/(googlebot|crawler)/i'; //set a regular expression that detects invalid agents like googlebot
    if (!preg_match($invalid_list, $_SERVER['HTTP_USER_AGENT'])){
        //it is a brower. probably. increment and save.
        $total_count++;
        ftruncate($counter_file,0);
        fwrite($counter_file, $total_count);
    }
    fclose($counter_file);
    if(!trim($total_count))
        $total_count = 0; //let's make sure it is a 0 if it somehow was set to a blank string
    return $total_count;
}
echo "val= ". log_page_load(); //each load you get 1, 2, 3, 4

so there you have it, define the function and either capture the return value for later or print it as shown.
Isn’t there something missing though? Most of the counters are graphical since they are used on sites that have no scripting. How can we get graphics instead of just numbers as a text string? There are many ways, but try this on for size.

$page_loads = log_page_load(); //logs once and also return the new value
$page_l_str = strval($page_loads);
$icons = "";
for($i = 0; $i < strval($page_l_str); $i++){
    $icons .= '<imr src="images/' . $page_l_str[$i] . '.gif" />';
}
echo $icons;

that will produce image tags with the pattern <imr src=”images/1.gif” /> and so on. $page_l_str[$i] means get the letter with index $i.
Of course you might also wish to zero padd it or instead of images use <li>$page_l_str[$i]</li>, there are a limitless variety of possibilities with modern css and php.

To take this a step further you might want to build in counting of visitors instead on top of pageviews. That would be done by recording $_SERVER[‘REMOTE_ADDR’] and checking if the visitor has been there recently. You could use 2 counters for hits and unique hits, or some other combination. That’s all I will cover here though so that concludes the article on hit counters, I hope it has been informative.

Custom Math High and Low Functions in PHP

January 11th, 2012

This should be a good beginner tutorial, especially if you have used some functions and if statements and haven’t gone much further. I will explain the concept as we go along, first let’s review the Ternary Operator / Operators that we will use.

$x = $y < 0 ? -1 : 1;

That is sort of a quick “what is the sign” test for signed numbers. If means if y is less than 0 x is negative 1, otherwise it is positive 1. 0 is considered +1 in that case. Following so far? You just need to understand the basic rules so you can understand what is happening in a complex line of code.

$x = $y == 0 ? 0 : ($y < 0 ? -1 : 1);

In that case it mean if y is 0 x is 0, otherwise x is either -1 or +1. Let’s use that principal to make a function that accepts 3 arguments and tells us whether argument 1 is within the bounds of arguments 2 and 3.

function custom_clamp_check($number, $low, $high){
    return $number > $high ? false : ($number < $low ? false : true);
}

Think about that function like this, if the first statment is true, we return false, if it isn’t we check the second statment. The function returns false unless the $number is between $high and $low or equal to either. This is intentionally written to work well with floats and integers. Other variable types should not be used.

PHP has built in min and max functions like in this example.

$x = min($y, 0);
$x = max(5, 12);

That just gives you the higher number of the two numbers put into the function. Actually you can do max(1, 4, 99, -5) since it allows more arguments, or max(array(1, 4, 99, -5)) with the same result. It returns the highest of whatever is put in. I don’t know if min/max have many pros or cons over statements like we used earlier, but some users have said min/max are slower and less efficient. Regardless of that this article is focusing on using operators in statements to construct the desired functions, even if only for learning purposes.

Our final function is a clamp function, it clamps the value entered to be equal to $high, equal to $low, or between the two.

function custom_clamp($number, $low, $high){
    return $number > $high ? $high : ($number < $low ? $low : $number);
}

You should now understand how the function works and what the results will be. custom_clamp(1.0115, 1.0, 0.0) would give you 1.0, the exact high value you put in. These functions are useful for many things, and as I described earlier we can use integers or floats. If a user entered a comment we could check if it’s length is within the range we want.

if(custom_clamp_check(strlen($_GET['comment']), 20, 512) == false){
    return "Your comment must be 20 to 512 chars in length.";
}

If the user must also enter a number within 1 and 10 and we want to make sure there are no other numbers possible, we could force it with the clamp function.

$entered_number = custom_clamp(intval($_GET['number']), 1, 10);

I added intval to make this even more strict, since users could have entered 1.0002 and we probably only want whole numbers. The final use shows how useful the function can be in math. The goal is to keep the product above 0 since dividing by zero is not acceptable.

$angle = 1.0 / custom_clamp($radius * pi(), 0.0000001, 1.0);

PHP – What in the world is CType

January 7th, 2012

Apparently the name comes from ctype.h, a file in the C programming language. The PHP engine can execute the code from that file in it’s ctype functions. Does the c in ctype stand for classification, or character maybe? I don’t know, but according to PHP, these functions “are always preferred over regular expressions, and even to some equivalent str_* and is_* functions.” because they are executed from the executable functions (from ctype.h) and are therefore faster.

$is_it_alphanumeric = ctype_alnum("Carnival101"); //true
$is_it_alphanumeric_too = ctype_alnum("Carnival*_*");//false
$is_it_alphanumeric_also = ctype_alnum("Carnival1.01"); //false

ctype_alnum() checks if the string is totally alphanumeric. The first of those was the only one, a decimal is still not going to return true. Checking if things are alphanumeric is actually pretty useful, but it’s probably more common to check if it is an unsigned integer for example.

$is_it_digit = ctype_digit("05909090"); //true
$is_it_digit_too = ctype_digit(-4); //false
$is_it_digit_also = ctype_digit(4.5); //false

So only 0s to 9s will get you a true result. Positive integers will also work. ctype_alpha() is the same as those 2 but for letters only. Going back to ctype_alnum, it also accepts integers but “If an integer between -128 and 255 inclusive is provided, it is interpreted as the ASCII value of a single character ” So if you aren’t interested in ASCII tests don’t pass integers to ctype_alnum(). That rule applies to the next function as well, called ctype_print();

ctype_print("asdfnrt"); // false

ctype_print() only returns true if the characters are printable and not control characters. This is a confusing classification, since spaces would be allowed and tabs not. Only use it if you are looking for a very specific type of check. ctype_graph() might be more clear, as it is the same but spaces are not valid, no white space is allowed. ctype_cntrl() is the opposite of ctype_print(), the characters must be control characters to get it to return true.

ctype_lower() returns true for lowercase letters only
ctype_punct() returns true for punctuation only
ctype_space() returns true for white space only (tab, space, newline and so on)
ctype_xdigit() returns true for hexidecimal characters only (comes in useful for checking if the string is a color code for example)
ctype_upper returns true for uppercase letters only

For all these functions, empty strings will give you false in new versions of PHP, but true in older versions (< 5.1). Passing something other than an integer or string will return false.

In PHP gzcompress is easy, and often useful

January 6th, 2012

xœKLJNIMK Û½

That is what I got when I ran the following code:

echo gzcompress("abcdefg");

In the title I said “often useful”. If you look closely you’ll see why. The compressed version takes more bytes than the uncompressed. It’s not a surprise of course, the feature was created for compressing a file or something of considerable size, at least with a bigger size than 7 bytes (though characters may or may not take up a byte each I suppose…).

echo strlen(gzcompress("A camel is an even-toed ungulate within the genus Camelus, bearing distinctive fatty deposits known as humps on its back. There are two species of camels: the dromedary or Arabian camel has a single hump, and the bactrian has two humps. Dromedaries are native to the dry desert areas of West Asia, and Bactrian camels are native to Central and East Asia. Both species are domesticated; they provide milk and meat, and are working animals. "));

There, we printed the compressed versions size. I measured 258 chars for compressed and 2439 for the uncompressed version. That’s not even a very large chunk of text, so clearly gzcompress() will give a good reduction in almost all situations. As for how to uncompress:

$gz_string = gzcompress($reg_string);
echo strlen($gz_string);
$un_reg_string = gzuncompress($gz_string);
echo strlen($un_reg_string);

So to sum it up you won’t have any problems as long as you use strings not arrays for example. Compressing and uncompressing them in very useful and it’s great the PHP makes it so easy. Be sure to check out PHP’s other compression capabilities too.

Parsing XML in PHP

December 7th, 2011

I’m sure many php users have needed to read some xml data into a php program and looked around hoping to find a function that can parse an XML file with a few lines of code. The road to simple XML usage may not be that short, but we’ll explore some techniques to get the data you want from an xml source.
First define some xml:

$contents = ‘
<rss version=”2.0″>
<channel>
<item>
<title>Orange Cat</title>
<link>http://www.phpprogrammer.co.uk/</link>
<description>A nice tabby.</description>
</item>
<item>
<title>Black Cat</title>
<link>http://www.phpprogrammer.co.uk/</link>
<description>A shy cat.</description>
</item>
</channel>
</rss>
‘;

Then parse the XML with this PHP code:

$parser = xml_parser_create('UTF-8');
$did_parse = xml_parse_into_struct($parser, trim($contents), $xml_values);
if(!$did_parse) {
	echo xml_error_string(xml_get_error_code($parser)) . " error on line: " . xml_get_current_line_number($parser);
}

The above example takes an “XML document”, in the form of a string, and parses it into an array ($xml_values). The array style and structure is complicated, but we will go through some simple steps to rearrange it into a usable format. $parser is an object. Functions like xml_parse_into_struct($parser … ) take $parser as an argument.
Read the rest of this entry »

Simplifying PHP string reading with sscanf()

December 6th, 2011

In this article we’ll see how to use sscanf() to read or parse a string in a customized way. You may have heard of the scan series of functions before, especially in other types of programming. In c based console applications that could read user input and then print text results, scan was the opposite of print. That only has a little bit to do with the function we will be talking about here.

sscanf() isn’t something you will use every day. You could try to pick apart strings with other standard string functions, or use variations on preg_match() or preg_replace(). Regardless there are situations where any of these methods might be best. The first example of sscanf will be pretty simple;

$scanned_float = 0.0;
sscanf("9.64", "%f", $scanned_float);
echo $scanned_float;

You may have guessed that $scanned_float now equals 9.64. The first parameter is the string to be read. The second is a format string based on the format used by the printf() function. Any additional arguments will be filled with values computed from the function, in order. In this case the format means 1 float value. There is one variable to receive it, $scanned_float.

$scanned_float = 0.0;
sscanf("height: 9.64", "%f", $scanned_float);
echo $scanned_float;

Read the rest of this entry »

HTML Character Codes in PHP

December 6th, 2011

PHP is a language that is highly associated with outputting HTML so that the output is shown properly in a browser. If you send the browser text with no context and no concerns for whether it is in HTML format the results are problematic and hard to predict. To format text into HTML there are many conversions that may be needed. A simple example would be converting newlines to <br /> tags. There is a well know PHP function for that of course, nl2br(). If your text uses < somewhere it also needs to be converted since HTML browsers would think it is the start of a tag. &lt; is the correct representation of < in HTML.

echo htmlspecialchars('In "real" math, 5 < 5.1');

Read the rest of this entry »

String Comparison in PHP – When are strings equal

December 6th, 2011

It’s simple enough to check if strings are exactly equal in PHP, just use ==, the standard comparison operator. However, this assumes we are only using strings or string type variables. It is a case sensitive comparison only. In this short article we are going to go though some alternate string comparison options and learn what they are good for.

First is exact type comparison, ===

$str1 = "100DollarsCash";
if($str1 == 100) {
	echo "it equals 100. ";
}
if($str1 === 100) {
	echo "it is 100. ";
}

Read the rest of this entry »

PHP Sessions – Let’s Start from the Beginning

December 6th, 2011

You don’t need to know about cookies (though we have an article on cookies here) to get through this article or to use sessions. Just keep in mind that they usually automatically use and set cookies, and like cookies you have to do certain things before the first output is sent (including doctype, <html>, or any whitspace).

The main thing you need to do is start a session before output is started. Also, for those familiar with it, output buffering can help give you more flexibility with where session_start() or setcookie() are used.

session_start();

Read the rest of this entry »

Cookies – PHP can help with cookies

December 6th, 2011

Cookies are a long standing method of storing information so it can be used again on a per user basis. Prior to database and server based sessions becoming popular cookies saw use in more complex ways. There are still a component of sessions and used on most web sites, from shopping carts to web mail. In PHP it isn’t hard to get started with cookies.

setcookie("UserInfo", "3644 Alder St", time() + 3600, "/~phppro/", "iodigitalsec.com");

That example shows an example of setting the cookie UserInfo to a street address.
Read the rest of this entry »