Sebastian BergmannStatic Analysis with HipHop for PHP (27.1.2012, 19:00 UTC)

In July 2010 I already blogged about the fact that HipHop for PHP, the source code transformer that turns PHP code into C++ code that can then be compiled with g++, can also be used for static code analysis to find problems in PHP source code.

Today I started to work on a convenience wrapper for HipHop's static analyzer:

➜  ~  hphpa /usr/local/src/code-coverage/PHP
hphpa 1.0.0 by Sebastian Bergmann.

/usr/local/src/code-coverage/PHP/CodeCoverage/Filter.php
  206   TooManyArgument: $this->addFileToWhitelist($file, FALSE)

Of course the tool can also generate an XML logfile in a format that is suitable for continuous integration:

➜  ~  hphpa --checkstyle hphpa.xml --quiet /usr/local/src/code-coverage/PHP
hphpa 1.0.0 by Sebastian Bergmann.

➜  ~  cat hphpa.xml
<checkstyle>
 <file name="/usr/local/src/code-coverage/PHP/CodeCoverage/Filter.php">
  <error line="206"
         message="$this->addFileToWhitelist($file, FALSE)"
         source="TooManyArgument"/>
 </file>
</checkstyle>
Link
Pádraic BradyMockery 0.7.2 Released (And On Packagist.org!) (25.1.2012, 11:07 UTC)

Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a framework for creating test doubles like mock objects through the use of a simple and succint API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit’s phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can happily operate alongside phpunit-mock-objects.

Today, I am pleased to announce the release of Mockery 0.7.2, a maintenance release fixing a small number of bugs and annoyances. A special thanks to all those who forked the Github project at and submitted pull requests! Leaving a developer with hardly any work to do other than a quick test and merge is always appreciated! You can install or upgrade to the new version from the survivethedeepend.com PEAR channel.

Another piece of news is that Mockery is now available on Packagist.org for users of Composer. Composer is a tool to help you manage your own projects’ or librarys’ dependencies and it can handle and mix dependencies from Composer compatible repositories like Packagist.org, any git repository using tags, and any PEAR channel. I do this of my own free will and not because Luis Cordova and Benjamin Eberlei are standing behind me with pitchforks ;) .

The more pertinant fixes include:

  1. Fixed a problem in resolving methods chains which abuse the Law of Demeter (thanks to the wizardly Robert Basic).
  2. Fixed unexpected static calls to an alias mock which were causing fatal errors (thanks to Luis Cordova).
  3. Fixed a crash present since PHP 5.3.6 due to a referenced $this variable entering a closure (thanks to Martin Sadovy).
  4. Added support for PHP_CodeCoverage 1.1 whose filter class is no longer a singleton (thanks to Matthew Vivian).
  5. Added non-halting exception handling (for Mockery exceptions) to the PHPUnit TestListener (thanks to Adrian Slade).
  6. Added boolean $prepend (defaults to FALSE) parameter to \Mockery\Loader::register() to allow for registering Mockery’s autoloader to the top of the autoloader stack even after other autoloaders have been registered (thanks to Hermann Kosselowski).
  7. Updated documentation/tests for the release of Hamcrest 1.0.0 several days ago (thanks to me, me, me – who finally got to do something nobody else had a pull request for!).
  8. Added new \Mockery::self() static method to make retrieving the current mock object simpler and more readable while setting expectations without the need to refer back to past variable assignments.

Users should also note that Hamcrest 1.0.0, which includes a small filename change (hamcrest.php was capitalised to Hamcrest.php), was released several days ago. If you use Hamcrest matchers with Mockery, you should ensure that both libraries are updated on your system.

As always, please report any bugs or potential improvements to the Github issue tracker using the relevant label or, even more appreciated, send me a pull request.

Enhanced by Zemanta
Link
Fabien PotencierCreate your own framework... on top of the Symfony2 Components (part 12) (25.1.2012, 06:39 UTC)

This article is part of a series of articles that explains how to create a framework with the Symfony2 Components: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12.

In the last installment of this series, we have emptied the Simplex\\Framework class by extending the HttpKernel class from Symfony. Seeing this empty class, you might be tempted to move some code from the front controller to it:

<?php
 
// example.com/src/Simplex/Framework.php
 
