PHP Security

Learning PHP on your own – 6 most ignored security concepts

We all have different approaches to learning. While some prefer having a mentor, others prefer learning in institutes and then there’s some who prefer learning on their own. I have seen many self learners in the tech field. Infact this Stackoverflow survey shows that 41.8% respondents (a majority) were self taught. I strongly believe the stats are proportionate to the larger world as well.

Active communities, learning resources, numerous channels like Video, interactive websites, online courses etc have made self learning very easy and convenient especially in the tech space.

However, a common trend among most people learning PHP, is that there’s a tendency to focus entirely on functionality (Ensuring the code works). After all, that is the most tangible aspect of your work. Moreover most learning resources and examples also focus more on functionality. As a result, many crucial aspects like security, optimization, programming methodologies etc remain neglected.

This is a series of posts about things most often missed out on while learning PHP.

Let’s start with PHP security, as I believe there’s nothing as important as this.

PHP is great. After all there has to be a some reason for it to support approx 80% of all known websites. While PHP is great, like every other language it has some security flaws. These flaws can lead to devastating scenarios if not handled properly.

Below are some security practices to keep in mind while Learning PHP.

  1. Always use PDO

SQL_Injection

PDO is more or less a layer between your application and the database. It helps bring about consistency in the way different databases are accessed from the application,

Most PHP examples out there use MySQL or MySQLi. Moreover the term PHP is often accompanied with MySQL. As a result, self learners, would research about MySQL and use it directly with PHP. This works, but is not safe.

One of the biggest risks of using mysql directly is SQL injection which ranks one on the OWASP top 10 list.

SQL injection is when some SQL code is injected (inserted) into the MySQL query. Here’s a simple example.

Let’s say your SQL query is

and the variable $username and $password is populated from a login form. In such a case, if someone simply entered

as the username and password, the resulting query being executed would be

This will return one (or many) valid entries and thus can always return true for authentication.

While there are many ways to mitigate this risk (prepared statements & mysql_real_escape_string) for example, these ways are not always foolproof.

A better approach is to use PDO (PHP Data objects)

It brings not only consistency but also security to database interaction. The points mentioned above (Prepared statements and string escaping) are implemented and encouraged in PDO. If you’ve been using MySQL for a while you might find the need to “bind” and prepare as unnecessary steps. Trust me they help. If you’re still in the initial phases of learning PHP and MySQL, switch to PDO right away, you would be saving a lot of time and effort in the future.

2. Sanitize Output

XSS

Sanitizing is basically removal or formatting of unsafe text so it’s safe for use. Any data whether input or output must be sanitized appropriately. Certain characters are known to cause problems as they represent different meanings in PHP and HTML. For example quotes ( “<” ) represent the start of an HTML tag, as well as a less than sign. Thus if the character “<” was sent to a browser, the browser might think it’s part of an opening tag. This property can be exploited to conduct XSS (Cross Site Scripting) attacks. Keep in mind, “<” is just one of the many examples. The longer list would include almost all html tags, brackets, special characters etc.

Like SQL injections XSS also involves injecting code to run exploits. The only difference is, here the code is injected into the front end code of a webpage and executed when a user loads the page. In most cases, the code would be javaScript.

Here’s a simple example.

Let’s say you have created a site like twitter, where people can make text updates. The updates are stored in a database and displayed when a friend / follower logs in. The following code can be entered as a status

In this case the browser would read the <p as an opening tag and thus render a <p> element. Hence the onmouseover code would also be loaded and ran. While the code here only displays an alert, much worse things like stealing cookies can be done in the same way.

