Questions from the Field: Should I Escape My Input, And If So, How?

At last weekend's PHP Benelux I gave a tutorial titled "From SQL to NoSQL". Large parts of the tutorial covered using MongoDB—how to use it from PHP, schema design, etc. I ran a little short of time, and since then I've been getting some questions. One of them being: "Should I escape my input, and if so, how?". Instead of trying to cram my answer in 140 characters on Twitter, I thought it'd be wise to reply with this blog post.

The short answer is: yes, you do need to escape.

The longer answer is a bit more complicated.

Unlike with SQL, inserting, updating and deleting data, as well as querying data, does not require the creation of strings in MongoDB. All data is always used as a variable or a constant. Take for example:

<?php
$c = (new MongoClient())->demo->col;
$c->insert( [ 'name' => $_GET['name'] ] );
?>

Because we don't need to create a string with the full insert statement, there is no need to escape with ' to prevent issues like SQL injections. The context in which variables are used is immediately clear.

But be aware that PHP's request parameters (GET, POST, COOKIE, and others) allow you to send not only scalar values, but also arrays. If we take the example code from above in mind, and request the URL http://localhost/script.php?name[first]=Derick&name[last]=Rethans, we end up inserting the following document into the collection:

[ 'name' => [
        'first' => 'Derick',
        'last' => 'Rethans'
] ]

And this is probably not what you had in mind.

The same trick is possible when doing queries. Look at this code:

<?php
$c = (new MongoClient())->demo->col;

$r = $c->findOne( [
        'user_id' => $_GET['uid'],
        'password' => $_GET['password']
] );
?>

If we now would request the URL http://localhost/script.php?uid=3&password[$neq]=foo we end up doing the following query:

<?php
$c = (new MongoClient())->demo->col;

$r = $c->findOne( [
        'user_id' => '3',
        'password' => [ '$neq' => 'foo' ]
] );
?>

The password clause in that query, will likely always match. Of course, if you are not storing passwords as a hash, you have other problems too! This is just a simple example to illustrate the problem.

This same example highlights the second issue - that is that all request parameters are always represented by strings in PHP. Hence my use of '3' instead of 3 in the above example. MongoDB treats '3' and 3 differently while matching, and searching for 'user_id' => '3' will not find documents where 3 is stored as a number. I wrote more extensively about that before.

So although MongoDB's query language does not require you to build strings, and hence "escape" input, it is required that you either make sure that the data is of the correct data type. For example you can do:

<?php
$c = (new MongoClient())->demo->col;

$r = $c->findOne( [
        'user_id' => (int) $_GET['uid'],
        'password' => (string) $_GET['password']
] );
?>

For scalar values, often a cast like I've done above, is the easiest, but you might end up converting an array to the string 'Array' or the number 1.

In most cases, it means that if you want to do things right, you will need to check the data types of GET/POST/COOKIE parameters, and cast, convert, or bail out as appropriate.

Shortlink

This article has a short URL available: http://drck.me/escinput-bm4

Comments

While relatively obvious to most Mongo users it's still a good summary. Everyone should burn this into his/her mind :)

Code Coverage: Finding Paths

Picking up from where we left last time, in this second article we will look at some upcoming functionality in Xdebug. Sebastian has been pressuring me for years to add branch and path coverage to Xdebug, with issue #1034. In the post I will show you what "branch and path coverage" is, and how it helps.

In the previous post, I showed you a trivial script as an example for code coverage. Let's have a look at a different script this time (article2-test.php):

<?php
function ifthenelse( $a, $b )
{
        if ($a) {
                echo "A HIT\n";
        }
        if ($b) {
                echo "B HIT\n";
        }
}

We now run this through PHP CodeCoverage (article2.php):

<?php
require 'vendor/autoload.php';
include 'article2-test.php';

$coverage = new PHP_CodeCoverage;

$coverage->start('coverage1');
ifthenelse( true, false );
$coverage->stop();

$coverage->start('coverage2');
ifthenelse( false, true );
$coverage->stop();

$writer = new PHP_CodeCoverage_Report_HTML;
$writer->process($coverage, '/tmp/code-coverage-article');
?>

Which outputs:

And this nicely tells you that all your lines have been executed. However, you have not tested everything. With two if statements, there are four possible paths through your code:

$a

$b

false

false

false

true

true

false

true

true

