IERG4210 (Spring 2021)

Authentication and Authorization

Sherman Chow

Agenda

  • Session Management
    • HTTP: from Stateless to Stateful
    • Session Maintenance: Cookies, HTML5 localStorage
    • Extension to Server-side Session Storage
  • Authentication & Authorization
    • Authentication vs. Authorization
    • Authentication using Cookies
    • Authentication using HTTP Auth
    • Authentication Attacks

Session Management

HTTP is Stateless

  • Each request is independent of each other
  • Sufficient for serving static content (.html, .css, .jpg, etc.)
  • But the server cannot tell which requests come from the same user
  • Why useful? for personalized services and user conveniences
    • e.g., any signed-in user experience
    • consider you need to enter your password again after each click
  • "Solution": associate requests originated from the same user
  • i.e., maintaining a user session
  • or, tracking your cyber-whereabouts and breaking your privacy?
  • i.e., a double-edged sword
  • Note the privacy law, e.g., EU Cookie Law (always ask for permission)
  • P.S. We are not talking about website fingerprinting here.

Making HTTP “Stateful” Using (HTTP/Web/Browser) Cookies

Session Creation and Resumption using Cookies

  • In the 1st visit, the browser makes a request to ss.com w/ no cookies
  • The server gives a Cookie value (w/ Set-Cookie response header)
  • i.e., the web server told the browser to create a cookie for that "origin"
  • (A cookie can also be created at the client-side, see later slides)
  • For subsequent visits, the browser automatically replays Cookies (w/ Cookie request header) to ss.com until the expiry date

Session Maintenance using Cookies

  • Cookie Values can store user preferences (e.g., theme=yellow)
  • Setting a unique, random, and unpredictable "token" (a.k.a. session ID)
  • The server can then isolate a user-specific session from other sessions
    i.e., a brunch of requests having the same unique session ID
  • Usage: Personalization, Authentication, and Session Storage

RFC 6265: HTTP State Management Mechanism

Cookies Communications

  • Cookies := a small (<4KB) client-side storage with its data replayed to where they were configured (cookie origin)

Problems of Using Cookies

  • Privacy from a user perspective
    • We know how a site can uniquely identify a user
    • What are the resulted threats?
  • Integrity and Authenticity
    • Cookies values reside on client-side
    • That said, malicious users can tamper with the values
  • Storage Size
    • A cookie has at most 4KB per domain
    • Recall the best practice: We want to keep the name/value size minimal to reduce bandwidth overhead

Fed up with Cookies? Other Client-side Session Storage

  • HTML5 LocalStorage (5MB/origin)
  • Unlike Cookies, does not replay in requests but accessible via JS API
  • Useful to store specific service's offline content offline, e.g., Gmail
  • As in Assignment Phase 3b, store the shopping list in localStorage
// Given that list is an object that stores your data (e.g. key-value tuples: (pids, qtys))
// Encode it to a string before storing it in localStorage
localStorage.setItem('list', JSON.stringify(list));
// When page starts, restore and decode to get the original object
var list = localStorage.getItem('list');
list = list && JSON.parse(list);
// Remove the object if needed
localStorage.removeItem('list');
  • Security: Follows the HTML5 SOP (next lecture) but not Cookie SOP
  • Security: Client-side storage is still subject to tampering attacks

Server-side Session Storage

  1. Using a file-based system (most traditional):
    • Read and De-serialize variables from file,
      e.g., "/tmp/sess_" + req.cookies.sessionid
    • Serialize and Write variables to file
      "/tmp/sess_" + req.cookies.sessionid
    • Problems: File I/O is slow, locking writes (of multi apps)
  2. Using a DB system:
    • 'SELECT data FROM sessions WHERE id = ?', [req.cookies.sessionid]
    • 'UPDATE sessions SET data = ? WHERE id = ?', [data, req.cookies.sessionid]
    • Problem: DB I/O handles writes atomically ("no free lunch")
  3. Using in-memory cache:
    • Works similarly as a DBMS but much faster, much more scalable
    • Example Node.js Packages: Express-session
      (with Redis serving multiple instances)

Why not both?

  • How about storing something both on the server and the client sides?
  • Worst of both worlds?
    • Client storage could be adversarially manipulated
    • Server still needs to maintain resource for each client
  • We need a cleverer way enjoy the best of both worlds
  • Authenticated encryption of client-side storage!
  • Server holds a short secret key for ALL clients, e.g., 256-bit for AES
  • Without the key, client cannot produce meaningful ciphertexts produced by authenticated encryption
  • Trades off computation against storage I/O overhead
  • It is risky to maintain access to a secret on an online server
  • e.g., this from npmjs.com (I did not look into the details)
  • (Midterm/Exam?) Cookies vs. localStorage vs. PHP Session Mgt.

PHP Session Management (1/2)

  • Variable/state sharing made easier (server???side solution)
  • With the built???in function session_start(), PHP restores the superglobal array $_SESSION based on the unique PHPSESSID token
<?php
// setting a variable at pageA.php
session_start();
$_SESSION['username'] = 'niki'; ?>
<?php
//accessing the variable at pageB.php
session_start();
echo $_SESSION['username']; ?>

PHP Session Management (2/2)

  • By default, the token is automatically generated and hosted as Cookies; or configurable to be hosted as a GET parameter (?PHPSESSID=x)
  • Upon page termination, session_write_close() is implicitly called to serialize $_SESSION and store it in a server-side temp. file
  • Expiration and Garbage Collection
    • By default, PHPSESSIDcode> expires when the browser terminates (i.e., header expires:0)
    • PHP will garbage collect (delete) the temp files at the server

