fbpx

How to build a secure PHP webpage: Part 2

  • Home
  • Blog
  • How to build a secure PHP webpage: Part 2
How to build a secure PHP webpage: Part 2

When it comes to making a website, a few features are common to most: user sessions, cookies & a login/registration system. In this article, we’ll look at those more in depth to try and explain key ways that help ensure their security. Note that this article is still aimed at helping code such features, so some code examples will be provided.

A key insight that will help build a secure PHP webpage comes in two fold from my experience: try to keep security in mind when designing it & try to break your own creating via any user input either directly or indirectly whenever possible.

Session management

Session management often begins by managing user credentials, but most will forget to properly handle session tokens, however, session tokens are just as important as credentials since they generally pose the same security risks if compromised. A key attribute that is often left unchanged is the session token entropy, but over time this should change because of advances in computer science & user increases. Now if you’re running a small website with little users, this isn’t a big risk since the default PHP configurations will suffice, but as your user base grows, so does your risk in this attribute. Generally it’s recommended to at least have a session key of 128 bits long, which is luckily bellow the default that PHP 7.1.0 implements.

Another attribute of session tokens that is often overlooked is the lifetime of the tokens. Now this part comes in two fold, the first point is that the lifetime of the session cookie should always be set to a short amount of time that’s not so long that it might become a risk to the users. Typically the PHP session cookie will last around 24 minutes, which is quite short if the application will be used for a long duration.

Setting it to longer periods will allow a lower amount of refreshing of this token and possibly re-authentication by the user which is generally preferable. However, setting a session token to last for months on end would also encourage Man-in-the-middle attacks so setting the session cookie’s lifetime to a week or a few days is generally preferable. Now the second point here, is that the lifetime of the session token should not only be enforced on the user’s browser, but also on the website’s end. To achieve this, we can save in a database a timestamp of the creation with the session token when it gets assigned to a user. Lastly, all that’s needed is to ensure the date saved on the server is verified before processing any requests.

As an added layer of protection against Man-in-the-middle attacks it is generally a good idea to issue a new session token to a user after they’ve authenticated with the website. This ensures that if the person’s session token was stolen before being authenticated on the website, the token would then become useless to the attacker since it would not be an authenticated session token.

Cookies

A key technological component for modern websites is cookies, this allows the website to track the user, to store information on the browser & do a multitude of things. But the lifespan of a cookie isn’t always the same, this depends if it’s a session cookie or a permanent cookie. A session cookie is deleted from the browser when the “session” ends, which is controlled by the browser. A good example of this is when someone closes a private/incognito browser session, all cookies collected during it’s use will typically be deleted. A permanent cookie however is a cookie that will only be deleted when it’s set to “expire”, which is a property called “Expires” that can be controlled by the website as seen bellow:

session_start([‘cookie_lifetime’ => 604800]); // 7 days cookie lifetime

Note that in this code, the “lifetime” is the amount of seconds before the cookie is deleted by the browser.

Registration

When it comes to registration, checks on user inputs are often done on the user’s side using HTML & JavaScript. However, those checks should always be done on the back end as well to ensure that the incoming user data is sanitized and of proper form. A key detail too, is that these checks both on the front end and the back end need to be in sync to avoid potential bugs.

One common registration check is that an email is valid, now to achieve this, the front end needs to ensure the email is of a proper form & then the back end needs to again verify the proper form of the input. But, the validity of the domain needs to also be checked which requires the PHP code to check that the domain exists & that an MX record is present. The MX record is the DNS entry pointing to the email server, which must exist for the domain to offer an email service. As seen bellow is an example of a PHP function that verifies both of those requirements:

public function isValidEmail(string $email): bool {

if (strlen($email) > 0 && filter_var($email, FILTER_VALIDATE_EMAIL)){

$domain = explode(“@”,$email);

if (!is_null($domain) && array_key_exists(1, $domain) && checkdnsrr($domain[1], ‘MX’))

return True;

}

return False;

}

Registrations often demand more then an email, so for other types of inputs, it’s recommended to at least use filters, which are standardized and reusable. In essence, it’s a bunch of pre-saved regex set, which can be reused. This comes in handy when validating or sanitizing user inputs. So depending on your use case, using these will help you avoid reinventing the wheel as well as get some high quality regex.

So far we’ve covered some of the basics, but never forget that a good mindset is always helpful when it comes to securing code. Reviewing your code after changing your mind and doing so with the mindset of an attacker can yield useful results. In future articles we might look into the following attack vectors aimed at web applications: XML Entity Injection, Information Leakage & Cross-Site Request Forgery.

Leave a Reply

Your email address will not be published. Required fields are marked *