But we have only tested for the second and the third cases. Because we are doing line coverage, this sort of coverage issues don't show up. In order to address this, we need to do branch and path coverage.

I wrote in the previous article that Xdebug follows all branches to find dead code during code coverage, but it never did really more with that. So, again, I started experimenting through VLD to see how I could get it to list all possible branches (easy) and paths through a function or method.

So now VLD would say the following (besides dumping the opcodes) about the code:

filename:       /home/httpd/html/test/xdebug/code-coverage/article2-test.php
function name:  ifthenelse

…

branch: #  0; line:     2-    4; sop:     0; eop:     4; out1:   5; out2:   8
branch: #  5; line:     5-    6; sop:     5; eop:     7; out1:   8
branch: #  8; line:     7-    7; sop:     8; eop:     9; out1:  10; out2:  13
branch: # 10; line:     8-    9; sop:    10; eop:    12; out1:  13
branch: # 13; line:    10-   10; sop:    13; eop:    14; out1:  -2
path #1: 0, 5, 8, 10, 13,
path #2: 0, 5, 8, 13,
path #3: 0, 8, 10, 13,
path #4: 0, 8, 13,
End of function ifthenelse

It's a bit difficult to see what goes on here, but in general there are five branches and four paths. The first two branches (0 and 5) are for the first if statement, the second two branches (8 and 10) are for the second if statement and the last branch (13) is the end of function, with an implicit return to the calling function. Branches are named after the opcode entry that forms the start of a branch.

Seeing the different branches is probably easier to see in a graph, which VLD can also produce (using the vld.save_paths=1 php.ini setting). This produces a paths.dot file in /tmp which we can convert to an image with GraphViz' dot tool:

dot -Tpng /tmp/paths.dot > /tmp/paths.png

And then this graph looks like:

With the functionaly added to VLD, the next step was adding this code to Xdebug. Xdebug needs to know about all the paths, but also need figure out which branches and paths are actually followed. It needs to overload every opcode (PHP's smallest execution unit) handler, as any of them could be at the start of a branch. Overloading each opcode handler makes running your code, a lot slower unfortunately when with branch/path coverage is enabled.

AlthoughPHP_CodeCoverage does not support it yet, it is possible to visualize the new path coverage with help from some helper scripts in Xdebug's contrib directory. As a similar example as above, the test script would look like:

<?php
require '/home/derick/dev/php/xdebug-xdebug/contrib/branch-coverage-to-dot.php';
include 'article2-test.php';

xdebug_start_code_coverage(
        XDEBUG_CC_DEAD_CODE |
        XDEBUG_CC_UNUSED |
        XDEBUG_CC_BRANCH_CHECK
);

ifthenelse( true, false );

ifthenelse( false, true );

$info = xdebug_get_code_coverage();
file_put_contents('/tmp/paths.dot', branch_coverage_to_dot( $info ) );
?>

This again creates a paths.dot file that we can convert to an image just like above:

dot -Tpng /tmp/paths.dot > /tmp/paths-covered.png

And then this graph looks like:

This clearly shows we have only covered two of the four possible paths through this particular function. PHP_CodeCoverage has not been updated yet to include this new functionality, so I made a mock-up in the mean while:

Now it's just waiting until Sebastian (or somebody else) has time to upgrade PHP_CodeCoverage to show the branch and path coverage. Happy hacking!

Shortlink

This article has a short URL available: http://drck.me/pathcoverage-blb

Comments

That's a very cool change. Wishing you all the best in having it implemented. I can't wait until I have to write exponentially more tests.

Has an issue already been opened for this over at the PHPUnit github repo? That might help to raise visibility, or allow people who want it bad enough to add a bounty to it (https://www.bountysource.com/ comes to mind, amongst others...)

From how i read it, and looking at the linked issue, this already has been implemented (Oh happy joy!)

Now Derick can start bugging Sebastian in return :)

@Oneway I think we mean the same thing... that this has not yet been implemented in PHPUnit_CodeCoverage. Unless I am missing something in which case I would love to know the issue URL :-)

Whisky Advent: part 4

December 19th: GlenDronach Parliament 21

This is another bottle that I got given as a gift for Xdebug. It is a 21 year old whisky from the GlenDronach distillery. This GlenDronach Parliament has been matured in a combination of Oloroso and Pedro Ximinez sherry casks. It is a bit stronger at 48% ABV.

