Linux Containers Authors: Sematext Blog, Stackify Blog, Liz McMillan, Yeshim Deniz, Elizabeth White

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:


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



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() {
  $saltseeds =
  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
The platform combines the strengths of Singtel's extensive, intelligent network capabilities with Microsoft's cloud expertise to create a unique solution that sets new standards for IoT applications," said Mr Diomedes Kastanis, Head of IoT at Singtel. "Our solution provides speed, transparency and flexibility, paving the way for a more pervasive use of IoT to accelerate enterprises' digitalisation efforts. AI-powered intelligent connectivity over Microsoft Azure will be the fastest connected pat...
CloudEXPO has been the M&A capital for Cloud companies for more than a decade with memorable acquisition news stories which came out of CloudEXPO expo floor. DevOpsSUMMIT New York faculty member Greg Bledsoe shared his views on IBM's Red Hat acquisition live from NASDAQ floor. Acquisition news was announced during CloudEXPO New York which took place November 12-13, 2019 in New York City.
At CloudEXPO Silicon Valley, June 24-26, 2019, Digital Transformation (DX) is a major focus with expanded DevOpsSUMMIT and FinTechEXPO programs within the DXWorldEXPO agenda. Successful transformation requires a laser focus on being data-driven and on using all the tools available that enable transformation if they plan to survive over the long term. A total of 88% of Fortune 500 companies from a generation ago are now out of business. Only 12% still survive. Similar percentages are found throug...
Atmosera delivers modern cloud services that maximize the advantages of cloud-based infrastructures. Offering private, hybrid, and public cloud solutions, Atmosera works closely with customers to engineer, deploy, and operate cloud architectures with advanced services that deliver strategic business outcomes. Atmosera's expertise simplifies the process of cloud transformation and our 20+ years of experience managing complex IT environments provides our customers with the confidence and trust tha...
The graph represents a network of 1,329 Twitter users whose recent tweets contained "#DevOps", or who were replied to or mentioned in those tweets, taken from a data set limited to a maximum of 18,000 tweets. The network was obtained from Twitter on Thursday, 10 January 2019 at 23:50 UTC. The tweets in the network were tweeted over the 7-hour, 6-minute period from Thursday, 10 January 2019 at 16:29 UTC to Thursday, 10 January 2019 at 23:36 UTC. Additional tweets that were mentioned in this...
Today's workforce is trading their cubicles and corporate desktops in favor of an any-location, any-device work style. And as digital natives make up more and more of the modern workforce, the appetite for user-friendly, cloud-based services grows. The center of work is shifting to the user and to the cloud. But managing a proliferation of SaaS, web, and mobile apps running on any number of clouds and devices is unwieldy and increases security risks. Steve Wilson, Citrix Vice President of Cloud,...
Artificial intelligence, machine learning, neural networks. We're in the midst of a wave of excitement around AI such as hasn't been seen for a few decades. But those previous periods of inflated expectations led to troughs of disappointment. This time is (mostly) different. Applications of AI such as predictive analytics are already decreasing costs and improving reliability of industrial machinery. Pattern recognition can equal or exceed the ability of human experts in some domains. It's devel...
The term "digital transformation" (DX) is being used by everyone for just about any company initiative that involves technology, the web, ecommerce, software, or even customer experience. While the term has certainly turned into a buzzword with a lot of hype, the transition to a more connected, digital world is real and comes with real challenges. In his opening keynote, Four Essentials To Become DX Hero Status Now, Jonathan Hoppe, Co-Founder and CTO of Total Uptime Technologies, shared that ...
The Japan External Trade Organization (JETRO) is a non-profit organization that provides business support services to companies expanding to Japan. With the support of JETRO's dedicated staff, clients can incorporate their business; receive visa, immigration, and HR support; find dedicated office space; identify local government subsidies; get tailored market studies; and more.
As you know, enterprise IT conversation over the past year have often centered upon the open-source Kubernetes container orchestration system. In fact, Kubernetes has emerged as the key technology -- and even primary platform -- of cloud migrations for a wide variety of organizations. Kubernetes is critical to forward-looking enterprises that continue to push their IT infrastructures toward maximum functionality, scalability, and flexibility. As they do so, IT professionals are also embr...