Welcome!

Linux Containers Authors: Zakia Bouachraoui, Elizabeth White, Yeshim Deniz, Liz McMillan, Pat Romanski

Related Topics: Linux Containers

Linux Containers: Article

Two stupid PHP tricks

Seemingly insignificant, but important, details to help you run PHP successfully

(LinuxWorld) -- In the face of a slowing economy, it is increasingly difficult to justify spending any time working on my non-profit site VarLinux.org. I posted a notice stating there will be no further progress. Yet even after making it "official," I can't seem to stop myself from working on the site. Perhaps I have some secret hope it will blossom into a successful project that makes money instead of sucking the food out of my children's mouths. Or perhaps I find it therapeutic in these trying times.

Regardless, working on this site continues to be educational, particularly in when it comes to learning from my mistakes. (Whenever I think of that expression, I am reminded of the Peanuts strip where Charlie Brown says something along the lines of, "If it is true that you really learn from your mistakes, that makes me the smartest person in the world.")

I chronicle much of what I experience as it happens on VarLinux.org. But for the sake of my LinuxWorld readers and VarLinux.org readers alike, and to dispel any notion that I'm a master programmer, I will condense some of the most important lessons here. I've got reams of lessons I've learned regarding MySQL, Apache, and other pieces of the site, but I'll start with some of the places where I stumbled (or had to deal with the undesirable coding practices of others) while using PHP.

PHP lesson number 1

First, if you program in PHP, always use echo "text, variables, and html goes here"; instead of interspersing HTML and other displayed text with PHP commands. In other words, every ".php" file should begin with "<?php" and end with "?>" and never break away from PHP programming mode anywhere in-between.

This is the opposite of the way people tend to get started with PHP. They take their HTML files and insert some PHP commands here and there as necessary, breaking away from the HTML when they need the functionality PHP provides.

Even though that seems like a sensible way to get started, take my advice, even if you want to create a project based on existing HTML files. Wrap your existing HTML in echo statements, even though this means you'll have the tedious job of making sure all your double-quotes are preceded by a backslash. In other words, this...

<A HREF="http://wherever.domain">link text</A>

converts to...

echo "<A HREF=\"http://wherever.domain\">link text</A>";

The same goes for every other instance where quotes exist in your HTML. And remember that if you want your HTML to conform to the w3c standard, there are many places where you need to use quotes even if you can get away without using them. Most browsers aren't picky about such things these days, so it is tempting to leave out quotes where the HTML specification says you should use them. I'm a standards kinda guy, so I say use them just because you are supposed to use them.

I wouldn't be surprised if I hear from PHP programmers who tell me the above practice will have a negative affect on performance. It may, it may not. I have no idea, because I don't know how much overhead (if any) you are adding to your site when you make the PHP module parse echo statements rather than pass plain HTML through to Apache. But after having modified the code for VarLinux.org for the past couple of months, I can tell you it is a whole lot easier to maintain a site when you assume everything on the page is PHP. Use echo to send HTML to the browser.

Just one more note to satisfy the PHP gurus who are no doubt breaking out in a rash due to my focus on the echo command alone. It's true there's more to life in PHP than echo. For example, as you learn PHP, you'll find you don't need to use echo for every line of HTML. You can accumulate multiple lines, assign them to variables, use printf formatting, and then echo that output, for example. And you can use things like output buffers to play tricks and make your site more efficient (see the command ob_start() in the PHP documentation for an introduction to this technique).

My point is your should stay in PHP from start to finish if you want to make it easier to maintain your site down the road.

Stupid PHP trick number 1

In addition, make sure there are no blank lines above or below these two PHP opening and closing tag markers, "<?php" and "?>", respectively. If you follow this rule as well as the one about never breaking away from PHP, your server will never send anything to a visiting browser unless you have instructed it to.

This is extremely important if you ever expect to use cookies or redirect a visiting browser to a new location. If the PHP compiler/interpreter sees a blank line in a file outside of any PHP tags, it assumes it should send the blank line(s) to Apache immediately.

Once this occurs, Apache assumes it has sent the header for your page and you can no longer use the functions that manage cookies or redirect browsers to new locations. You can check for this condition with the PHP headers_sent() command. If it is true, then it's too late to set a cookie or redirect the browser with the PHP Header("Location: newlocation") command.

The easiest way to trip up on this particular rule is to include another file that has blank lines. For example, your hello.php file may read something like the following:

<?php
include("configvars.php");

function dosomething() { setcookie("thiscookie","thisinfo",time() - 3600); echo "Hello"; }

dosomething();

?>

If configvars.php has any blank lines outside of PHP tags, then you have unwittingly created the condition where headers_sent() is true, even if your hello.php file has no blank lines outside of the PHP tags and hasn't used any functions or variables from the included file. The setcookie() command in the function dosomething will fail simply because there was a blank line outside of PHP tags in the included file.

Stupid PHP trick number 2

I can't take the blame for how this stupid trick affected VarLinux.org, since the problem emerged from the way PHP-Nuke 4.4.1a was coded (I haven't checked to see if later versions of PHP-Nuke correct this). But the lesson I learned is simple. Always specify both arguments for the crypt() function. The first argument is the string you want to encrypt, and the second argument is the salt, which is something like the "key" to the encryption scheme.

The crypt() function is a one-way encryption technique that is useful for storing user passwords. You can't decrypt anything you encrypted using crypt(). (You might be asking yourself how such a function could possibly be useful, but we'll get to that in a moment.)

PHP provides other encryption functions that allow you decrypt what you encrypted. But I like using crypt() for storing VarLinux.org passwords because it provides my users with more privacy. If you use this function, not even the administrator can decrypt a user's password. If someone uses an embarrassing string of text, I can't find out what it is.

More important, it is difficult to figure out any VarLinux.org user's password even if a bad guy gains direct root access to the VarLinux.org server. If a VarLinux.org user's password includes any information that might help a cracker break into that user's own system, this technique makes it almost impossible for anyone to exploit information in the VarLinux.org database for such a purpose, even if they gain access to these passwords.

The crypt() function takes one or two arguments and returns the encrypted string. The first argument is the text that you want to encrypt. If you do not provide a second argument, crypt() will choose the default encryption algorithm from the following list (according to the PHP documentation):

  • CRYPT_STD_DES - Standard DES encryption with a 2-char SALT
  • CRYPT_EXT_DES - Extended DES encryption with a 9-char SALT
  • CRYPT_MD5 - MD5 encryption with a 12-char SALT starting with $1$
  • CRYPT_BLOWFISH - Extended DES encryption with a 16-char SALT starting with $2$

If you provide a second argument, crypt() will use the encryption scheme that matches the type of salt you provided as the second argument.

As I said earlier, the salt is like a key to the encryption algorithm. It is what the encryption algorithm uses to encrypt your text. If you use the crypt() function with only a single argument, it creates its own salt automatically, according to the default algorithm it has selected. Then it outputs the encrypted string. The first portion of that encrypted string is the salt that it used. This is what makes this function useful for storing passwords.

Here's how it works. (This example is entirely bogus and is meant only to illustrate the way the function is used in practice). Suppose you enter "password" as your password. VarLinux.org encrypts "password" with the crypt("password") function, which returns the string "2j38sn3km4", which is what VarLinux.org stores in its database for your password. We didn't specify any salt, but since we know the default encryption technique is standard DES, we know the first two characters of the encrypted output string comprise the salt for the string, because that's how standard DES works.

Assuming the first two characters of this string, "2j", comprise the salt, we now have a way to validate you as a user without having to know your actual password. The next time you log in, you will type the word "password". The VarLinux.org PHP code will then use your login name to find your encrypted password string, "2j38sn3km4". It extracts the first two characters, and attempts to re-encrypt your password with the following function: crypt("password","2j").

Notice this time we specify the salt as the second argument. Since you are using the same password, "password", and since the crypt() function is using the same salt it automatically created when it encrypted your password in order to store it in the database, it should create the same encrypted string again now. The two encrypted strings match, and you're validated.

The problem

Suddenly VarLinux.org users complained they couldn't log in again after changing their password. As a shot in the dark, I looked at the encrypted password strings in the database, and noticed some were much longer than others.

At some point while updating software on my server, PHP stopped using standard DES as the default for the crypt() function and started using MD5 encryption instead.

The mismatch arose from PHP-Nuke 4.4.1a specifing the first two characters of your encrypted password as the salt when you log in. In other words, it forces crypt() to use standard DES when it validates you at login. But PHP-Nuke 4.4.1a leaves out the salt as the second parameter when it creates your first password, or when it allows you to change your password.

As long as PHP defaulted to standard DES, there was no problem. But when PHP started using MD5 as a default, it started storing MD5-encrypted passwords in the database whenever someone would create a new password or change an existing one. The problem is the code continued to try to validate these encrypted strings as standard DES when you tried to log in.

If you take my advice above and always specify the second argument for crypt() whenever you use it, this mismatch will never occur. That's how I fixed the problem. Whenever anyone creates or changes a password, my code now calls a routine that generates a random two-character salt. It specifies this salt as the second parameter of the crypt() function, which forces crypt() to use standard DES at all times. No mismatch. No more failed login attempts.

