Blog | G5 Cyber Security

Secure Authentication with Untrusted Servers

TL;DR

When connecting to a server you don’t fully trust, avoid sending passwords directly. Use secure authentication methods like OAuth 2.0 or OpenID Connect, and always verify the server’s certificate. If those aren’t possible, implement strong client-side encryption before transmission.

Understanding the Risk

An untrusted server means you can’t be certain how it handles your data. It could log passwords, intercept communications (man-in-the-middle attacks), or otherwise compromise your security. Directly sending credentials is a major risk.

Solution Steps

  1. Prioritize OAuth 2.0 or OpenID Connect: These are the best options if available.
    • They allow users to authenticate with a trusted provider (like Google, Facebook, or your own identity server) without sharing their password directly with the untrusted server.
    • The untrusted server receives an access token instead of credentials.
    • Implementation: Use well-vetted OAuth 2.0/OpenID Connect libraries for your programming language. Configuration is key – ensure correct redirect URIs and scopes are set up.
  2. Verify Server Certificates (HTTPS): Always use HTTPS.
    • Ensure the server’s SSL/TLS certificate is valid and issued by a trusted Certificate Authority (CA).
    • Your programming language or web framework should handle this automatically, but double-check your configuration. Look for warnings about invalid certificates.
    • Example (Python with Requests):
      import requests
      
      response = requests.get('https://example.com', verify=True) #verify=False is VERY BAD
  3. Client-Side Encryption (If OAuth/OpenID Connect are not possible): If you absolutely must send some form of credential, encrypt it before transmission.
    • Generate a unique key pair: The private key stays on the client (user’s device), and the public key is sent to the server.
    • Encrypt the password with the private key: Use a strong encryption algorithm like RSA or ECC.
    • Send the encrypted password to the server.
    • Server decrypts with the public key: The server uses the received public key to decrypt the password.
    • Important Considerations:
      • Key management is critical. Protect the private key on the client.
      • Use a robust encryption library.
      • Consider using Perfect Forward Secrecy (PFS) for added security.
  4. Implement Two-Factor Authentication (2FA): Add an extra layer of security.
    • Even if the password is compromised, 2FA makes it much harder for attackers to gain access.
    • Use time-based one-time passwords (TOTP) or SMS codes.
  5. Rate Limiting: Protect against brute-force attacks.
    • Limit the number of login attempts from a single IP address within a given timeframe.
    • Implement account lockout after multiple failed attempts.
  6. Regular Security Audits: Regularly review your authentication process for vulnerabilities.
    • Penetration testing can help identify weaknesses.
    • Keep your libraries and frameworks up to date with the latest security patches.

What NOT To Do

Exit mobile version