Authentication & Authorization

Authentication vs. Authorization

  • Authentication: Is a user really whom he claims himself to be?
    • Authentication Factors:
      • something you know: password, private key
      • something you have: CULink, one-time hardware token
      • who you are: biometric features like fingerprints
      • what you do: the way you shake/tap smartphone
      • where you are: FB checks if country changed, IP, GPS
      • or a combination of n of them
        (the so-called n-factor authentication or nFA)
  • Authorization: Is an authenticated user allowed to do a task?
    • Most common: Role-based access control
    • e.g., is user A allowed to do task T1

Authentication using Forms and Cookies

Credentials Database

  • Create a DB table:
    • uid: primary key, auto increment
    • username: email address; UNIQUE
    • password: the hashed and salted password
    • authorization: e.g., 1 indicates admin, 0 indicates normal user
  • Security Best Practices for the password field:
    • NEVER store the password in plaintext
    • Using one-way hash to make them non-recoverable even if leaked
    • Even hashed, an attacker can pre-compute a list of hashed values
    • Salted password is to avoid such kind of brute-force attack
    • Salt: a random string for each password and hashed with the password
    • Store both the salt and the hash value together for recoverability
  • Hash based Message Authentication Code (HMAC)
    • hash_hmac() is a keyed function to calculate a MAC
 $storedPW = hash_hmac('sha1', $password, $salt);

Checking against the Credentials

<?php
session_start(); 
function ierg4210_login() {
  /* apply server-side validations here */
  global $db;
  $q = $db->prepare(
    'SELECT salt, password FROM users WHERE email = ?');
  if ($q->execute(array($_POST['em']))&&($r=$q->fetch())
      && $r['password']==hash_hmac('sha1',
            $_POST['password'], $r['salt'])){
    // When successfully authenticated,
    // 1. create authentication token
    // 2. redirect to admin.php
  } else {
    throw new Exception('auth-error');
  }
}   ?>
We talked about prepared statement before already!
NEVER try to concatentate a SQL statement by yourself! (Why?)

Creating Authentication Token

  • First principle: Token is random and unpredictable
  • Best practice: Token changes every time after login
    to mitigate session fixation attack
// if successfully authenticated
$exp = time() + 3600 * 24 * 3; // 3days
$token = array('em'=>$r['email'], 'exp'=>$exp,
  'k'=> hash_hmac('sha1', $exp . $r['password'], $r['salt']); 

// create the cookie
setcookie('auth', json_encode($token), $exp);
// put it also in $_SESSION
$_SESSION['auth'] = $token;
// change the PHPSESSID after login
session_regenerate_id();
return true;

Checking Authentication Token

function auth() {// returns email if valid, otherwise false
  if (!empty($_SESSION['auth'])) 
    return $_SESSION['auth']['em'];
  if (!empty($_COOKIE['auth'])) {
    if ($t = json_decode($_COOKIE['auth'], true)) {
      if (time() > $t['exp']) return false;
      global $db; // validate if token matches our record
      $q = $db->prepare(
        'SELECT salt, password FROM users WHERE email = ?');
      if ($q->execute(array($t['em']))
          && ($r = $q->fetch()) 
          && $t['k'] == hash_hmac('sha1', 
                $t['exp'] . $r['password'], $r['salt'])) {
        $_SESSION['auth'] = $_COOKIE['auth'];
        return $t['em'];  }
      return false; // or header('Location: login.php');exit();
    }   }  } 

Authentication Token and Authorization

  • Authenticate the token before admin operations
  • Authorization check before admin operations
    • Only upon a successful login
      • req.session.username and req.session.admin are set according to DB
    • For subsequent requests,
      • req.session.username accessible means logged-in user
      • req.session.admin accessible means a logged-in admin user

Best Practice on Session Isolation

  • We often separate auth cookies from other session cookies
    • connection sessionId (expires = 3 mths) and auth (expires: 180s)
  • Authentication Cookies
    • auth should be configured with tighter security
      • secure (i.e., https only)
      • httpOnly (i.e., no JS access)
      • path (restricted to a specific folder)
      • Expire more often
  • General Session Cookies
    • Associated with less critical data, possibly served over HTTP

HTTP (Basic) Authentication

  • The standardized and traditional way to authenticate a user
  • Not favorable by commercial websites since it's not customizable
  • Yet, a current trend is to just use this over HTTPs

HTTP (Digest) Authentication

  • nonce: number used once
  • MD5 became an insecure hash function
  • But the attack was finding collision, not breaking one-wayness

General Authentication Attacks

  • Brute-force/Dictionary
    • enumerating possible passwords
  • Eavesdropping and Session Hijacking
    • reading the password in plaintext protocol
    • replaying captured session token (or if it can be easily guessed)
  • Shoulder surfing
    • looking over shoulders when entering password
  • Phishing
    • providing a fake webpage to lure genuine password
  • Time-of-check to Time-of-use (TOCTTOU)
    • taking over by unauthorized person after authentication
  • Others...

Best Practices of Password Authentication

  • Enforce Proper Password Strength (incl. length, complexity)
  • Require Current Password for Password Changes
  • Implement Secure Password Recovery
  • Use Multi-factor Authentication
  • Prompt for Proper Authentication Error Messages
    • Good: Login failed. Invalid user ID or password
    • BAD: Login for User A: invalid password
  • Send Password only over Secure HTTPS Connections
  • Store Password in its One-way Hashed Format
  • Implement Account Lockout after Failed Attempts

Ref.: https://www.owasp.org/index.php/Authentication_Cheat_Sheet