Tasting notes: Very dark colour. Also very sweet, a tad spicy and hints of plums and other fruits. The sherry flavours are have a big overtone, but don't over power. The whisky ends with an oaky finish. A drop of water doesn't really help.

December 20th: Springbank 15

Tonight we have a Springbank 15, bought as a set of minatures from Cadenhead's to give away as wedding favours. As it is exactly six months ago since we got married, that seemed to be a fitting whisky to include. It is a Campbeltown whisky and not particularly special, but it reminds me of good times past. It was of course also quite nice of Cadenhead's to provide the minatures with a label with our names on it!. And, we did try out which whisky to pick as favours. We've tried a Springbank 10, 12 and 15, but the 15 year old won. Although I think we liked the 10 over the 12.

Tasting notes: Caramel, Vanilla, malty with some smokyness. Lingers long on the tongue with hints of pepper, and a flavour that sits all over the tongue. Well balanced.

December 21th: Cradle Mountain from Cadenhead

Another unusual whisky. Tonight's Cradle Mountain 15 is distilled by Small Concern Whisky Distillery, a distillery in Tasmania. It is bottled by Cadenhead at 57.9% ABV as part of their World Whiskies series. It has been aged for 15 years in ex. Jim Beam Bourbon Barrels. It is one of 186 bottles, and as you would expect with a single cask whisky, it does not have colouring added, or has it been chill-filtered.

Tasting notes: Very much in your face. It's sweet and syrup, but also oaky. The bourbon certainly has made its impression on this one. I would almost go as far as saying that it has more of a liqueur flavour to it than a "normal" whisky. It gets better with a drop of water, and the finish is long lingering with tropical fruits.

December 22nd: Highland Harvest Organic Batch 003

A bottle that I got as a birthday gift, which is fitting as today is my birthday! This whisky is certified organic and a blend of 7 casks. Each batch is a unique expression. This is batch 003 of this Highland Harvest whisky. It is bottled at 40% ABV.

Tasting notes: The colour is very pale. It's quite light, a little smoky and a taste of oak is very apparent. It's quite sharp, but also watery. The after taste is not very long, but what there is, is oak. I think this whisky should be aged more, as there is unfortunately very little character to it.

Morag says: It smells like blue cheese, and it would probably work great as a cocktail whisky.

December 23nd: The English Whisky 2010 - Chapter 9

Tonight's whisky is a dram from The English Whisky Company. Yes, a distillery from England. This Chapter 9 is the first ever English peated whisky, bottled at 46% ABV and is mixed from four casks. The distillery started distilling in 2006, and is therefore very young. The English Whisky Co. source their barley, yeast and water from within England, making this a truly English spirit. It is also a very young whisky, at only 3 years old. It is non-chill filtered, and it does not have colour added.

Tasting notes: Peated, light smoke. A bit watery on the palette, with not much of an after taste. You can easily taste that it is a very young whisky as it's rather sharp, but there are hints of citrus and pepper.

December 24nd: Glenmorangie Quarter Century

This is the most expensive whisky in my collection, but I don't think it is the best one. Some of the whiskies from Cadenhead's that I featured in earlier days in this advent calendar are several leagues ahead. Nonetheless, I am quite happy having a bottle of this Glenmorangie Quarter Century. It comes in a nice box too. I like this whisky even better, as it was another gift due to my work on Xdebug.

Tasting notes: It is a very rounded whisky, floral hints and citrus. The flavours are quite a mouth full and a lot is going on. There is also a toasty sweetness. It lingers a little while with a oaky after taste. A very enjoyable dram.

Shortlink

This article has a short URL available: http://drck.me/whiskyad4-b7f

Comments

No comments yet

Whisky Advent: part 3

December 12th: Auchentoshan American Oak

Tonight's dram is an Auchentoshan American Oak. It's from a bottle that I received as a gift for speaking at Glasgow PHP. Thanks! This Auchentoshan does not have an age statement, giving the bottlers a bit more freedom in which ages of barrels they use to blend with. It is possible that whiskies as young as three years are part of this "blend". This specific whisky is aged in first-fill Bourbon casks. Unlike many other whiskies on this calendar, it is both chill filtered and coloured.

Tasting notes: Over ripe fruits, oak, and a sour grapefruit finish. It's a little bland, and it has a short finish. It's still quite enjoyable.

