Cleartext transmission of sensitive information ("Insecure Transport")
ID |
dart.network.insecure_transport |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
medium |
Remediation Effort |
medium |
Resource |
Network |
Language |
Dart |
Description
Sensitive data is transmitted over a cleartext channel: http:// or ws:// URL, Uri.http(…) constructor, raw Socket.connect, or a Dio BaseOptions(baseUrl: 'http://…'). Any network attacker in the path can read, modify, or forge requests.
Rationale
Cleartext HTTP and WebSocket traffic is observable and modifiable by:
-
Any open / poorly-configured Wi-Fi access point (coffee shops, hotels, airports — the most common attack surface for mobile apps).
-
Anyone on the same broadcast LAN segment (corporate, hotel, cellular captive portals).
-
Anyone in the carrier or upstream-ISP path with access to traffic capture.
-
Hostile state actors performing wholesale interception.
Flutter compounds the risk because Flutter apps ignore the OS proxy setting and OS-level TLS configuration on most targets (Cossack Labs: "Flutter application security considerations"). A user who legitimately configures a proxy or installs a corporate cert cannot route Flutter traffic through it — and conversely, app code that opts in to cleartext cannot rely on system-wide protections kicking in.
The rule allow-lists localhost, 127.0.0.1, [::1], and the .local
/ .test / .example suffixes (dev / mDNS / RFC 2606), so legitimate
loopback or development traffic does not produce findings.
The following code illustrates a vulnerable pattern detected by this rule:
class Cleartext {
Future<void> uriLiterals() async {
// VULNERABLE: Cleartext transmission of sensitive information ("Insecure Transport")
final u1 = Uri.parse('http://api.example.com/v1');
// VULNERABLE: Cleartext transmission of sensitive information ("Insecure Transport")
final u2 = Uri.parse("http://example.com/x");
// VULNERABLE: Cleartext transmission of sensitive information ("Insecure Transport")
final u3 = Uri.http('api.example.com', '/v1/users');
print('$u1 $u2 $u3');
}
}
Remediation
Use https:// / wss:// everywhere; for high-value targets add
certificate pinning at the Dart layer (see android_certificate_pinning
and insecure_ssl). Reject http:// URLs at the boundary if they
reach a network call.
// Vulnerable
await http.get(Uri.parse('http://api.example.com/balance'));
final dio = Dio(BaseOptions(baseUrl: 'http://api.example.com'));
await WebSocket.connect('ws://socket.example.com/');
// Fixed
await http.get(Uri.parse('https://api.example.com/balance'));
final dio = Dio(BaseOptions(baseUrl: 'https://api.example.com'));
await WebSocket.connect('wss://socket.example.com/');
References
-
OWASP Top 10 2025 - A04 : Cryptographic Failures.
-
OWASP Top 10 2025 - A06 : Insecure Design.
-
Talsec — OWASP Mobile Top 10 for Flutter M5 — Insecure communication in Flutter / Dart, with concrete MitM scenarios
-
Cossack Labs — Flutter application security considerations — Documents Flutter’s bypass of OS proxy / system TLS on most targets
-
OWASP Transport Layer Security Cheat Sheet — TLS configuration recommendations and pinning guidance