Skip to main content
Cryptographic vulnerabilities expose data in transit, allow traffic interception, or enable attackers to forge authentication tokens. Most of these issues stem from missing security headers, use of deprecated algorithms, or secrets inadvertently included in client-side code.

crypto-mechanism-bypass

Critical

What it is

Cryptographic protection is negated because secrets, keys, or authentication logic are exposed in client-side JavaScript or HTML. An attacker who reads the page source can bypass the protection entirely.

Why it matters

Any secret placed in client-side code is effectively public. API keys, encryption keys, hardcoded passwords, or client-side password comparisons provide zero security — they’re visible to every user who opens DevTools.

How QAOS detects it

The agent scans all JavaScript loaded by the page for patterns indicating exposed secrets:
  • Hardcoded API keys (sk_live_, api_key =, apiKey:, secret =)
  • Client-side password comparisons (if (password === 'admin123'))
  • Encryption keys stored as JS constants
  • Hidden <input> elements with name="secret" or data-api-key attributes
  • Expected password hashes in JavaScript for local comparison

Examples

// Hardcoded API key
const stripe = require('stripe')('sk_live_ABC123...')

// Client-side password check
if (password === 'SuperSecretPassword2024') { allowAccess() }

// Encryption key in source
const encryptionKey = 'my-secret-key-12345'

How to fix

Never place secrets in client-side code. All authentication and cryptographic operations must happen server-side. Use environment variables loaded server-side only. For API keys that must be client-side (e.g., Stripe publishable keys), use restricted, scope-limited keys that cannot perform sensitive operations.

unencrypted-page-serving

Critical

What it is

The web page itself is served over plain HTTP instead of HTTPS, meaning all traffic between the user’s browser and the server is transmitted in the clear.

Why it matters

HTTP traffic can be intercepted, read, and modified by anyone on the network path — including ISPs, coffee shop Wi-Fi operators, and corporate network proxies. All credentials, session cookies, and sensitive data submitted over HTTP are exposed.

How QAOS detects it

The agent checks whether the current page URL starts with http:// instead of https://.

How to fix

  1. Obtain a TLS certificate (free via Let’s Encrypt)
  2. Configure your server to serve all content over HTTPS
  3. Redirect all HTTP traffic to HTTPS:
server {
  listen 80;
  return 301 https://$host$request_uri;
}
  1. Add HSTS to prevent future HTTP connections (see misconfigured-security-headers)

weak-crypto-key-generation

High

What it is

Client-side JavaScript uses Math.random() or other non-cryptographic functions to generate session tokens, keys, or security-sensitive identifiers. Alternatively, deprecated algorithms like DES, RC4, or MD5 are used for cryptographic purposes.

Why it matters

Math.random() is not cryptographically secure — its output can be predicted from a small number of observed values. Tokens generated with it can be brute-forced in seconds. Deprecated algorithms have known vulnerabilities that can be exploited with modest computing resources.

How QAOS detects it

The agent scans JavaScript source for:
  • Math.random() used to generate tokens or keys
  • CryptoJS.MD5() or CryptoJS.SHA1() for key derivation
  • RSA key generation with modulus < 2048 bits
  • Use of DES, RC4, or other deprecated cipher names

Examples

// Vulnerable: Math.random() for token generation
const sessionToken = Math.random().toString(36).substr(2)

// Vulnerable: MD5 for crypto purposes
const key = CryptoJS.MD5(password).toString()

// Vulnerable: short RSA key
const { privateKey } = crypto.generateKeyPairSync('rsa', { modulusLength: 512 })

How to fix

// Use the Web Crypto API for secure random generation
const array = new Uint8Array(32)
crypto.getRandomValues(array)
const token = Array.from(array).map(b => b.toString(16).padStart(2, '0')).join('')

// Node.js
const crypto = require('crypto')
const token = crypto.randomBytes(32).toString('hex')

// RSA: use 2048 bits minimum (4096 recommended)
const { privateKey } = crypto.generateKeyPairSync('rsa', { modulusLength: 4096 })

unencrypted-sensitive-communication

High

What it is

Forms or JavaScript fetch/XHR calls submit sensitive data (passwords, credit card numbers, personal information) to http:// endpoints instead of https://.

Why it matters

Even if the page itself is served over HTTPS, if form submissions or API calls go to HTTP endpoints, the sensitive data is transmitted in the clear. This is particularly dangerous for login forms and payment flows.

How QAOS detects it

The agent scans JavaScript source and form action attributes for http:// URLs that receive sensitive data (forms containing password fields, credit card inputs, or personal data fields).

Examples

<!-- Form submitting credentials over HTTP -->
<form action="http://api.example.com/login" method="POST">
  <input type="password" name="password">
</form>
// Fetch sending data over HTTP
fetch('http://api.example.com/login', {
  method: 'POST',
  body: JSON.stringify({ password: userPassword })
})

How to fix

Ensure all form action attributes and API call URLs use https://. Configure your server to reject HTTP requests for sensitive endpoints.

misconfigured-security-headers

High

What it is

HTTP response headers that protect against common browser-side attacks are missing or misconfigured. These include HSTS, Content-Security-Policy, X-Frame-Options, and X-Content-Type-Options.

Why it matters

Security headers are the browser’s last line of defense. Missing headers leave users vulnerable to downgrade attacks, clickjacking, MIME-type sniffing, and XSS escalation — even if the application code itself is secure.

How QAOS detects it

The agent checks HTTP response headers for the presence and correctness of key security headers.

Commonly missing headers

HeaderRisk if missing
Strict-Transport-SecurityHTTP downgrade attacks
Content-Security-PolicyXSS escalation
X-Frame-OptionsClickjacking
X-Content-Type-OptionsMIME sniffing
Referrer-PolicyURL leakage

How to fix

Add these headers to your server’s response:
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'; script-src 'self'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Most frameworks support middleware for this:
// Express.js with Helmet
const helmet = require('helmet')
app.use(helmet())

weak-hashing-no-salt

High

What it is

Passwords or other sensitive values are hashed using weak algorithms (MD5, SHA-1) or without a unique random salt, making them vulnerable to rainbow table and dictionary attacks.

Why it matters

Unsalted MD5 or SHA-1 hashes of common passwords exist in precomputed lookup tables. An attacker who obtains your password database can instantly reverse millions of passwords.

How QAOS detects it

The agent scans JavaScript source for hashing calls using weak algorithms: CryptoJS.MD5(password), CryptoJS.SHA1(data), single-round SHA-256 without iterations, or hashing without a random salt.

How to fix

Use a proper key derivation function (KDF) designed for password hashing:
# Python: bcrypt
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))

# Python: Argon2
from argon2 import PasswordHasher
ph = PasswordHasher()
hashed = ph.hash(password)
// Node.js: bcrypt
const bcrypt = require('bcrypt')
const hashed = await bcrypt.hash(password, 12)
Never use MD5, SHA-1, or raw SHA-256 for password storage.

misconfigured-cors

High

What it is

The server returns Access-Control-Allow-Origin: * (or reflects any origin) on endpoints that return sensitive data, allowing any website to make authenticated cross-origin requests and read the response.

Why it matters

A wildcard CORS policy combined with Access-Control-Allow-Credentials: true allows any malicious website to make requests to your API on behalf of your logged-in users and read the response. This effectively bypasses the Same-Origin Policy.

How QAOS detects it

The agent checks HTTP response headers for Access-Control-Allow-Origin: * or reflected origin values on sensitive API endpoints.

Examples

# Vulnerable: wildcard CORS on authenticated API
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

How to fix

Maintain an explicit allow-list of trusted origins and validate against it:
# FastAPI CORS middleware
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://app.example.com"],  # explicit list, never "*"
    allow_credentials=True,
    allow_methods=["GET", "POST"],
)