Get a Pentest and security assessment of your IT network.

Cyber Security

Secure Query String Authentication

TL;DR

Passing authentication details in a query string is insecure. This guide shows how to move authentication to cookies or headers and protect against common attacks.

Why Query String Auth is Bad

Putting usernames, passwords, or tokens directly into the URL (the query string) has several problems:

  • History: URLs are often stored in browser history, server logs, and proxy logs.
  • Referrer Headers: The URL might be sent to other websites via referrer headers if a user clicks a link on your page.
  • Bookmarking: Users could bookmark the URL with sensitive information.
  • Easy Manipulation: Query strings are easily modified by users or attackers.

How to Fix It

The best approach is to avoid using query string authentication altogether. Here’s how to move authentication data securely:

1. Use Cookies (Recommended)

  1. Authentication Process: When a user logs in, verify their credentials on the server-side.
  2. Create a Session ID: Generate a unique session identifier (e.g., using a random string). Store this ID securely on the server and associate it with the user’s account.
  3. Set a Secure Cookie: Send a cookie to the browser containing the session ID. Crucially, set the following attributes:
    • HttpOnly: Prevents JavaScript from accessing the cookie (protects against XSS attacks).
    • Secure: Only sends the cookie over HTTPS connections.
    • SameSite=Strict or SameSite=Lax: Helps prevent CSRF attacks. `Strict` is more secure but may break some legitimate cross-site functionality; `Lax` offers a good balance.
  4. Subsequent Requests: On subsequent requests, the browser automatically sends the cookie to your server. Your server uses the session ID in the cookie to identify the user.

Example (Python/Flask):

from flask import Flask, request, make_response, redirect, url_for
import secrets

session_data = {}

app = Flask(__name__)
app.secret_key = secrets.token_hex(16) # Important: Use a strong secret key!

@app.route('/login', methods=['POST'])
def login():
    # ... (verify username and password here)
    session_id = secrets.token_hex(16)
    session_data[session_id] = 'user123' # Store user info associated with the session ID
    resp = make_response(redirect(url_for('home')))
    resp.set_cookie('session_id', session_id, httponly=True, secure=True, samesite='Strict')
    return resp

@app.route('/home')
def home():
    session_id = request.cookies.get('session_id')
    if session_id in session_data:
        user_info = session_data[session_id]
        return f'Welcome, {user_info}!'
    else:
        return redirect(url_for('login'))

2. Use Headers

  1. Authentication Process: Similar to cookies – verify credentials on the server-side and create a token (e.g., JWT).
  2. Send Token in Header: Instead of setting a cookie, send the token in an HTTP header (e.g., Authorization: Bearer <token>).
  3. Subsequent Requests: The client application includes the header with each request.

Example (JavaScript/Fetch):

async function fetchData(token) {
  const response = await fetch('/api/data', {
    headers: {
      'Authorization': 'Bearer ' + token
    }
  });
  // ... handle the response
}

3. Redirect After Authentication

If you absolutely *must* use a query string temporarily (e.g., for Single Sign-On redirects), redirect the user to another page immediately after authentication, removing the sensitive information from the URL.

Important Security Considerations

  • HTTPS: Always use HTTPS to encrypt all communication between the client and server.
  • Input Validation: Validate all input on the server-side to prevent injection attacks.
  • CSRF Protection: Implement CSRF protection mechanisms (e.g., using tokens) if you are using cookies.
  • XSS Prevention: Protect against XSS attacks by properly escaping output and using HttpOnly cookies.
Related posts
Cyber Security

Zip Codes & PII: Are They Personal Data?

Cyber Security

Zero-Day Vulnerabilities: User Defence Guide

Cyber Security

Zero Knowledge Voting with Trusted Server

Cyber Security

ZeroNet: 51% Attack Risks & Mitigation