Hence it’s important to “tell” php / browser that these characters are not the code you think they are. PHP has a few useful functions for doing this. Some are as below

  1. htmlentities – Characters like “<” are also represented with “&lt;”. When a browser sees a “<” it thinks it’s part of an HTML tag, however when it sees “&lt;” it renders a “<” as plain text. htmlentities() converts all such characters to their equivalent encodings so the browser reads them as text and not code.
  2. htmlspecialchars – Just like the previous function, this function also converts characters to text encoding. The only difference – the previous function applied to html characters (“<“, “>” etc) while this function applies  to special characters like “&”, “!” etc. In this case the function would convert “&” to &amp.
  3. strip_tags – Strip tag simply removes all html / php codes from the variable’s value. So in this case text like “<p>”,”<div>” etc would simply be removed.

3. Be extra extra extra cautious when using forms

CSRF

Forms are simply an open door for data into your application. While it’s necessary to let users send data to the application, it’s not necessary to trust them. The two main concerns with forms is

  1. The data might be malicious
  2. The person sending it, might not be the user himself

We have already covered a bit about handling malicious code already, so I’ll focus more on the second point, the person sending the data.

Picture this, you have logged into an online shopping site (www.dummyshoppingsite.com) where you have already saved your credit card information for convenience. Usually when purchasing a product, the following request is sent to the shopping site to complete the transaction.

An attacker could craft a url as

and then share it with you via mail / social media or some other medium. Thus if you clicked it while you were logged into the shopping site, the shopping site would assume it came from you and proceed with the transaction.

These attacks are knows as CSRF (Cross site request forgery) attacks. Attacks like these can be best mitigated by using a CSRF token (ID unique for each user as a hidden input in sensitive forms). This token can be used to confirm the user submitting the form.

These tokens can be made easily using unique aspects like the current time + IP of the user and then hashing it (more on hashing in the next section). This value can then be stored in a session and then checked on the server side before acting on a form.

4. Hash Passwords

Hashing

One of the most common mistakes made with password storage is storing it as plaintext. Passwords should never be stored as plaintext because

  1. Your users might like you, but won’t trust you with their password. Plain text gives you (and anyone with database access) visibility to everyone’s password.
  2. An attacker only needs to gain access to your database, from there on it’s all a piece of cake.

Hashing is basically converting text of any length to a string of fixed length. It’s a lot like encrypting, the only difference being hashes cannot be reversed “sort of decrypted” to the original string – ever. The two most important things to keep in mind while hashing is

  1. Add salt to the password – Salt is a random piece of string added to the original password, so it cannot be guessed.
  2. Use a strong algorithm – MD5 for example is outdated and broken avoid using it

Reasons for using salt and a strong hashing algorithm is beyond the scope of this post. However this indepth article about hashing might help understand it better.

While there are a lot of PHP hashing algorithms and functions, it’s best to use

  1. password_hash – Creates a secure strong hash for storing purpose.
  2. password_verify – Verifies that a given password matches the given hash.

This is a better method because it handles both salt and algorithm by default.

5. Properly configure PHP.INI before going live

Configuration

Before going live, see that you properly set up your sessions and error messaging in PHP.ini.

PHP handles sessions quite well, however it is recommended to tweak things a bit to make them more secure.

Sessions

Error Messages

While error messages are great for debugging, they are equally harmful when your system is live (in production). Simple error messages like “variable not defined”, “unexpected data” etc can give crucial information to attackers.

This would basically display no errors on a page, but save them in a log file for debugging.

6. Read through OWASP as often as possible.

owasp

OWASP ( Open Web Application Security Project ) is a not-for-profit charitable organization focused on improving the security of software. You would find tons of resources with regards to security trends and mitigation techniques. Reading it periodically will program your mind to think from a security aspect as well, while designing software architecture.

While this is not in any way an exhaustive list, I hope it was enough to raise awareness about security. Safe coding!

Related Post

Tabnapping – A new hacking technique (and ho... With all the progress we're making in technology, there's also progress on the opposite side - Hacking. Most of us, by now, would be aware of some com...
How to create a website – Web Design and Dev... How does one create a website - I've come across this question a lot of times, mostly from people aspiring to learn web design or web development but ...

Related Posts