no-unencrypted-transmission
Detects unencrypted data transmission (HTTP vs HTTPS, plain text protocols)
CWE: CWE-693
OWASP Mobile: OWASP Mobile Top 10
Detects unencrypted data transmission (HTTP vs HTTPS, plain text protocols). This rule is part of eslint-plugin-browser-security and provides LLM-optimized error messages that AI assistants can automatically fix.
💼 This rule is set to error by default in the recommended config.
Quick Summary
| Aspect | Details |
|---|---|
| CWE Reference | CWE-319 (Cleartext Transmission of Sensitive Information) |
| Severity | HIGH (security vulnerability) |
| Auto-Fix | 💡 Suggestion (rewrites the scheme to its TLS twin, string literals only) |
| Category | Security |
| ESLint MCP | ✅ Optimized for ESLint MCP integration |
| Best For | All applications making network requests, APIs, database connections |
Vulnerability and Risk
Vulnerability: Transmission of sensitive data over unencrypted protocols (HTTP) allows unauthorized parties to intercept or modify the data in transit.
Risk: Man-in-the-Middle (MitM) attacks can capture sensitive information like authentication tokens, passwords, or personal data. Attackers can also inject malicious content into the response.
Detection Flow
Why This Matters
| Issue | Impact | Solution |
|---|---|---|
| 🔒 Man-in-Middle | Data intercepted in transit | Use HTTPS/TLS |
| 🔐 Data Breach | Sensitive data exposed | Encrypt all transmissions |
| 🍪 Compliance | Violates security standards | Enforce encrypted protocols |
| 📊 Best Practice | All external connections need TLS | Use secure protocols |
Detection Patterns
By default the rule detects the cleartext non-web protocols, in a string literal or in the static text of a template literal:
- FTP:
ftp://(should useftps:///sftp://) - TCP:
tcp:// - MongoDB:
mongodb://(should usemongodb+srv://or TLS) - Redis:
redis://(should userediss://) - MySQL:
mysql://(should use SSL)
http:// and ws:// are not in the defaults. They are owned by the transport partition, so each line draws one finding:
| Shape | Owner |
|---|---|
URL argument of fetch / axios.<verb> | require-https-only |
http:// in a subresource position | detect-mixed-content |
any other hardcoded http:// URL | no-http-urls |
URL argument of new WebSocket(…) | require-websocket-wss |
any other ws:// URL | no-insecure-websocket |
Add them back with insecureProtocols if you run this rule without those siblings.
A loopback host on a web scheme, an RFC 2606 reserved domain, an XML namespace URI and a string being tested for its scheme are never reported. On the non-web schemes loopback is not exempt by default — a mongodb://user:pass@localhost string carries credentials that survive a host swap.
allowInTests exempts, in test files only, URLs whose written-down host is loopback (redis://localhost:6379, `mongodb://127.0.0.1/${db}`) on any scheme, and templates whose host is left to an interpolation. A real host in a test file still reports.
Examples
❌ Incorrect
// Unencrypted transmission
const mongoUrl = 'mongodb://localhost:27017/db'; // ❌ MongoDB without encryption
const mongoProd = `mongodb://db.internal:27017/${name}`; // ❌ template, fixed scheme
const redisUrl = 'redis://localhost:6379'; // ❌ Redis without TLS
const mysqlUrl = 'mysql://user:pass@localhost/db'; // ❌ MySQL without SSL✅ Correct
const mongoUrl = 'mongodb+srv://cluster0.example.com/app';
const redisUrl = 'rediss://cache.example.com:6380';
// http:// and ws:// are reported by their owning rules, not this one
fetch('http://api.example.com/data'); // require-https-only
const ws = new WebSocket('ws://socket.example.com'); // require-websocket-wssConfiguration
Default Configuration
{
"browser-security/no-unencrypted-transmission": "error"
}Options
| Option | Type | Default | Description |
|---|---|---|---|
allowInTests | boolean | false | In test files, exempt URLs whose written-down host is loopback (any scheme); a real host still reports |
insecureProtocols | string[] | [] | Insecure protocol patterns to detect |
secureAlternatives | object | {} | Mapping of insecure protocols to their secure alternatives |
ignorePatterns | string[] | [] | Additional safe patterns to ignore |
Example Configuration
{
"browser-security/no-unencrypted-transmission": [
"error",
{
"allowInTests": true,
"insecureProtocols": ["mongodb://", "redis://", "ftp://"],
"secureAlternatives": {
"mongodb://": "mongodb+srv://",
"redis://": "rediss://"
},
"ignorePatterns": ["localhost", "127.0.0.1"]
}
]
}Auto-Fix Behavior
The rule offers a suggestion (not an automatic fix) on string literals that rewrites the scheme to its secure alternative — mongodb:// to mongodb+srv://, redis:// to rediss://, and any pair supplied in secureAlternatives. Template literals get no suggestion: rewriting around an interpolation is too risky.
// Before (triggers rule)
const redisUrl = 'redis://cache.example.com:6379';
// After (suggestion applied)
const redisUrl = 'rediss://cache.example.com:6379';Best Practices
- Always use HTTPS: For all external API calls
- Use WSS for WebSockets: Encrypt WebSocket connections
- Database encryption: Use TLS/SSL for database connections
- Environment variables: Store URLs in environment variables
- Test exceptions: Use
allowInTests: truefor loopback hosts in tests; a real host in a test file still reports
Known False Negatives
The following patterns are not detected due to static analysis limitations:
Algorithm from Variable
Why: Algorithm names from variables not traced.
// ❌ NOT DETECTED - Algorithm from variable
const algo = config.hashAlgorithm; // May be weak
crypto.createHash(algo);Mitigation: Hardcode secure algorithms.
Third-party Crypto Libraries
Why: Non-standard crypto APIs not recognized.
// ❌ NOT DETECTED - Third-party
customCrypto.encrypt(data, key);Mitigation: Review all crypto implementations.
Configuration-based Security
Why: Config-driven security not analyzed.
// ❌ NOT DETECTED - Config-based
const options = getSecurityOptions(); // May be weakMitigation: Validate security configurations.
Related Rules
no-exposed-sensitive-data- Detects sensitive data exposureno-insecure-cookie-settings- Detects insecure cookies
Resources
- CWE-319: Cleartext Transmission of Sensitive Information
- OWASP: Transport Layer Protection
- MDN: HTTPS
Use this rule
npm install -D oxlint-plugin-browser-security{ "jsPlugins": ["oxlint-plugin-browser-security"], "rules": { "browser-security/no-unencrypted-transmission": "error" }}import { defineConfig } from 'vite-plus';export default defineConfig({ lint: { jsPlugins: ['oxlint-plugin-browser-security'], rules: { 'browser-security/no-unencrypted-transmission': 'error', }, },});oxlint-plugin-browser-security re-exports eslint-plugin-browser-security/oxlint: the same rules under the same IDs, and no ESLint install. Why oxlint.
Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.