Category Archives: Uncategorized

The Day the World Will End

5
Filed under Uncategorized

With a new movie coming out about how the world will end with the (supposed) end of the Mayan calender, I figured it would be nice to get a list of software related “end of calender” issues:

Dec. 31st 1999, 23:59:59 GMT
The famous Y2k issue. We made it… (so far ;-) )

Jan. 10th, 2010, 10:10:00 GMT
“Binary Armageddon Day”. The binary representation, 1010011010 translates to ‘666′. Also, the date only includes 1s and 0s (other then the ‘2′ in the year). (thx Gadi. Also see Gadi’s facebook group about this issue ). If you are on facebook, you can find the group here: http://www.facebook.com/pages/Binary-Armageddon-Day

Dec. 21, 2012
end of Mayan calendar. Just listed here because everybody is talking about it. Should not affect software (other then the fact that the world will end that day).

Feb. 7th 2036, 6:28:16 GMT
The last date that can be expressed using “ntp”. ntp is a protocol used to synchronize clocks on the internet. The ntp date starts on Jan 1st 1900 and is expressed in 64 bits. The first 32 bits are used to indicate the number of seconds since Jan 1st 1900, the remaining bits are used as fractional seconds.

Jan. 19th 2038, 03:14:07 GMT
The end of the Unix epoch. Unix uses a 32 it signed number to express time. ‘0′ is January 1st 1970. The last date that can be expressed using unix time is Jan 19th 2038. After that… who knows? This can already be a problem. Imagine you are a bank and handing out 30 year mortgages?

Dec. 31st 9999, 23:59:59 GMT
The end of 4 digit years. Well, we got a while until that will happen.

Got any other dates of note? Let us know!

Pentesting: Do you need “coverage” ?

3
Filed under Pentest, Uncategorized

Last week, I had a discussion via instant messenger. The discussion essentially evolved around the need for coverage in a pentest. It has always been my conviction that a pentest should find as many problems as possible. In my opinion, the pentest is not over once I got root on the system. In many ways, this is where it starts.

I think it is a matter of pentesting philosophy. I see myself primarily as a coder. A pentest is for me part of my software testing regimen. Like my other tests, code coverage is of utmost importance. I don’t consider my application working until it has been fully and thoroughly tested. A pentest is just another, very special, test I subject my code to. As a result, I am not a big fan of “black box” testing, or “early dawn raids” as I call them. They may find a problem, but the tester will typically waste a lot of time finding and exploiting vulnerabilities, which may have been trivial to exploit with a bit of source code, or after talking to the developer. I rather have the pentester spend their precious time on going after yet another possible vulnerability.

I do understand that a pentest does not find all bugs, but the aim should be to do just that. I strongly believe that a pentester should be held to the same standards as a developer. Would you accept software that works once? Code that only has one bug fixed? Just because it is hard, doesn’t mean that we shouldn’t attempt it. In many ways, this is what I enjoy about being a developer: Hard problems.

Is it possible to come close to the goal? I think it is. All of this is based on a good framework and to apply this framework thoroughly. You do your recognicance, and don’t stop at the first web application you find, unless the scope of the project limits you. Next, you map out the web application, and try to find not just all URLs or “pages”, but all features. A feature you miss in the mapping phase will be a feature you miss in your test. Next, you discover vulnerabilities. And finally, you try to exploit them. Once you manage to exploit a vulnerability, you are likely to find more content and your process starts all over again.

Sounds boring and tedious? Yes it is! If you don’t know how to script. I say this a lot: If you don’t script, you will soon be replaced by a script. If you want to distinguish yourself as a pentester, you will have to understand your tools well enough to extend them and build upon them.

Various PHP and MySQL pitfalls

2
Filed under Uncategorized

This is a short post, to summarize some of the issues I see with PHP code and the use of MySQL. Not too many people know about these pitfalls and they are given rise to some of the more subtle security issues:

1 – “SQL Overflow”

If a value you insert into a column is too large, it is truncated silently. This can lead to security issues if you don’t validate that the submitted string is of the right length.