namespace Simplex;
 
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\Routing;
use Symfony\Component\HttpKernel;
use Symfony\Component\EventDispatcher\EventDispatcher;
 
class Framework extends HttpKernel
{
    public function __construct($routes)
    {
        $context = new Routing\RequestContext();
        $matcher = new Routing\Matcher\UrlMatcher($routes, $context);
        $resolver = new HttpKernel\Controller\ControllerResolver();
 
        $dispatcher = new EventDispatcher();
        $dispatcher->addSubscriber(new HttpKernel\EventListener\RouterListener($matcher));
        $dispatcher->addSubscriber(new HttpKernel\EventListener\ResponseListener('UTF-8'));
 
        parent::__construct($dispatcher, $resolver);
    }
}
 

The front controller code would become more concise:

<?php
 
// example.com/web/front.php
 
require_once __DIR__.'/../vendor/.composer/autoload.php';
 
use Symfony\Component\HttpFoundation\Request;
 
$request = Request::createFromGlobals();
$routes = include __DIR__.'/../src/app.php';
 
$framework = new Simplex\Framework($routes);
 

Truncated by Planet PHP, read more at the original (another 18437 bytes)

Link
Ulf WendelPECL/mysqlnd_qc: query cache statistics log (24.1.2012, 17:20 UTC)

Is it worth the efforts to cache the results of a MySQL query at the client? In most cases the answer is: try it, measure it! Install the development version of the mysqlnd query cache plugin, which can be used with PDO_MySQL, mysqli and mysql. Set three PHP directives and find the answer in a log file.

While updating the query cache plugin to support PHP 5.4, the latest versions of APC and Memcached for cache storage, I virtually stumbled upon an undocumented feature I had long forgotten. The plugin can periodically dump statistics into a log file. The plugin collects tons of statistics and query traces to find cache candidates and for measuring cache efficiency. Details can be found in the quickstart.

Quick and dirty evaluation

A quick and dirty evaluation of the maximum performance gain client-side query caching can give you is obtained by caching all statements. The first PHP directive to set is mysqlnd_qc.cache_by_default = 1. Ignore the fact that the cache may serve stale data because its default invalidation strategy is Time-to-Live (TTL). Quick and dirty…

Enable the collection of per-process cache statistics with mysqlnd_qc.collect_statistics. Tell the plugin to dump statistics into the log file set through mysqlnd_qc.collect_statistics_log_file. The plugin will now dump per-process cache statistics into the log at every 10th web request.


info : pid=17092
info : cache_hit=9
info : cache_miss=5
info : cache_put=5
info : query_should_cache=14
info : query_should_not_cache=21
info : query_not_cached=21
info : query_could_cache=14
info : query_found_in_cache=9
info : query_uncached_other=0
info : query_uncached_no_table=0
info : query_uncached_no_result=0
info : query_uncached_use_result=0
info : query_aggr_run_time_cache_hit=232
info : query_aggr_run_time_cache_put=1785
info : query_aggr_run_time_total=2017
info : query_aggr_store_time_cache_hit=113
info : query_aggr_store_time_cache_put=214
info : query_aggr_store_time_total=327
info : receive_bytes_recorded=355
info : receive_bytes_replayed=639
info : send_bytes_recorded=205
info : send_bytes_replayed=369
info : slam_stale_refresh=0
info : slam_stale_hit=0
info : -----------------------------
info : pid=17099
info : cache_hit=12
info : cache_miss=6
info : cache_put=6
info : query_should_cache=18
info : query_should_not_cache=27
info : query_not_cached=27
info : query_could_cache=18
info : query_found_in_cache=12
info : query_uncached_other=0
info : query_uncached_no_table=0
info : query_uncached_no_result=0
info : query_uncached_use_result=0
info : query_aggr_run_time_cache_hit=185
info : query_aggr_run_time_cache_put=3017
info : query_aggr_run_time_total=3202
info : query_aggr_store_time_cache_hit=145
info : query_aggr_store_time_cache_put=405
info : query_aggr_store_time_total=550
info : receive_bytes_recorded=426
info : receive_bytes_replayed=852
info : send_bytes_recorded=246
info : send_bytes_replayed=492
info : slam_stale_refresh=0
info : slam_stale_hit=0

