Overview

Secure Sessions

Demonstrates robust state management and defense-in-depth strategies for web applications. This example showcases the use of 'Nonces' for session token generation and mandatory CSRF protection, illustrating how to manage secure cookies with HttpOnly and Strict flags to prevent unauthorized access and cross-site attacks.

Source Code

<?pas
uses System.Net, System.Crypto;

// Session Demo - Secure Implementation
// Demonstrates secure sessions using Nonces and CSRF protection.

var user := WebRequest.ContentField['user'];
var pass := WebRequest.ContentField['password'];
var csrfToken := WebRequest.ContentField['csrf_token'];
var action := WebRequest.QueryField['action'];

var cookieName := 'DemoSession';
var sessionToken := WebRequest.Cookie[cookieName];

// 1. Session Validation
// Use Nonces.GetData to retrieve the user associated with the token.
// If the token is invalid or expired, this returns an empty string.
var loggedInUser := '';
if sessionToken <> '' then begin
   loggedInUser := Nonces.GetData(sessionToken);
end;

// Handle Logout
if action = 'logout' then begin
   if sessionToken <> '' then begin
      Nonces.Remove(sessionToken); // Invalidate server-side
      WebResponse.SetCookie(cookieName, '', Now - 1, '/', '', Integer(WebCookieFlag.HttpOnly), WebCookieSameSite.Strict);
   end;
   loggedInUser := '';
   PrintLn('<div class="alert alert-info">Logged out successfully.</div>');
end;

// Handle Login
if (user <> '') and (pass <> '') then begin
   // Validate CSRF Token (One-time use)
   if not Nonces.CheckAndRemove(csrfToken, 'csrf-login') then begin
      PrintLn('<div class="alert alert-danger">Security violation: Invalid or expired CSRF token.</div>');
   end else if (user = 'admin') and (pass = 'password') then begin
      // Generate secure session token (1 hour expiration)
      // We store the username directly in the nonce data
      var newToken := Nonces.Generate(3600 * 1000, user);
      
      // Set secure cookie
      WebResponse.SetCookie(cookieName, newToken, Now + (1/24), '/', '', Integer(WebCookieFlag.HttpOnly), WebCookieSameSite.Strict);
      
      loggedInUser := user;
      PrintLn('<div class="alert alert-success">Login successful!</div>');
   end else begin
      PrintLn('<div class="alert alert-danger">Invalid credentials.</div>');
   end;
end;

// Generate new CSRF token for the form (valid for 10 minutes)
var newCsrf := Nonces.Generate(600 * 1000, 'csrf-login');

PrintLn('<h3>Session State</h3>');
if loggedInUser <> '' then begin
   PrintLn('<p>Welcome back, <strong>' + StrToHtml(loggedInUser) + '</strong>!</p>');
   PrintLn('<p class="text-muted small">Session Token: ' + sessionToken + '</p>');
   PrintLn('<a href="?action=logout" class="btn btn-warning">Logout</a>');
end else begin
   PrintLn('<p>You are not logged in.</p>');
   PrintLn('<form method="POST" class="border p-3 rounded" style="max-width: 300px;">');
   // CSRF Protection
   PrintLn('  <input type="hidden" name="csrf_token" value="' + newCsrf + '">');
   
   PrintLn('  <div class="mb-3">');
   PrintLn('    <label>Username</label>');
   PrintLn('    <input type="text" name="user" class="form-control" value="admin">');
   PrintLn('  </div>');
   PrintLn('  <div class="mb-3">');
   PrintLn('    <label>Password</label>');
   PrintLn('    <input type="password" name="password" class="form-control" value="password">');
   PrintLn('  </div>');
   PrintLn('  <button type="submit" class="btn btn-primary">Login</button>');
   PrintLn('</form>');
end;
?>

Result

<h3>Session State</h3>
<p>You are not logged in.</p>
<form method="POST" class="border p-3 rounded" style="max-width: 300px;">
  <input type="hidden" name="csrf_token" value="x_v07jU_Vg9wYH7kPk4F">
  <div class="mb-3">
    <label>Username</label>
    <input type="text" name="user" class="form-control" value="admin">
  </div>
  <div class="mb-3">
    <label>Password</label>
    <input type="password" name="password" class="form-control" value="password">
  </div>
  <button type="submit" class="btn btn-primary">Login</button>
</form>
On this page