2 – “Trailing White Space Ambiguity”

Trailing white spaces are removed by MySQL silently. For example, these two queries retrieve the same result:

select role from user where username='Admin';
select role from user where username='Admin   ';   (note the space at the end).

3 – Unbalanced comments

Older versions of MySQL allow /* to be used unbalanced. For example,

select now() /* test

will work. Newer versions of MySQL require balanced comments (unbalanced was always “illegal” according to the documentation

4 – php ‘rand()’ function returns bad results

If the argument exceeds the maximum integer, you will get not-so random numbers back. This one depends a bit on the version of PHP you are using. But you will not get an error. Instead, you will get negative numbers, or numbers that are not random (e.g. only last couple of digits change).

5 – MySQL “–” comments require a white space

In order to use “–” as a comment, it has to be followed by a whitespace.

select now() –test  will fail
select now() — test will work

You don’t have to use a space. A tab will work just fine and evades some filters.

Got some to add? Use the comments ;-)

My Top 6 Honeytokens

6
Filed under Uncategorized

A few years ago, I was looking for a new developer to join our team. Of course, the hard part was to find a developer that was up to the task. I don’t believe much of what people say in their resumes, so I rather had them show me a site they coded and give me permissions to take a closer look. Many of the sites failed miserably after only some minor probing. The result was a small guide I published to summarize my experience, Web Application Auditing over Lunch. Sadly, a lot of attacks are just so simple. But then again, lets see how we can turn this around and use it against the attacker. An attacker will likely try to use simple tricks just like the once outlined in the guide. As a counter measure, I am using a set of “honeytokens”. Simple tripwires to alert me of an attacker.

  1. Don’t hand session credentials to automated clients: Whenever a browser identifies itself a “wget”, or a search engine, don’t bother setting a session cookie for them. They shouldn’t log in. Yes, it is easy to fake the user agent. But many attackers don’t bother.
  2. Add fake admin pages to robots.txt: Add a fake admin page as “Disallowed” to your robots.txt file. We all know of course that robots.txt should not be used as a security tool. But many websites still use it that way and as a result, attackers use it as a road map to attack a site. Whenever someone hits your fake “admin” page, you know they are up to no good.
  3. Add fake cookies: Add a fake “admin” cookie and set it to “FALSE”, or “No”. This is a classic mistake attackers are looking for. But you are of course not using this cookie to assign admin privileges. Instead, you detect attacks whenever the cookies value changes.
  4. Add “spider loops”: Little redirect loops to send spiders in a loop. Be nice, and add “NOFOLLOW” tags to not annoy legit search engines too much. See if anybody falls for it. It is kind of like a La Brea tarpit for web application vulnerability scanners.
  5. Add fake hidden passwords as HTML comments: On your login page, add a comment like <!– NOTE: developer test login, user: alkhewr password: 234kjw –> … Wait for someone to use it :-)
  6. “Hidden” form fields: This is different from the <input type=”hidden”> form field. Instead, add a regular form field <input type=”text”> but set the style to “display: none” . That way, the form field will not be visible to normal browsers. But vulnerability scanners will happily fill it in. Note that this can be a problem for “audio browsers” used by the blind. You may want to pre-fill the form with something like “do not change this field”.

Now isn’t that all just about hiding more serious vulnerabilities? Security through obscurity? Sure … it is… but it works. In my opinion, a good defensive technique is easy to implement but hard to bypass. These techniques only take minutes to implement, but break most automated tools and will cost hours of the attackers time.

You have to decide for yourself what to do once you detected an attacker. Maybe just hope for the attacker to go away? A more aggressive, but dangerous approach is to automatically shun attackers. It all depends on how much you are willing to lock out the wrong person. In particular the hidden URLs in robots.txt are dangerous as someone who discovers the trick my now spam this hidden URL to your customers and lock them out of the side if they click on it. If you decide to shun attacker: Have a plan ready to mass “unblock” a large number of false positives.

Got your own tricks like that? Let us know and write a comment below!

An Encrypted Password Experiment

9
Filed under Uncategorized

Jason’s blog post (”How Not to Do Website User Registration“) certainly attracted a lot of comments! I think articles like this exceed my expectations about this blog. Back before we had “blogs”, we had the Internet Storm Center diaries, which are still going strong. I always felt that the best diaries are the diaries that don’t have all the answers, but diaries that stimulate discussion and feedback.

With that comes the need to sometimes step back and consider that I don’t have all the answers. In particular, we have to keep in mind that we don’t secure websites just for themselves, but we secure websites so they can fulfill a function. 32 characters random passwords, which have to be changed daily, are just not the solution. I am always interested in ways to make software more secure without impacting usability. The way I sometimes put it: “Security is not about preventing a breach, security is about staying in business”.

Now how does this apply to website registration and encrypted passwords? A dilemma I always had: I hash all my passwords in the database. I use SSL to transmit the password and cookies. But I hardly ever encrypt the password itself as it is transmitted from the browser to the server. You may say: Wait! We got SSL for that! Right, but remember SSL is just protecting the password. The website still ends up processing the clear text password. What is needed is a way to encrypt the password on the browser before passing it to the server.

The Internet Storm Center is one site that I like to use for experiments like that. However, the only way I know how to encrypt passwords is to use Javascript. I also have a rule not to force users to turn on Javascript. I may use it for the usability improvements, but the site has to work with Javascript turned off. I know this is an anachronism in today’s Web 2.0 world, but you should see some of the hate mail we get just for using cookies.

HTTP actually has a decent way to encrypt passwords, called Digest authentication. But it has other problems and is not really an option for many sites.

Here is the solution I came up with: Make it optional. If Javascript is enabled, it is used to encrypt the password and the original clear text password is not sent. If Javascript is not enabled, the password is sent “as before”.You can check out the Javascript code at https://isc.sans.org/login.html .

I am using a SHA1 hash. Sadly, Javascript doesn’t have a SHA1 function natively, so I am using an implementation of the SHA1 algorithm in Javascript that appears to work pretty well (see http://isc.sans.org/js/sha1.js).  The database stores the sha1 hash of e-mail address and password (sha1(email+password)). I could just pass this hash, but I well, since I hash the password anyway I want to do it right and avoid reply/”pass the hash” style attacks. So the server sends a “nonce” first. The nonce is a random value. The client now appends the nonce to the password hash and hashes it again. So the final hash function is:

sha1(sha1(email+password)+nonce)

The server stores the nonce in a session, and can do the same calculation using the password hash stored in the database.

This way the server is only exposed to the original password during the account creation and whenever the password is changed. You may ask why anybody would care about their ISC password… well, maybe if they use the same password for their online banking, I just don’t want to touch it. Information becomes a liability pretty quickly in these cases and sometimes you have to protect the users from themselves.

So here my questions:

- Is this effort worth it? Am I fighting a real threat or am I just an obnoxious security fanatic?
- Are there other solutions?
- What did I do wrong? Any holes in this scheme? (I do consider sha1 good enough for this case)

[digg=http://digg.com/security/Javascript_Password_Encryption_for_Web_Applications]

Web application penetration testing VS vulnerability assessment

2
Filed under Pentest, Uncategorized

I deal with infrastructure and application security testing on a regular basis. On the infrastructure/network side, the consulting and testing market is much more mature, definition of pentest and vulnerability assessment are industry accepted. It is easy to communicate with other folks about the work involved. On the application side, things are not as well defined. It will be at least a couple more years before the definition or an “application pentest” is accepted.

What is vulnerability assessment?

According to Wikipedia, “A vulnerability Assessment is the process of identifying, quantifying, and prioritizing (or ranking) the vulnerabilities in a system.” In short, it involves anything to determine if there is a weakness or vulnerability in the system subjected to the assessment, then report on it. For application testing, you would throw some test input at the application or try a number of test cases and see if it is vulnerable to any of the vulnerabilities you are testing for.

In general real world terms, the tester for a VA (vulnerability assessment) is expected to perform the reconnaissance phase which allows the tester to understand the application well enough and determine if there are any short cuts to compromising the system. Also, gathering enough data about the application (such as platform it is running on or what other virtual hosts are running) to allow later testing phases.

Then, the tester is expected to map out the application and understand the application flow and relationship between objects in the application. Some of the vulnerabilities such as business logic flaws may also be revealed at this phase. Following mapping is the discovery of vulnerabilities, for input related flaws it might involve automated tools and manual validation test. There are also various other test cases that need to be manually test,  especially on the session related and access controls related flaws that are not easily automated.

In general, testers follow a common testing framework such as the OWASP Testing Guide, to ensure sufficient coverage of vulnerabilities during the process. After the discovery, the vulnerabilities are evaluated and usually manually verified again. Then a risk rating is given to each vulnerability to be included in a report.

Running a vulnerability scanner against a web application is a form of vulnerability assessment. It is also a form of assessment that is not very complete or thorough, in general, an automated scanner covers about 50-70% of the vulnerabilities in a given application.

What is penetration testing?

Penetration testing or “pentesting” includes all of the process in vulnerability assessment plus an important extra step, which is to exploit the vulnerabilities found in the discovery phase. You may ask, “Just a one step difference?” Pretty much, but this one step could separate the boys from the men. I often tell the students in my pentest class that it is common for a pentester to spend 20% of his/her time locating a single vulnerability and then 80% of the time is spent exploiting that vulnerability. The process of exploitation usually involves a lot of trial and error and may not work the first time. Depending on the type of vulnerability being exploited, some other system general knowledge maybe required to aid the exploitation process.

The better pentesters don’t usually stop at exploiting one single vulnerability. For example, a single CSRF vulnerability can be somewhat limited, bundle that with a XSS vulnerability and you have a much bigger problem at hand. In a lot of cases, an expert pentester can leverage two or three low to medium  risk vulnerabilities and turn the result into a critical exposure.

The added benefit of a pentest is able to see the vulnerabilities being put into active exploitation and show the actual maximum effect.Due to the nature of pentesting, the exploitation does not really have any established framework. The exploitation is highly dependent on the skillset of the invidual/team performing the test.

An example to show the difference

Let’s use an example to illustrate the difference. Let’s say the tester is testing for SQL injection and a single quote (’) is put into all input field. In a particular field, when a quote is put to the field, a SQL error is generated in the resulting page like this, “You have an error in your SQL syntax near ‘\’0′ at line 1″  This is tell-tale sign of error SQL injection. A vulnerability assessment might just do a bit further validation such as trying to dump current user name to validate the vulnerability and then goes into reporting.

A pentest on the other hand would likely be taking a lot more time on this error alone. The pentester would figure out how to tag on extra logic or command structure into the current SQL statement so that the tester can control the SQL database. If possible, the tester will enumerate the database structure and possibly dump the whole database content. If the permission is not set properly, the pentester may also be able to jump into OS command context and start executing commands in the OS. Obviously, all these attacks requires patience and takes a lot of time to succeed.

What’s more popular?

If there is such as difference and pentesting is so much more in demonstration, why don’t we just do pentesting then? Well, there is always a costing difference making pentesting significantly more expensive than a vulnerability assessment. In fact the market is currently leaning towards pentesting; those who are concerned about web app sec are willing to spend the money to get what they think is the best. (cost more, it must be better)  In the next few years, as the general public are more educated about security testing for web applications, I am sure the market will adopt both services – vulnerability assessment and penetration testing. Until then, I have to be very careful about listing requirements and looking at quotation for security testing consulting work.

Logging Links to 3rd party provider

0
Filed under Uncategorized

While web application spans over multiple sites boundary, it is essential to keep track of where the users are being directed. This is pretty much a basic logging and audit trail concept. While it is easy to understand in theory, it is not always easy to see where it should be implemented. Development communities sometimes have a harder time to understand why this is important, so let’s examine why it is a good idea to do so. If you ever have to explain to others why you should do this, hope this info will become useful.

Internal redirection or links

While directing users on the same site (same server) using HTML links, it is easy to track where the user is visiting. Each of the link that the user followed will be in the web server log and it is not difficult to trace the footstep of a specific user (with IP address).

External redirection or links

When directing to an external site using HTML links, there is no way by default to track the user’s activity. The webserver log doesn’t track the user’s visit to an external site, only the destination server logs it. The browser fetch page from another site and does not necessarily report back.

Why is this even important?

It is common for applications to be spread out in different servers or even different organizations. An online retailer may present products for user’s selection and then let the user click on the checkout button to be directed to a payment processor for finishing the transaction. If the payment processor in this example is compromised, how do the retailer know who clicked on the checkout button if the button is a straight link to the payment processor? The chances of an audit trail is minimal.

On December 2nd, 2008, Checkfree Billpay site was compromised, this is the organization that owns about 70-80 percent of online bill payment in the US. A lot of the banks simply forward their clients to Billpay using HTML link for bill payment function. It is essentially an application service provider for a lot of the US banks. The attackers were able to hijack the DNS entry of Billpay’s domain to a malicious site hosting malware awaiting to infect visiting users.

When performing incident handling on issues like this one, “who went to the compromised site” might be one of the first question to be answered. If a straight HTML link <a href=> style external link is used, there is not a whole lot of chance to be able to answer that question.

What’s the right way to do it?

While directing user to an external service provider, make the link internal. The link should be targeted at a redirection script. The script uses a 301 redirection header to direct the user to external provider’s site. This way, there is web server log (for IP logging) and also application log which is done by the redirection script. The application log should have user name information since it should be session aware.

For the redirection script, it is important to ensure the issue of open redirect does not exist. User should never be able to tell the script the exact URL to be redirected to.

——————————————————

More information on the Checkfree compromised can be found here and here

Logging Cookies and Ambushing Lazy Pentesters.

5
Filed under Uncategorized

Logging is probably one of the dry topics in application security. Without logs, debugging or even incident handling is soo much more exciting! One of the little Apache tricks I learned is to log cookie information in your Apache log. The cookie typically includes the session ID, which then links to a particular user. So this way, you can figure out which user caused a particular action. Yes, in many sites you can just use the IP address and the time stamp. But this is more labor intensive and not as accurate. It only works well in sites nobody actually visits. Apache typically logs after the complete page is served. Your own application logs however are written (and I hope you do have application logs!) while the page is created. There may be a few seconds difference which can be a pain to link up if you have a few hundred hits a second.

So here is the little added logging directive:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\"
           \"%{User-Agent}i\" \"%{Cookie}i\"" withcookies

Here I just used the “combined” log format, and added the cookies to the end. You can add any request header using the “%{headername}i” scheme. The quotes have to be escaped if you use double quotes to enclose the header. Now to actually log using the header just add

CustomLog /var/log/httpd/access_log withcookies

You probably already have a line just like this using the “combined” or a similar format. Make sure your log analysis tools know how to deal with custom log formats.

But this is the “Streetfighter” blog, so lets take this idea a notch further. Many pentesting classes ask pentesters to look for “bad cookies”. This is session information that should be kept on the server but is too often kept in a cookie. For example, the userid. Pentesters are aksed to look for cookies like “userid” and see if the value matches their userid. If so, they will next try to modify the userid. Well, we got a surprise for them:

We do set a “userid” cookie, and you may even set it to the users userid, but you essentially ignore it. You only check if the cookie’s content matches the actual userid stored in the session. If not… give them a good kick. I like to disable the account for 30 minutes. It sure slows them down. If it was a real hacker: Remember the old hiking rule: You don’t have to outrun the bear, you only have to outrun your hiking buddy. A little trick like this can make your side too much of a hassle to attack and they will move on to a simpler site. Lots of vulnerable sites to go around!

(In some cases, you may have false positive issues if your site’s users are in particular playful. But then again: They shouldn’t “play” with your site. You may just want to trigger a log entry to catch excessive abusers)

How Not to Do Web Site User Registration

48
Filed under Uncategorized

The Internet is FULL of real life scenarios of how NOT to do web application security…it is unfortunate when a large, popular site shows the rest of the world some form of this inappropriate behavior. Unfortunate because it becomes both a HOW-TO for programmers, marketers, decision makers to repeat as well as an illustration of what NOT to do for the infosec community to harp on – both are undesirable.

Here’s a few screen shots I took while going through Account Registration on WordPress – this is a classic case study in what not to do.

While jumping through common hoops of account creation, WordPress required email address verification before activating my newly created account. After creating my account and waiting a few minutes, I was greeted with the following email requesting that I click on a link to verify that my email address did, in fact, belong to me:

Email notification of WordPress Account Activation Requirement

The names and email addresses have been removed to protect the innocent. This is pretty standard so far, no surprises – create an account, get an email, click the activation link, activate the account, login, good to go…

But then to my surprise, I’m greeted with the following Activation web page:
WordPress Credential Reminder

This is one of the very very few times I recall being shown both my user name and password on a web site. This can only mean that WordPress is storing my password in plain-text in their database or using reversible encryption – I suspect the former – plain text…with this knowledge I then glance up at the URL. *Sigh* – http:// – no ’s’, meaning this was sent over the wire unencrypted for anyone paying attention as my credentials bounced from Columbus, OH up to Cincinnati, OH -back down to Atlanta, GA and then over to Dallas, TX – at first I wanted to kick myself – I should have been paying more attention to the activation email link and noticed  the lack of the ’s’ and added it manually – but wait, why would I? I didn’t expect to be shown my credentials…this is not common.

Then I notice I have new Email…WordPress has also sent me an email notifying me that I have activated my account. View it in all its glory:Your Account has been Successfully Activated

Good GOD how many times do I need my credentials delivered to me over an unencrypted channel! Not to mention they managed in the email to group all information conveniently together – user name, password, AND login link…

I’ve seen flawed Password Reset schemes, but I think this might be the first poorly implemented Registration workflows I’ve run across and took notice.

Some quick tips for a more Secure User Registration:

  1. Perform all operations containing credentials (user name/password) over a secure connection. E.g. SSL/TLS
  2. Store passwords in the database using a one-way hash algorithm like SHA-1.
  3. Additionally, salt users password when generating the hash based on something unique to the user whose account you are protecting. The salt doesn’t have to a secret piece of information.
  4. If passwords must be recoverable (which should be a RARE requirement) store them using accepted open encryption algorithms – e.g. AES, 3DES.
  5. Never email a user their password.

Finally, I noticed that if you have my activation ID – without an authenticated session, you can go back and visit the activation page – anyone can now retrieve my email address and login name. Thankfully after the account is activated the first time, all subsequent requests do not reveal the password again, however, they do reveal my email address and user name which is completely unnecessary. Here’s what you see if you visit the activation page again after already activating your account:
What Subsequent Visits to the Activate Page Reveals
I’m going to add a 6th tip: There’s no need to keep telling the user they have activated their account once the activation key has been used- and there’s also no need to reveal the user name and email address to an unauthenticated user on the activation page – this only gives an attacker more information that they can use to reset the victim’s password and gain access to the account – for instance, when an attacker finds a valid activation id they could follow it up with a spear phishing attack to easily gain that final piece of information from the victim to compromise their account.

And here comes Tip #7: Since the activation page can be revisited and because the Activate ID is in the URL, this URL will be cached not only on the local users computer browser, but in web server logs, proxy server logs, router logs, firewall logs, etc. on potentially any system from here to Texas. If the activation key was discarded after first use or did not reveal any interesting information to begin with..who cares…but this is not the case.

While these features may be a benefit to users of WordPress (which is debatable, as it was overly repetitious), these features add an unnecessary level of Risk with little gain.

Also, I’d recommend going in and changing your WordPress password after registering – and hope they don’t email it to you again…they don’t appear to anyway…*fingers crossed*

* Update – it’s been over 16 hours and the activation link still works, revealing my user name and email – I’ll be checking back to see when it actually get’s removed. Additionally, I did not receive an email containing my updated credentials after I changed my password on WordPress…so the recommendation to change your password seems like a good one.

* Update 2 – Readers are reporting that WordPress does in fact hash the password, but only after mailing the plaintext one back to the user. And to clarify – many have suggested that WordPress is sending a randomly generated password. That is not the case. The password emailed to me was most certainly one of my creation.

A Proposal for a PHP "UserData" Class

5
Filed under Uncategorized

The title of this blog is “Application Security Street Fighting”. It is based on an idea I am pursuing for a while now. The goal is to come up with a set of simple and reproducible techniques to secure applications. Personally, I favor coding in unstructured languages like Perl and PHP for all the wrong reasons: It is fast and I am able to focus on the result. For example the first version of DShield.org was created over a Thanksgiving weekend. It worked “great”, crashed hard on the first Slashdotting and set the server I build for cheap on fire during the Code Red outbreak. But it survived! (The fire destroyed some of the insulation on the power supply, but amazingly the server kept on running for another two weeks until I was able to replace it. The best $400 home made server I ever had).

However, you will not find much of the original code in the DShield site of today. I probably replaced it 3 or 4 times just that first year. Each time, I learned a bit more about PHP. On the other hand, the site would probably not exist if I had done it “right” the first time. Coding slow kills momentum and opportunity.

Now how do we code fast and safe? Most developers associate secure coding with slow coding. I think there are a few misconceptions when it comes to secure coding, and I would like to address some of them in this and future blog posts. In this post, let me focus on user input validation, one of my favorite topics.

How do I validate input securely using php? For deep and complex questions like that, there is only one answer: Google it! . The first link that came back for me was a page on Techrepublic, “Secure your Web Applications by validating user input with PHP“. The solution presented on this page gets some things right: It uses a PEAR library, “Validation”. Less code to write, less bugs to fix! At least the way I code, reusing code works always in my favor. But let’s look at the rest of the code:

extract($_POST);
// check name field
if (!$validate->string($name, array("min_length" => 1))) {
  $errors[] = "Error in NAME field";
}

Now you may want to argue the use of the “extract” command, but well, this is not the point here. The problem is that you need to first pull the user submitted data out of the super global array like “$_POST”, then you need to validate it. And you need to do this every single time. I can tell you, it gets boring quickly. Before too long, you will miss a spot. If you clean a kitchen floor, “missing a spot” means having a happy dog help you fix the problem later. If you miss a spot in your PHP script, you got a vulnerability! That’s right: As a developer, you have to get it right every single time.

Personally, I find user input validation one of the more boring parts when coding. I would rather make sure my business logic is soundly implemented. So let me talk about a different approach I got to like lately:

  1. Start out by pulling all the user submitted data into an object.
  2. The only way for you to get to the user data is to call an “extraction” function, which will also validate the data.

For example  a bit of pseudo code:

$oUserData=new UserData($_POST);
$sName=$oUserData->getName("firstname");

And this is what the class approximately would look like (pseudo code)

class UserData {
  protected $aData;

  function __construct($aSource) {
    /* pull data out of source and assign to $aData */
    /* and clear out $aSource */
  }

  function getName($sLabel) {
    if ( is_name($this->aData[$sLabel]) ) {
      return $this->aData[$sLabel];
    }
    return false;
  }
}

Cool. So now we got a very simple mechanism to extract validated user data. As a developer, I need to write the validation functions only once. The constructor for the class should also clear out the initial unvalidated userdata to avoid accidents down the line.

I will expand on this idea in future posts. Again: The idea is to write secure code without getting lost in endless and boring input validation exercises. That’s what I consider “application security street fighting”. It’s not pretty, its not fancy. But it works. We need to find simple and repeatable techniques that work every time.