HIGH CWE-261 Authentication & Cryptography

CWE-261 in APIs

CWE ID
CWE-261
Category
Encryption
Severity
HIGH
Short Name
Weak Password Encoding

What is CWE-261?

CWE-261 refers to Weak Cryptography for Passwords — a weakness where passwords or other credentials are stored, transmitted, or processed using weak cryptographic algorithms or insufficient protection mechanisms. This can include using outdated hashing algorithms like MD5 or SHA-1, storing passwords in plaintext, or using weak encryption keys that can be easily broken.

The weakness manifests when developers prioritize simplicity or legacy compatibility over security best practices. Common scenarios include:

  • Using MD5 or SHA-1 for password hashing (vulnerable to rainbow table attacks)
  • Storing passwords in plaintext in configuration files or databases
  • Using unsalted hashes that allow pre-computed attacks
  • Implementing custom "encryption" schemes instead of proven cryptographic libraries
  • Using weak keys or insufficient key lengths

The impact can be severe: credential theft, account takeover, and potential lateral movement through systems if users reuse passwords across services.

CWE-261 in API Contexts

APIs introduce unique CWE-261 vulnerabilities due to their distributed nature and authentication requirements. Common API-specific manifestations include:

  • Token Storage: JWT tokens or API keys stored in client-side storage (localStorage, cookies without proper flags) where they can be stolen via XSS attacks
  • Basic Auth Headers: Transmitting credentials via Authorization headers without TLS, exposing Base64-encoded credentials
  • Configuration Exposure: API configuration files containing database credentials or service keys committed to repositories
  • Weak Token Algorithms: Using HS256 JWT with weak secrets instead of RS256 with asymmetric keys
  • Credential Transmission: Accepting credentials via GET parameters in URLs (logged in server logs, browser history)

Real-world example: In 2020, a major API service was compromised when developers used MD5 for password hashing. Attackers pre-computed rainbow tables for common passwords and gained access to thousands of accounts within hours of the breach.

APIs also face credential stuffing attacks where weak or reused passwords from data breaches allow automated login attempts. Without proper rate limiting and monitoring, these attacks can go undetected for months.

Detection

Detecting CWE-261 requires both static analysis and runtime scanning. Here's how to identify weak cryptography in your APIs:

  • Code Review: Look for cryptographic imports and algorithms. Search for MD5, SHA-1, DES, RC4, or custom "encryption" functions. Check for hardcoded secrets or weak key generation.
  • Configuration Analysis: Examine configuration files for plaintext credentials, weak JWT secrets, or exposed database connection strings.
  • Network Traffic Analysis: Use tools like Wireshark or mitmproxy to verify TLS is properly configured and no credentials are transmitted in plaintext.
  • Automated Scanning: Tools like middleBrick can detect CWE-261 by scanning your API endpoints for weak authentication mechanisms, exposed credentials in responses, and insecure configuration patterns.

middleBrick's Approach: The scanner tests your API's authentication endpoints for weak cryptography by attempting to intercept credentials, checking for exposed secrets in API responses, and analyzing authentication flows. It specifically looks for:

  • Credentials transmitted without proper encryption
  • Weak JWT implementations or exposed secrets
  • Exposed configuration files containing credentials
  • Insecure authentication mechanisms

middleBrick's LLM security module also checks for AI-specific credential exposure, such as system prompts containing API keys or credentials that could be extracted through prompt injection attacks.

Remediation

Fixing CWE-261 requires implementing industry-standard cryptographic practices. Here are code-level solutions:

1. Password Hashing

// Weak - DO NOT USE
const weakHash = crypto.createHash('md5').update(password).digest('hex');

// Strong - RECOMMENDED
const bcrypt = require('bcrypt');
const saltRounds = 12;
const hashedPassword = await bcrypt.hash(password, saltRounds);

// Verification
const isValid = await bcrypt.compare(providedPassword, storedHash);

2. JWT Implementation

// Weak - DO NOT USE
const token = jwt.sign({ userId }, 'supersecretkey', { algorithm: 'HS256' });

// Strong - RECOMMENDED
const privateKey = fs.readFileSync('private.key');
const token = jwt.sign({ userId }, privateKey, { algorithm: 'RS256', expiresIn: '1h' });

// Verification with public key
const publicKey = fs.readFileSync('public.key');
jwt.verify(token, publicKey, { algorithms: ['RS256'] });

3. API Key Management

// Weak - DO NOT USE
const apiKey = process.env.API_KEY || 'default-key'; // Default fallback

// Strong - RECOMMENDED
if (!process.env.API_KEY) {
  throw new Error('API_KEY environment variable is required');
}

// Use AWS KMS, Azure Key Vault, or HashiCorp Vault for key management
const encryptedKey = await kms.decrypt({ CiphertextBlob: process.env.ENCRYPTED_API_KEY });

4. TLS Configuration

// Weak - DO NOT USE
const server = https.createServer({
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem'),
  secureOptions: crypto.constants.SSL_OP_NO_SSLv2 | crypto.constants.SSL_OP_NO_SSLv3
});

// Strong - RECOMMENDED
const server = https.createServer({
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem'),
  secureOptions: crypto.constants.SSL_OP_NO_SSLv2 | 
                 crypto.constants.SSL_OP_NO_SSLv3 | 
                 crypto.constants.SSL_OP_NO_TLSv1 | 
                 crypto.constants.SSL_OP_NO_TLSv1_1,
  honorCipherOrder: true,
  ciphers: 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384'
});

Best Practices Summary:

  • Always use bcrypt, scrypt, or Argon2 for password hashing with appropriate work factors
  • Implement proper key rotation policies for JWT secrets and API keys
  • Use environment variables or secret management services for credentials
  • Enable HSTS and enforce HTTPS for all API communications
  • Implement proper logging without exposing sensitive credentials
  • Regularly audit your cryptographic implementations against current best practices

For teams using middleBrick, the scanner can verify your remediation efforts by re-scanning your API endpoints and providing updated security scores, ensuring your cryptographic implementations meet modern security standards.

Frequently Asked Questions

How can I tell if my API is vulnerable to CWE-261?
Look for signs like plaintext passwords in configuration files, use of MD5/SHA-1 for hashing, exposed credentials in API responses, or weak JWT implementations. middleBrick can automatically scan your API endpoints and identify these vulnerabilities in seconds without requiring credentials or access to your source code.
What's the difference between encryption and hashing for passwords?
Hashing is one-way and should be used for passwords (bcrypt, scrypt, Argon2). Encryption is two-way and should only be used when you need to retrieve the original data. Never encrypt passwords — if your encryption key is compromised, all passwords are exposed. Hashing with salt prevents rainbow table attacks and ensures one-way protection.