3 minute read Security

Welcome to part two of this OWASP Top 10:2021 series, where I break down each of the top security risks, in a way that makes sense to everyday engineers. In this post, we’re looking at Cryptographic Failures—which sounds complex, but often boils down to not using encryption where it’s needed, or using it incorrectly.

What is a Cryptographic Failure?

A cryptographic failure isn’t just about algorithms or math. It’s a broader term that covers any situation where sensitive data isn’t properly protected in transit or at rest.

Common examples:

  • Not using HTTPS to encrypt data over the network.
  • Storing passwords in plain text.
  • Using weak or outdated encryption algorithms (like MD5 or SHA-1).
  • Hardcoding cryptographic keys in source code or exposing them in config files.

Why Does This Happen?

A few root causes we often see in the wild:

  • Lack of awareness about what data should be encrypted.
  • Developers rolling their own crypto instead of using proven libraries.
  • Legacy codebases still using insecure defaults.
  • Misconfigured TLS, leaving communication channels open to interception.
  • Improper key management, including reusing or exposing keys.

It’s not just about using encryption—it’s about using it correctly and consistently.

How an Attacker Might Exploit It

When crypto fails, attackers can:

  • Intercept sensitive data in transit (like passwords or session tokens) over unencrypted channels.
  • Access unencrypted files or databases if they gain access to your systems.
  • Crack weakly hashed passwords using dictionary or brute-force attacks.
  • Exploit predictable or reused encryption keys to decrypt sensitive information.
  • Bypass weak TLS configurations (e.g., forcing a downgrade attack to use insecure ciphers).

What Engineers Can Do

Here’s how to keep your data safe, even when attackers are watching:

  1. Use HTTPS Everywhere
    • All data in transit should be encrypted using HTTPS, even for internal services.
    • Redirect HTTP to HTTPS automatically, and enforce HSTS headers.
  2. Never Store Sensitive Data in Plaintext
    • Encrypt sensitive fields like SSNs, credit card numbers, and private user data at rest.
    • Use proven, vetted encryption libraries (like libsodium, OpenSSL, BouncyCastle).
  3. Hash Passwords Properly
    • Use a slow, adaptive hashing function like bcrypt, scrypt, or Argon2.
    • Never use plain SHA-256 or MD5 for passwords—they’re too fast and easy to crack.
  4. Don’t Roll Your Own Crypto
    • Resist the temptation to write your own encryption routines. Even experienced devs get this wrong.
    • Lean on platform standards or libraries with strong community and academic vetting.
  5. Handle Keys with Care
    • Don’t hardcode keys in your source code or upload them to version control.
    • Use a key management solution (like AWS KMS, HashiCorp Vault, or Azure Key Vault).
  6. Regularly Review and Update Configurations
    • Audit your TLS settings (disable insecure protocols like TLS 1.0 and weak ciphers).
    • Monitor dependencies for vulnerabilities in crypto libraries.

Real-World Example: The “Oops, We Logged the Password” Incident

Picture this: a new user signs up, and their password is accidentally logged in plaintext due to verbose error logging. Now it’s sitting in logs—maybe even shipped off to a centralised log system where multiple teams have access.

Even if you’re using proper hashing elsewhere, that one log statement has become a data breach waiting to happen.

Or worse—developers skip hashing entirely during testing, forget to fix it, and ship to prod with plain text passwords in the DB. It happens more than you think.

Final Thoughts

Cryptographic failures are often silent. Your app keeps running, users don’t notice, and everything seems fine—until your customer data is exposed and you’re issuing breach notifications.

Good encryption isn’t just a checkbox. It’s a mindset. Secure by default. Avoid the shortcuts. And always assume that if data can be intercepted or leaked—it eventually will be.

Next in the series: A03: Injection Attacks → We’ll explore the infamous family of injection flaws—from SQL injection to command injection—and how to keep untrusted input from owning your application.

Leave a comment