Description
Apple's Network.framework is a lower-level API for configuring protocols such as TCP, UDP, TLS, and DTLS. The URL Loading System's App Transport Security (ATS) does not apply to these connections, so the application must configure transport protection and peer authentication correctly.
Network.NWParameters.tls combines TLS with TCP, and Network.NWParameters.dtls combines DTLS with UDP. Network.NWParameters.tcp and Network.NWParameters.udp do not add those security protocols. The forms Network.NWParameters(tls: nil, tcp: ...) and Network.NWParameters(dtls: nil, udp: ...) explicitly omit them as well.
Before sending sensitive data, check the actual protocol and peer authentication. A send call alone does not establish that a connection succeeded or that independent application-layer protection is absent.
Potential impact
If the application protocol also lacks authenticated encryption:
- Network observers or intermediaries may read credentials and personal information.
- An active attacker may modify transmitted data.
- An attacker may impersonate the server or peer.
- Captured messages may be replayed if separate replay controls are absent.
Remediation
- For TCP, use
Network.NWParameters.tlsor a non-nilTLS option. For UDP, useNetwork.NWParameters.dtlsor a non-nilDTLS option. - Retain the system's default server-trust evaluation. Do not install a callback that accepts every certificate or peer.
- For HTTP and URL-based resources, use HTTPS with
URLSessionand minimize ATS exceptions. - Minimize sensitive data in transit. If the threat model extends beyond TLS endpoints, add application-layer authenticated encryption with independent key management, unique nonces, and replay controls as defense in depth. It does not replace authenticated transport.
- Inspect network traffic from release builds to check for cleartext data and unexpected protocol paths.
Examples
Before
import Dispatch
import Foundation
import Network
func sendCredential(clientSecret: Data) {
let connection = Network.NWConnection(
host: "api.example.com",
port: 443,
using: Network.NWParameters.tcp
)
let queue = DispatchQueue(label: "cleartext-connection")
connection.start(queue: queue)
connection.send(content: clientSecret, completion: .contentProcessed { _ in })
}
After
import Dispatch
import Foundation
import Network
func sendCredential(clientSecret: Data) {
let connection = Network.NWConnection(
host: "api.example.com",
port: 443,
using: Network.NWParameters.tls
)
let queue = DispatchQueue(label: "tls-connection")
connection.start(queue: queue)
connection.send(content: clientSecret, completion: .contentProcessed { _ in })
}
Explanation:
- Before: Port 443 does not cause
Network.NWParameters.tcpto add TLS. Without an independently authenticated upper-layer protocol,clientSecretis unprotected. - After:
Network.NWParameters.tlsconfigures the default TLS/TCP stack. Keep server-trust evaluation enabled and handle connection states and send errors in the application.
References
- CWE-319: Cleartext Transmission of Sensitive Information
- Apple - Network
- Apple - NWParameters
- Apple TN3151 - Choosing the right networking API
- OWASP MASTG-TEST-0323: Uses of Low-Level Networking APIs for Cleartext Traffic
- OWASP MASTG-TEST-0344: Network.framework TLS Protocol Configuration
- OWASP MASTG-TEST-0236: Cleartext Traffic Observed on the Network
- CodeQL - Cleartext transmission of sensitive information