Sunday, December 2, 2012

My PHP WTF Of The Day: max_input_vars

I recently moved the installation of a legacy in-house LAMP application from a dated server (hardware failures) to a virtual machine based on backups. To make the transition as smooth as possible, I chose the same software components: centos, mysql5 (the dumps are not compatible with 5.1 and newer thanks to a charset collation bug), php 5.1.6. Because it's an in-house app behind firewalls I don't need to worry about security updates.

Smoke signal testing passed, and so I gave the OK for the users to continue their work.

After weeks of using it, a problem was reported about just one function of the app that would sometimes return a blank screen. It took me hours of debugging (read: echo) to figure out what's going on, digging through some old PHP code (fun!): It appeared that only 1000 post variables arrived on the server. (Well, 1006 actually, but 2 were added by PHP, and that sounded like a PHP-style limitation of 1000.) A quick google lookup revealed that PHP introduced a new feature where it would limit the number of post variables. For safety reasons.

The variable is called "max_input_vars" with a default of 1000. PHP states that this feature was introduced in 5.3.9, but I'm running 5.1.6 and the limit is enforced.

Because the server is for production, it was running with on-screen warnings turned off. PHP says that it "prints a warning and cuts". For me, that's a real WTF. A post request should be processed as all-or-nothing. It should instead refuse the request completely. But for a technology named "personal home page" the priorities are different.

Cutting the post data is as if a browser would enforce a URL length limit of 256 and just cut there, or a database would just truncate a string too long to fit in a field (oh, no, wait, mysql does this without the strict option, and so did earlier versions of postgres ...).

The purpose of this new feature is to harden security... what it did for me is hardening my hate-hate relationship with PHP.