Here is the makesalt() function, which I simply lifted from the comments section of the online PHP manual. There are better salt generators than this, but if you are truly concerned about security I recommend you base your site on MD5 or better instead of standard DES.

function makesalt() {
  srand((double)microtime()*1000000);
  $saltseeds =
  array('.','/','0','1','2','3','4','5','6','7','8','9',
   'a','b','c','d','e','f','g','h','i','j','k','l','m',
   'n','o','p','q','r','s','t','u','v','w','x','y','z',
   'A','B','C','D','E','F','G','H','I','J','K','L','M',
   'N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
  return $saltseeds[rand(0,63)] . $saltseeds[rand(0,63)];
}

More Stories By Nicholas Petreley

Nicholas Petreley is a computer consultant and author in Asheville, NC.

Comments (1)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


IoT & Smart Cities Stories
In his general session at 19th Cloud Expo, Manish Dixit, VP of Product and Engineering at Dice, discussed how Dice leverages data insights and tools to help both tech professionals and recruiters better understand how skills relate to each other and which skills are in high demand using interactive visualizations and salary indicator tools to maximize earning potential. Manish Dixit is VP of Product and Engineering at Dice. As the leader of the Product, Engineering and Data Sciences team at D...
When talking IoT we often focus on the devices, the sensors, the hardware itself. The new smart appliances, the new smart or self-driving cars (which are amalgamations of many ‘things'). When we are looking at the world of IoT, we should take a step back, look at the big picture. What value are these devices providing. IoT is not about the devices, its about the data consumed and generated. The devices are tools, mechanisms, conduits. This paper discusses the considerations when dealing with the...
Bill Schmarzo, Tech Chair of "Big Data | Analytics" of upcoming CloudEXPO | DXWorldEXPO New York (November 12-13, 2018, New York City) today announced the outline and schedule of the track. "The track has been designed in experience/degree order," said Schmarzo. "So, that folks who attend the entire track can leave the conference with some of the skills necessary to get their work done when they get back to their offices. It actually ties back to some work that I'm doing at the University of San...
Bill Schmarzo, author of "Big Data: Understanding How Data Powers Big Business" and "Big Data MBA: Driving Business Strategies with Data Science," is responsible for setting the strategy and defining the Big Data service offerings and capabilities for EMC Global Services Big Data Practice. As the CTO for the Big Data Practice, he is responsible for working with organizations to help them identify where and how to start their big data journeys. He's written several white papers, is an avid blogge...
Dynatrace is an application performance management software company with products for the information technology departments and digital business owners of medium and large businesses. Building the Future of Monitoring with Artificial Intelligence. Today we can collect lots and lots of performance data. We build beautiful dashboards and even have fancy query languages to access and transform the data. Still performance data is a secret language only a couple of people understand. The more busine...
If a machine can invent, does this mean the end of the patent system as we know it? The patent system, both in the US and Europe, allows companies to protect their inventions and helps foster innovation. However, Artificial Intelligence (AI) could be set to disrupt the patent system as we know it. This talk will examine how AI may change the patent landscape in the years to come. Furthermore, ways in which companies can best protect their AI related inventions will be examined from both a US and...
Enterprises have taken advantage of IoT to achieve important revenue and cost advantages. What is less apparent is how incumbent enterprises operating at scale have, following success with IoT, built analytic, operations management and software development capabilities - ranging from autonomous vehicles to manageable robotics installations. They have embraced these capabilities as if they were Silicon Valley startups.
Chris Matthieu is the President & CEO of Computes, inc. He brings 30 years of experience in development and launches of disruptive technologies to create new market opportunities as well as enhance enterprise product portfolios with emerging technologies. His most recent venture was Octoblu, a cross-protocol Internet of Things (IoT) mesh network platform, acquired by Citrix. Prior to co-founding Octoblu, Chris was founder of Nodester, an open-source Node.JS PaaS which was acquired by AppFog and ...
The deluge of IoT sensor data collected from connected devices and the powerful AI required to make that data actionable are giving rise to a hybrid ecosystem in which cloud, on-prem and edge processes become interweaved. Attendees will learn how emerging composable infrastructure solutions deliver the adaptive architecture needed to manage this new data reality. Machine learning algorithms can better anticipate data storms and automate resources to support surges, including fully scalable GPU-c...
Cloud-enabled transformation has evolved from cost saving measure to business innovation strategy -- one that combines the cloud with cognitive capabilities to drive market disruption. Learn how you can achieve the insight and agility you need to gain a competitive advantage. Industry-acclaimed CTO and cloud expert, Shankar Kalyana presents. Only the most exceptional IBMers are appointed with the rare distinction of IBM Fellow, the highest technical honor in the company. Shankar has also receive...