Link Search Menu Expand Document

Broken Authorization in PHP

Prevention

PHP does not provide any authentication and authorization mechanism that can be implemented using sessions.

The login.php script checks that the credentials submitted by the user are saved to ensure the user role persists as a session variable in $_SESSION.

<?php
session_start();

if ( isset( $_POST['username'] ) && isset( $_POST['password'] ) ) {

  // If returns a string with the role name or NULL if the credentials are wrong.
  $role = password_verify( $_POST['username'], $_POST['password']);

  if ( $role ) {
    $_SESSION['name'] = $_POST['username'];
    $_SESSION['role'] = $role;
  }
}
?>

Other pages check that the user is logged in before accessing any privileged parts of the code.

<?php

session_start();

if (  $_SESSION['role'] == "admin"  ) {
    // Administrative functionalities
} elseif (  $_SESSION['role'] == "user"  ) {
    // User functionalities
} else {
    // Redirect to loing page
    header("Location: /login.php");
    die();
}
?>

Many PHP frameworks have authentication and autorization mechanisms already built-in.

Symfony

Symfony provides several authentication providers to manage the login process. The endpoint can be protected by authorization controls using access_control in security.yaml to protect URL patterns (e.g. /admin/).

# config/packages/security.yaml
security:
    # ...
    firewalls:
        # ...
        main:
            # ...
    access_control:
        # require ROLE_ADMIN for /admin*
        - { path: ^/admin, roles: ROLE_ADMIN }

For more flexibility, the authorization can be written inside the controllers calling denyAccessUnlessGranted. If the access is not granted, AccessDeniedException is thrown, and no more code is executed.

public function adminDashboard()
{
    $this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'User is not authorized to use this admin functionality');
}

The authorization on controllers can be also enforced using annotations:

/**
 * Global control for *every* controller method in this class.
 *
 * @Security("has_role('ROLE_ADMIN')")
 */
class AdminController extends AbstractController
{
   /**
    * Control for only this controller method.
    *
    * @Security("has_role('ROLE_ADMIN')")
    */
    public function adminDashboard()
    {
    }
}

References

PHP - Sessions Basic Symfony - Security Symfony - @Security & @IsGranted