Insecure Transport
ID |
swift.insecure_transport |
Severity |
high |
Resource |
Information Leak |
Language |
Swift |
Tags |
CWE:319, MASWE:0050, NIST.SP.800-53, OWASP:2021:A4, PCI-DSS:6.5.4, PCI-DSS:6.5.6 |
Description
Insecure transport refers to vulnerabilities that arise when data is transmitted over a network without adequate encryption, making it vulnerable to interception and tampering by attackers.
This often involves using protocols like HTTP instead of HTTPS, or neglecting to configure SSL/TLS properly.
Rationale
Insecure transport vulnerabilities occur when sensitive data like credentials, personal information, or other sensitive communications are transmitted in plaintext or via improperly configured encryption protocols. Attackers can exploit such vulnerabilities through techniques like packet sniffing or man-in-the-middle attacks, compromising data integrity and confidentiality.
Exchange of sensitive data should always occur over secure channels to ensure that unauthorized parties cannot access or alter it.
Consider this simple example:
import Foundation
import FoundationNetworking
// FLAW: Using HTTP instead of HTTPS
let url = URL(string: "http://example.com/file.mp3")!
let (downloadURL, _) = try await URLSession.shared.download(from: url)
// ...
Remediation
To address insecure transport vulnerabilities, consider the following secure coding practices:
1. Use HTTPS: Always use HTTPS for data transmission. Configure your software to use HTTPS rather than HTTP. This involves obtaining a valid SSL/TLS certificate and configuring the target server(s) to support HTTPS.
2. Configure TLS Properly: Ensure proper configuration of TLS/SSL, avoiding outdated or vulnerable versions. Use strong ciphers and the latest protocol versions (TLS 1.2 or above).
3. Verify Certificates: When establishing HTTPS connections in software, ensure certificate validation is enabled and properly handled to avoid man-in-the-middle attacks.
4. Use Security Libraries: Use well-established libraries for making secure HTTP requests. Such libraries often come with sensible defaults for HTTP over TLS transport.
In Swift, the URLSession API provides built-in support for HTTPS and enforces SSL/TLS connections with certificate validation by default. Apple’s App Transport Security (ATS) policy encourages the use of HTTPS by blocking cleartext HTTP connections unless explicitly allowed in the app’s Info.plist.
Here’s a corrected example using HTTPS:
import Foundation
import FoundationNetworking // For non-Apple platforms
// FIXED
let url = URL(string: "https://example.com/file.mp3")!
let (downloadURL, _) = try await URLSession.shared.download(from: url)
// ...
App Transport Security (ATS)
Apple’s App Transport Security (ATS) is a security feature that improves privacy and data integrity by requiring secure connections. ATS is enabled by default in iOS 9.0+ and macOS 10.11+.
ATS blocks HTTP connections and enforces:
-
HTTPS with TLS 1.2 or higher
-
Forward secrecy ciphers
-
Certificates signed with SHA-256 or better
-
At least 2048-bit RSA keys or 256-bit ECC keys
To ensure your app uses ATS properly, avoid adding exceptions in Info.plist like:
<!-- BAD: Disables ATS globally -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
If you must allow HTTP for specific domains (e.g., development servers), use domain-specific exceptions:
<!-- BETTER: Only allow HTTP for specific domain -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
URLSession Configuration
For sensitive data transmission, you can further enhance security by customizing URLSession:
import Foundation
class SecureDataFetcher {
let apiUrl = "https://api.example.com/data"
func fetchData() async throws -> Data {
guard let url = URL(string: apiUrl) else {
throw URLError(.badURL)
}
// Create custom URLSession configuration
let configuration = URLSessionConfiguration.default
configuration.tlsMinimumSupportedProtocolVersion = .TLSv12
configuration.tlsMaximumSupportedProtocolVersion = .TLSv13
let session = URLSession(configuration: configuration)
let (data, response) = try await session.data(from: url)
// Verify HTTPS was used
if let httpResponse = response as? HTTPURLResponse,
let urlString = httpResponse.url?.absoluteString,
!urlString.hasPrefix("https://") {
throw URLError(.secureConnectionFailed)
}
return data
}
}
Configuration
The detector has the following configurable parameters:
-
allowedDomains, that indicates the domains that are allowed, even when using an insecure protocol.
References
-
CWE-319 : Cleartext Transmission of Sensitive Information.
-
OWASP - Top 10 2021 Category A02 : Cryptographic Failures.
-
MASWE-0050: Cleartext Traffic.
-
Preventing Insecure Network Connections - Apple’s guide to App Transport Security.
-
URLSession - Swift’s networking API.
-
NSAppTransportSecurity - ATS configuration reference.