Restart your web server, if needed, to make it recognize the new ini settings. Put some load on it, make sure the PHP scripts run a couple of MySQL queries. Note that its per-process statistics and that they are dumped on every 10th web request served by a process. In other words: you must have at least one process serve 10 requests before you can expect to find something in the log file.

The rest is simple math… pointers are given in the manual, for example, under mysqlnd_qc_get_core_stats(). No math, Perl, sed, grep, whatever-other-post-processing for you? Check out the web/ directory in the source distribution. There’s a basic web monitor.

The ini setting mysqlnd_qc.collect_statistics_log_file for setting a log file name is new and only available in the development tree. The feature itself - dump of statistics into a file - is old. Earlier versions have a compiled in file name of /tmp/mysqlnd.stats.

Happy hacking!

@Ulf_Wendel Follow me on Twitter

Link
Larry GarfieldTop Ten Reasons To Go To DrupalCon Denver (24.1.2012, 16:38 UTC)

You mean you aren't already attending what will likely be the largest web developer conference in the Western US this year? What are you waiting for? Not sure if it will be worth it? It will be. Oh, it will be...

If you still need some convincing, or if your boss still needs some convincing, here's the top ten reasons you want to be at DrupalCon Denver:

read more

Link
Official Blog of the PEAR Group/PEAR PresidentWhat would you do with 5 million lines of code? (24.1.2012, 14:05 UTC)

Since October 2011, 5 million lines of the PEAR codebase has shifted to github.

Hand in hand with this shift has been the tireless work of Daniel C – someone who brazenly said “I will fix the failing packages!” in the tail end of last year.

Coupling his efforts with a call to arms, we’ve now seen an evaluation of the Known Good packages against PHP 5.4, and massive input by the community. The net result is as follows:

  • Releases of Text_LanguageDetect, HTTP2, Net_Growl, Image_QRCode, Tree, HTML_BBCodeParser, Net_IMAP, Net_DNSBL, Services_Amazon, Image_Barcode2, Validate, Console_Color2, Services_ExchangeRates, Validate_DK, PEAR_PackageFileManager_Frontend, Text_Highlighter, PHP_Shell, Date, Image_Text, PEAR_Frontend_Gtk2, PHP_DocBlockGenerator, & Validate_AR through Dec/January
  • All test infrastructure upgrading to PHP 5.4 release candidates
  • All database driven test suites executing properly, catching a variety of simple bugs
  • Just shy of 900 commit emails to the pear-cvs list for Dec/Jan – many containing multiple commits & fixes
  • Hitting a point of “near zero” patches to be applied to unmaintained packages
  • Applying no less than 30+ patches contributed by the community across all of PEAR
  • Increasingly, the PEAR QA team is delivering PHP 5.3+ friendly forks of existing packages

I’d like to thank Daniel C for his efforts to date, as well as the contributors who may have previously lurked or found themselves distracted by other concerns.
Dec/Jan has been a great and vigorous period for the project – I heartily look forward to a great 2012.

Link
PHP: Hypertext PreprocessorPHP 5.4.0 RC6 released (23.1.2012, 23:00 UTC)
The PHP development team announces the 6th release candidate of PHP 5.4. PHP 5.4 includes new language features and removes several legacy (deprecated) behaviours. Windows binaries can be downloaded from the Windows QA site. THIS IS A RELEASE CANDIDATE - DO NOT USE IT IN PRODUCTION!. This is the 6th release candidate. The release candidate phase is intended as a period of bug fixing prior to the stable release. No new features should be included before the final version of PHP 5.4.0. The 6th release candidate focused on improving traits. Please test them carefully and help us to identify bugs in order to ensure that the release is solid and all things behave as expected. Please take the time to test this release candidate against your code base and report any problems that you encounter to the QA mailing list and/or the PHP bug tracker. A complete list of changes since the last release candidate can be found at NEWS The next candidate will be released on Feb 2.
Link
Pádraic BradyStoring Session Data In Cookies: Problems And Security Concerns To Be Aware Of (23.1.2012, 21:20 UTC)
English: Peanut butter cookie with a chocolate...

Image via Wikipedia

