DALT.PHP

Broken Middleware

Fix authentication and CSRF validation issues

Challenge: Broken Middleware

Difficulty: Medium
Bugs: 2
Time: 60 minutes

The Problem

The middleware system has two critical bugs affecting security.

Symptoms:

  • Auth middleware checks wrong session key
  • CSRF validation logic is inverted (accepts invalid tokens!)

Setup

Backup Current Files

cp framework/Core/Middleware/Auth.php framework/Core/Middleware/Auth.php.backup
cp framework/Core/Middleware/Csrf.php framework/Core/Middleware/Csrf.php.backup

Copy Broken Files

cp challenges/broken-middleware/framework/Core/Middleware/Auth.php framework/Core/Middleware/
cp challenges/broken-middleware/framework/Core/Middleware/Csrf.php framework/Core/Middleware/
cp -r challenges/broken-middleware/Http/controllers/dashboard Http/controllers/

Add Routes

cat challenges/broken-middleware/routes/routes.php >> routes/routes.php

Test the Bugs

  1. Try accessing /dashboard without logging in (should redirect, but doesn't!)
  2. Submit a form without CSRF token (should fail, but succeeds!)

Bug #1: Auth Middleware Checks Wrong Session Key

The Symptom

Users can access protected routes without logging in.

What's Happening

// BROKEN - Checks wrong key
class Auth {
    public function handle() {
        if (!isset($_SESSION['authenticated'])) {
            redirect('/login');
        }
    }
}

The middleware checks for $_SESSION['authenticated'], but the login system stores $_SESSION['user'].

Why It's Broken

When a user logs in:

$_SESSION['user'] = ['email' => 'user@example.com'];

But Auth middleware checks:

if (!isset($_SESSION['authenticated'])) // Never set!

So the check always fails, allowing unauthenticated access.

The Fix

Check the correct session key:

// ✅ CORRECT
class Auth {
    public function handle() {
        if (!isset($_SESSION['user'])) {
            redirect('/login');
        }
    }
}

Lesson: Always check the same session key that your login system uses!

Bug #2: CSRF Validation Logic is Inverted

The Symptom

Forms work without CSRF tokens, but fail with valid tokens!

What's Happening

// BROKEN - Logic is backwards
class Csrf {
    public function handle() {
        $token = $_POST['_token'] ?? '';
        $sessionToken = $_SESSION['_token'] ?? '';
        
        if ($token !== $sessionToken) {
            return; // Valid token, allow
        }
        
        abort(403); // Invalid token, block
    }
}

The logic is inverted:

  • If tokens DON'T match → Allow (should block!)
  • If tokens DO match → Block (should allow!)

Why It's Broken

This creates a serious security vulnerability:

  • Attackers can submit forms without tokens
  • Legitimate users with valid tokens get blocked

The Fix

Fix the logic and use timing-safe comparison:

// ✅ CORRECT
class Csrf {
    public function handle() {
        $token = $_POST['_token'] ?? '';
        $sessionToken = $_SESSION['_token'] ?? '';
        
        if (hash_equals($sessionToken, $token)) {
            return; // Valid token, allow
        }
        
        abort(403); // Invalid token, block
    }
}

Security: Always use hash_equals() for token comparison to prevent timing attacks!

Verification

After fixing both bugs, run verification:

php artisan verify broken-middleware

Expected output:

╔══════════════════════════════════════════════════════════════╗
║           DALT Challenge Verification System                ║
╚══════════════════════════════════════════════════════════════╝

Verifying: broken-middleware
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✓ Auth middleware checks correct session key
✓ CSRF middleware uses hash_equals
✓ CSRF logic is correct
✓ No problematic code found

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Results: 4/4 tests passed
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✅ All tests passed! Challenge complete!

Success Criteria

When fixed correctly:

  • ✅ Unauthenticated users are redirected to login
  • ✅ Authenticated users can access protected routes
  • ✅ Forms without CSRF tokens are rejected
  • ✅ Forms with valid CSRF tokens are accepted

Learning Objectives

After completing this challenge, you understand:

  • ✅ How middleware filters requests
  • ✅ Why session key consistency matters
  • ✅ How CSRF protection works
  • ✅ Why timing-safe comparison is important
  • ✅ Common middleware security bugs

Debugging Tips

Check Session Keys

// In Auth middleware
dd($_SESSION);

Test CSRF Logic

// In Csrf middleware
dd([
    'post_token' => $_POST['_token'] ?? 'none',
    'session_token' => $_SESSION['_token'] ?? 'none',
    'match' => hash_equals($_SESSION['_token'] ?? '', $_POST['_token'] ?? '')
]);

Files to Investigate

  • framework/Core/Middleware/Auth.php - Auth check (bug here!)
  • framework/Core/Middleware/Csrf.php - CSRF validation (bug here!)
  • Http/controllers/auth/login-post.php - See what session key is set
  • framework/Core/Authenticator.php - See login implementation

Cleanup

After completing the challenge:

# Restore original middleware
cp framework/Core/Middleware/Auth.php.backup framework/Core/Middleware/Auth.php
cp framework/Core/Middleware/Csrf.php.backup framework/Core/Middleware/Csrf.php

# Remove challenge controllers (optional)
rm -rf Http/controllers/dashboard

Next Challenge

Continue to Lesson 4: Authentication or try Challenge: Broken Auth.

On this page