Morag says: Slightly sharp nose, a little bit like vanilla. Not the smoothest with a hint of roughness. Short finish. Tastes like cardboard (or woody). Does not compare well to the Three Wood.

December 13th: Cadenhead's Glen Moray 21 year old

Another dram from Cadenhead's. It is a 21 year old whisky, distilled in 1992. It is part of their Wine Cask range and as usual, it is non-chill filtered and no colouring has been added. The 1992 CA is bottled at 55.4% ABV cask strength. A little curious is that the distillery on the label is Glen Moray-Glenlivet — the "Glenlivet" addition is not often seen anymore. There were only 216, and I'm afraid they are all sold out.

Tasting notes: It does need a drop of water to bring out some flavours—at 55.4% it is just a little bit too strong. Hints of sweeter wine, and cake. Perhaps a hint of aniseed and a finish of medicinal herbs. I'm not quite sure what to make of it really.

December 14th: Single Cask Aberlour 22 years old

I recently found the Whiskybase online, and noticed its extensive list of available whiskies. However, the whisky I had tonight was not known to them yet. I have since then added it.

The whisky is a 22 year old, single cask, cask strength whisky bottled by Speciality Drinks . This casks rendered 250 bottles and at 54.1% ABV it is a bit on the stronger side, and needs a little bit of water. I bought it at the Whisky Exchange as the bottle of the month1 for July. Interestingly the label on my bottle is different than what they have on their site.

Tasting notes: It is a very clear whisky. I taste hints of apple and cream. And with more than a hint of toffee. It lingers quite long with a hint of more toffee.

December 15th: Mortlach Càrn Mòr Strictly Limited

Tonight's dram is a whisky from the Mortlach distillery. Another whisky that the Whiskybase did not have! Or rather, I thought so. The search engine insisted that I spelled it "Mortlach Càrn Mòr" and wouldn't find it if I used "Carn Mor" :-/

This whisky is not from a single cask, but rather from two casks yielding 652 bottles. The whisky is non-chill filtered and has no colouring added. It is bottled at 46% ABV by Morrison and MacKay for their Strictly Limited range. The "two" whiskies are at least 16 years old and aged in Hogshead casks.

Tasting notes: Smooth and creamy honey on the tongue. Light summer fruits and caramel after taste. Could do with a few drops of water to make the flavours come out more.

December 16th: Millstone 1999 from Milroy's

The first non Scottish whisky in this calendar. Tonight we have a Dutch whisky, distilled in 1999 by Zuidam Distillery, and bottled by Milroy's of Soho in 2013. This Millstone 1999 is one of 271 bottles of a 14 year old single cask whisky matured in Sherry Casks. It is 46% ABV and again, non-chill filtered and it does not have colouring added. The whisky itself is quite dark of colour, rather like a sherry.

Tasting notes: Raisins, cinnamon, and a sweet sherry. The medium to longer finish is a bit oily and has a hint of oak and cherries.

December 17th: Yamazaki 18

This Yamazaki 18 from Suntory distillery is another non-Scottish whisky. As the name might hint at, this is Japanese. Some people might frown upon that, but "annoyingly", the Japanese actually make very good whiskies. This one, the Yamazaki is one of my favourites, but it does not come cheap. Luckily, it was given to me as a gift for my work on Xdebug. Since this Yamazaki 18, I've had another whisky, the Hakushu Distiller's Reserve that I actually like better. But that's empty.

Tasting notes: Very dark of colour. A little oily on the palette. Bubblegum, apricot and sweet fruits, a few herbs and spices. Fruits and woody flavours in the aftertaste that lingers quite a bit.

December 18th: Imperial 1994

This Imperial 1994 is bottled by Gordon & MacPhail as part of their Distillery Labels range. It is a first fill sherry butt and refill American hogshead. As the name suggests, it was distilled in 1994. The Imperial distillery is now closed though. This whisky was bottled in 2012 making it 18 years old. It is 43% ABV.

Tasting notes: Smells sweet, fruity and nutty. Smooth on the palette and vanilla, pepper and some tropical fruits in the aftertaste.

Shortlink

This article has a short URL available: http://drck.me/whiskyad3-b77

Comments

No comments yet

Whisky Advent: part 2

December 5th: Blue Hanger, 8th Release

This Blue Hanger is the only blend on the calendar, but this is an unusual blend so I am making an exception. This 8th release is a 21 year old blend, bottled by Berry Bros. & Rudd. It is named after William Hanger, the 3rd Lord Coleraine, a loyal customer of Berry Bros. & Rudd during the late 18th century. He was renowned for the striking blue clothes he wore and gained the soubriquet, "Blue Hanger".

It is bottled at 45.6% ABV, with natural colouring and it is not chill filtered. It is exclusive to The Whisky Shop.

Tasting notes: Orange peel, vanilla, caramel. With a little bit of salt and smoke.

December 6th: Springbank 12 Green

As this month's whisky of the month, I went to my favourite whisky shop in London, Cadenhead's. They are best known for their single cask whiskies, and indeed many of the whiskies on this advent calendar come from them.

This Springbank 12 Green whisky is not a single cask whisky. But it is a very new whisky. So new, that I couldn't find it through Google yet. The label on the bottle says it's one out of 9000 bottles. It is called "Green" because it is distilled from organic barley.

It is matured entirely in bourbon casks and bottled at 46% ABV. The result is creamy and sweet with classic Springbank peatiness giving depth and a hint of coastal air.

Tasting notes: Very pale. Sweet fruits and a little bit peaty. The whisky lingers quite long with peat and a hint of sherry.

December 7th: Single Cask Ardmore 16

Tonight's dram is 16 years old, distilled in 1996 by Ardmore and bottled in

2012. It is one of 315 bottles from a refill Hogshead, selected by Douglas Laing. It forms part of Douglas Laing's Old Malt Cask range, and is now sold out.

Tasting notes: As an Ardmore it is quite peaty, with barley and all spice flavours. Spices, smoke and peppers are its overtones. There are hints of wood in the aftertaste.

December 8th: anCnoc 22

A typical winter warmer from anCnoc. It is 22 years old, and as usual in a natural colour and non-chill filtered. It is a standard whisky, made from many different casks - but aged in both ex-bourbon casks and ex-sherry butts.

Tasting notes: Honey, sweet and a few hints of all spice. A bit like Christmas cake. There is also a hint of smoke, and the whisky is general full of flavours. The finish is spicy.

December 9th: Glenburgie 1994

This 17 year old whisky is distilled by Glenburgie, and bottled by Gordon & MacPhail in 2012. It is specifically bottled for La Maison du Whisky in Paris, not far from Métro station Madeleine. It is in Paris that I bought this whisky when I was there for Forum PHP last year. La Maison du Whisky is in my opinion the best whisky shop outside of Scotland, and Cadenhead's in London.

As is common to many of my whiskies, this is again a non-chill filtered natural colour single cask whisky—cask 10055 in case you care. It is 45% ABV and matured in 1st fill sherry butts.

Tasting notes: The colour is slight red, and it is slightly oily on the tongue. Hints of caramel and honey, but more stronger spices such as cardamom and cloves. The after taste is a little bit zesty, and has hints of oak.

December 10th: Tomintoul 16

I spoke at Glasgow PHP this evening, which meant that I couldn't do my regular bottle and a glass approach. I had to do with a miniature of a Tomintoul 16 that I had brought along. The organisers were so kind to gift me a bottle of Auchentoshan American Oak though, but I am saving that for an upcoming night.

Tasting notes: Overall quite bland, and I didn't pick out too many flavours. It's a bit fruity sweet, but the flavour doesn't linger and in a few seconds I had forgotten about it at all.

December 11th: Mannochmore 12

This latest whisky comes from the Mannochmore distillery, which produces for twelve months and then has a break of twelve months alternating with the nearby Glenlossie distillery, with which it shares the employees. A rather unusual arrangement if you ask me.

In one of the years, they did manage to distill the spirits that now end up as the Mannochmore 12, which I am enjoying tonight. It is part of Diageo's Flora and Fauna range.

Tasting notes: Honey and a hint of pepper? There is quite a lot of flavours coming into play after a while. And even a hint of ginger in the long lingering finish.

Shortlink

This article has a short URL available: http://drck.me/whiskyad2-b6x

Comments

No comments yet

  • 1

    The "bottle of the month" is a longer running project. I will blog about that at some point later.

  • 2

    The "bottle of the month" is a longer running project. I will blog about that at some point later.

Life Line