Back from my extended leave of absence, I’ll re-open the dusty cobwebbed depths of this blog to echo the sentiments of Paul Reinheimer in his recent article “Cookies don’t replace Sessions“. The topic is actually an old one since Ruby On Rails has adopted the strategy of storing application session data in cookies by default (take note, performance hounds). The purposes of storing sessions in userland cookies rather than the conventional “stick-it-on-the-filesystem/database” used by many apps is one of performance and a little obscuration. Cookie data can be accessed faster than hitting the filesystem/database plus it has the dubious ability to disguise the session-targeted programming language. Really though, PHP is assumed to be on all web servers so hiding its existence is a bit like trying to hide an elephant in a zoo. Hide it all you want – we still know there has to be one in there!

In exchange for speeding up session reading, storing session data in cookies has some fairly uncomfortable costs.

Now, developers are not unaware of the problems of storing potentially sensitive application data in plain text files on the user’s PC which users can manipulate, copy, and mangle to their (or the hacker’s currently fiddling with the user’s PC) heart’s content. It’s dangerous depending on just how much you rely on session data to drive other security rules or restrictions on business logic within the application. Technically, the reliance placed on sessions should be close to nothing – session data should drive the application towards other storage solutions for the really essential stuff and just stay around as a minimal identifier/stash of basic ID info. Such minimal information can be dumped, corrupted, or overwritten with the only cost being to perhaps require a user to login again when that happens. Stuffing a bank balance into a session, on the other hand, is one (very exaggerated!) example of the kind of data you should be shot for relying on a session for.

Programmers being programmers, it’s not rare to see sessions become a more intrinsically important storage location than it should be. In those cases, being able to manipulate the session data can become a problem and may give rise to exploitation scenarios where tampering with the stored data leads to some benefit for the manipulator. Obviously we want to make sure that that can’t happen even in scenarios where programmers may be a bit loose with where they store data. We don’t build frameworks and libraries for Gurus, we build them for all programmers – even the sometimes ignorant and under trained ones. This cookie stored session data is often coupled with the ability to encrypt that data. However…

As Paul Rainheimer remarks in his article, “Encryption is often viewed as a panacea for security problems, you sprinkle a little encryption dust around, and your problems dissolve”. This is an absolute truth in programming – programmers often view encryption as a solution without regard for one teeny tiny problem. If you encrypt a set of data for any purpose, even though it’s encrypted, the user (or the hacker hacking the user’s account) still has the data in some usable form!

