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/');

Configuration

This detector does not need any configuration.

References

© 2026 Xygeni. All rights reserved