Get a Pentest and security assessment of your IT network.

Cyber Security

Protecting URL Query Strings Without HTTPS

TL;DR

While HTTPS is the best way to protect query strings (and everything else) in a URL, you can take steps to make sniffing them more difficult. These aren’t foolproof – they add layers of obscurity, not security. The main techniques are encryption client-side before sending and obfuscation.

Protecting Query Strings Without HTTPS

  1. Understand the Risk
    • Without HTTPS, data in a URL is sent in plain text. Anyone monitoring the network can see it. This includes query strings which often contain sensitive information like IDs or tokens.
    • Sniffing tools (like Wireshark) easily capture this data.
  2. Client-Side Encryption
  3. Encrypt the query string in the browser before sending it in the URL. Decrypt it after receiving it on the server.

    • JavaScript Libraries: Use a JavaScript encryption library like CryptoJS or Stanford Javascript Crypto Library (SJCL).
    • Example using CryptoJS:
    • // Encryption in browser
      const queryString = 'sensitive_data=value&another=other';
      const encrypted = CryptoJS.AES.encrypt(queryString, 'secretKey').toString();
      const url = '/your-endpoint?' + encodedURIComponent(encrypted);
      
      // Decryption on server (Node.js example)
      const decryptedBytes  = CryptoJS.AES.decrypt(req.query.encrypted, 'secretKey');
      const originalText = decryptedBytes.toString(CryptoJS.enc.Utf8);
    • Important: Keep the encryption key secret! Do not embed it directly in your JavaScript code where it can be easily extracted. Consider fetching it from a secure source (though this introduces other complexities).
  4. Obfuscation (Not Encryption)
  5. Make the query string harder to read, but not truly secret. This is less effective than encryption.

    • Base64 Encoding: Encode the query string using Base64. It’s reversible and doesn’t provide security, just obscurity.
      // JavaScript
      const queryString = 'sensitive_data=value&another=other';
      const encodedString = btoa(queryString);
      const url = '/your-endpoint?' + encodedString;
      
      // Server-side (Node.js)
      const decodedString = atob(req.query.encodedString);
    • Simple Substitution: Replace characters with others. Again, easily reversible.
      // JavaScript - Example substitution
      function obfuscate(str) {
        let result = '';
        for (let i = 0; i < str.length; i++) {
          result += String.fromCharCode(str.charCodeAt(i) + 5);
        }
        return result;
      }
      const queryString = 'sensitive_data=value';
      const obfuscatedString = obfuscate(queryString);
      
  6. Short-Lived Tokens
  7. If the query string contains a token, make it expire quickly. This limits the window of opportunity for an attacker.

    • Implement a system to invalidate tokens after a short period (e.g., 5 minutes).
    • Generate new tokens frequently.
  8. Consider POST Requests
  9. If possible, send the data in the body of a POST request instead of as query string parameters. This doesn’t prevent sniffing entirely but makes it slightly harder to extract information directly from URLs.

  10. Important Disclaimer
    • These methods are not substitutes for HTTPS. They provide only limited protection and can be bypassed relatively easily.
    • Always prioritize using HTTPS whenever possible. It encrypts the entire communication channel, providing a much stronger level of security.
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