With perfectly intact data, and even through it’s hidden by encryption, that data can be recycled simply by copying it to another machine. Depending on the data that is stored (which admittedly may require the hacker/user to figure out by doing actual work like finding your open source a

Truncated by Planet PHP, read more at the original (another 3726 bytes)

Link
Chris Shiflett2011 Highlights (23.1.2012, 19:59 UTC)

A new year begins, so for the ninth year in a row, I'm taking a moment to record, reflect, assess, and aim.

Last year, I described 2010 as a landmark year, and it was. Analog, Mild Bunch, Brooklyn Beta, Mapalong, and PHP Advent. Even without factoring in conferences and such, it was a big year.

Tegan Saoirse Shiflett

All of 2010's accomplishments seem trivial when compared to 2011, because in May, Tegan was born.

She's eight months old as I write this, and being a father still feels new. Life has changed, and I have a renewed excitement for what lies ahead. I love what I do, and I love where I do it, but I can't wait to get home each night.

If you want to keep up with Tegan, you can follow her on Twitter. Her Twitter account has been a fun way to record life as it happens from her perspective.

Here are a few other highlights of 2011:

Mapalong
Mapalong is an app for bookmarking places. In a nutshell, we've made Google Maps social and beautiful. I haven't blogged much about Mapalong, but 2011 was full of ups and downs that I wish I had recorded. Although I've been involved with many startups and have even been involved early enough to be emotionally and financially invested, there's nothing quite like the struggle of bringing your own idea to life. If we find the right investor, we're going to be growing the team and opening the doors this year, and that's exciting. If you'd like to try Mapalong in the meantime, reserve your username with Twitter, then let me know.
Brooklyn Beta
With the help of our colleagues and friends (especially Jessi), Cameron and I organized a second Brooklyn Beta this past October. It was an experience that's hard for me to put into words. I will try to summarize Brooklyn Beta in a separate post soon. For now, I'd just like to say thanks to every speaker and every attendee who helped make it something truly special.
Ideas of March
In March, I pledged to blog more and convinced a lot of other people to do the same. It worked for a while. Planet Chris was full of wonderful content, and my link blog was busier than ever. Over time, my commitment waned, but I had a pretty good excuse. No excuses this year; I will get my blogging rhythm back.
Conferences
I went to New Adventures in January, but I went as an attendee, not a speaker. In fact, I did not speak at any conferences in 2011. (I spoke briefly at Brooklyn Beta, but that doesn't really count.) Just a few years ago, a recurring resolution was to speak at fewer conferences, because I felt like I was never home. How things have changed! 2011 was a really nice break, and it gave me a chance to focus on my family and my work.
PHP Advent
Sean and I curated another PHP Advent. This year was more of a struggle than usual, but I'm very happy with how it turned out.

Finally, here are a few goals for the coming year:

Mapalong
I believe strongly in Mapalong's promise, and 2012 is an important year. We need money to give us the freedom to focus on it and make it a success. We're also working on an iOS app with full mobile support to follow. Once you can take Mapalong with you wherever you go, we'll be a release or two away from opening the doors. I can't wait.
Brooklyn Beta
This is the year Brooklyn Beta becomes more than a conference. We've got some exciting things planned, and if you want to stay informed, please follow @brooklynbeta or subscribe to our newsletter.
Conferences
In 2012, I'm going to speak at a few select events. In Feb

Truncated by Planet PHP, read more at the original (another 1299 bytes)

Link
Paul ReinheimerCookies don't replace Sessions (23.1.2012, 17:48 UTC)

I’ve seen several instances where people have demonstrated the ease with which encrypted cookies can replace sessions within PHP. Michael Nitschinger wrote a piece recently demonstrating the switch with Lithium, while CodeIgniter does this by default (optionally encrypting). The problem is that while replacing sessions with cookies works, it introduces a few risks not present with native session support, and these risks tend to be under documented.

Encryption is often viewed as a panacea for security problems, you sprinkle a little encryption dust around, and your problems dissolve. Unfortunately, while properly implemented encryption solves the problem of other people reading your encrypted data quite well, it doesn’t do much else. It doesn’t (on its own) tell you if other people have duplicated your data, manipulated the data in question, or handed you an old copy of properly encrypted data.

Consider an attacker who manages to sit in between Amazon and one of their warehouses. Amazon (in this theoretical example) encrypts all order instructions well, then transmits them to the warehouse. The warehouse decrypts the instruction, fills the order, and ships. If the attacker wanted free stuff they could place an order during a low traffic period, and wait for Amazon to send an encrypted message and make a copy. A few minutes later they could re-send that encrypted message to the warehouse, never having even tried to read it. With luck, they’ll soon receive two of whatever they just ordered! This is an instance of the replay attack, and that vulnerability is the one this post will examine in detail.

Exploiting cookie based sessions

Executing a replay attack against a cookie based session is easy, legitimately obtain some desired state on the system in question, and make a copy of your cookies. Should something go wrong, simply restore your cookies to the previous state. To demonstrate this, I’ve created a sample gambling application, you can get the source from github, or Play Now! (thanks to Orchestra.io, it's a free account so give it a moment)

In the game you start with $1000, then have the ability to make arbitrary wagers. Make a few bets to get a feel for the system, then make a copy of your cookie values. Bet again. If you lose money, simply restore your earlier cookies to get that money back. That’s it. This attack works because the system is willing to accept any successfully decrypted message as a valid, and current, session.

This attack doesn’t exist under traditional session storage. The user’s cookie doesn’t change from one request to the next as their money goes up and down. If a system is regenerating the session ID when the user changes privilege levels, the old session is deleted and no longer available when invoked properly: session_regenerate_id(TRUE);

A system using cookie based session storage, while using a CAPTCHA to defeat bots is doomed to fail, the attacker could solve the CAPTCHA once, then re-use that same cookie a million times. Encryption makes it difficult for an attacker to read the message, additional systems must be bolted on to defend against this sort of attack. In the stateless world of HTTP and the web, this is exceedingly difficult without some server-side datastore.

While this was clearly a trivial example, the problem is not. If you’re looking at using cookie based sessions it’s one of the things you need to be aware of.

If you’re interested in learning more about cryptography, including a great rundown of this problem and many others, I’d highly recommend Practical Cryptography

Link
LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP