Connection String Parameter Pollution
ID |
swift.connection_string_parameter_pollution |
Severity |
critical |
Resource |
Resource Management |
Language |
Swift |
Tags |
CWE:15, NIST.SP.800-53, OWASP:2021:A5, PCI-DSS:6.5.10 |
Description
External control of connection string.
In iOS, macOS, and server-side Swift applications, connection string pollution commonly occurs when:
-
SQLite database file paths come from user input (FMDB, GRDB, SQLite.swift)
-
MongoDB connection strings include user-controlled parameters (MongoSwift, MongoKitten)
-
Redis server addresses or credentials are derived from external sources (SwiftRedis)
-
PostgreSQL/MySQL connection URLs are constructed from query parameters or environment variables
Rationale
Database connectivity typically involves constructing a connection string – a snippet of text encoding the details of the connection to the database, such as hostname, database name, and credentials.
When user input is improperly included in a connection string, it can lead to parameter pollution. This means that the attacker can inject additional parameters or override existing ones, potentially accessing databases they shouldn’t or altering their privileges.
The following example shows this vulnerability with MongoDB connection string:
import MongoSwift
class MongoService {
// VULNERABLE: User-controlled MongoDB connection string
func connectToMongoDB(connectionString: String) async throws {
// connectionString from environment variable, config file, or query parameter
// Attacker might provide:
// "mongodb://attacker.com/malicious?authSource=admin&ssl=false"
// "mongodb://localhost/mydb?connectTimeoutMS=1&socketTimeoutMS=1" (DoS)
// ISSUE: User controls entire connection string
let client = try MongoClient(connectionString)
let db = client.db("myapp")
// Attacker may have connected to their own server or disabled security
}
}
Remediation
Mitigating connection string parameter pollution involves several key practices:
-
Use Parameter Objects: Avoid concatenating user input into connection strings. Instead, use APIs or configurations that separate parameters from the connection logic.
-
Validate and Sanitize User Input: If user input must be incorporated into the connection process, ensure it is strictly validated and sanitized according to expected patterns.
-
Environment Configuration: Use environment variables or configuration files to manage sensitive credential information away from user modification capabilities.
To fix the previous vulnerability, carefully validate each part of the connection string:
import MongoSwift
class SecureMongoService {
// FIXED: Use structured configuration, not raw strings
func connectToMongoDB(host: String, port: Int, database: String, username: String, password: String) async throws {
// Validate inputs
guard isValidHostname(host),
isValidPort(port),
isValidIdentifier(database),
isValidIdentifier(username) else {
throw ValidationError.invalidInput
}
// Build connection string with validated parameters
let connectionString = "mongodb://\(username):\(password)@\(host):\(port)/\(database)?ssl=true&authSource=admin"
let client = try MongoClient(connectionString)
}
// FIXED: Use connection options object
func connectWithOptions() async throws {
var options = MongoClientOptions()
options.credential = MongoCredential(username: "user", password: "pass", source: "admin")
options.tls = TLSOptions(enabled: true)
let client = try MongoClient("mongodb://localhost:27017", options: options)
}
private func isValidHostname(_ host: String) -> Bool {
// Whitelist allowed hosts
let allowedHosts = ["localhost", "db.example.com", "mongo-cluster.example.com"]
return allowedHosts.contains(host)
}
private func isValidPort(_ port: Int) -> Bool {
return port > 0 && port <= 65535 && port == 27017 // Restrict to standard MongoDB port
}
private func isValidIdentifier(_ identifier: String) -> Bool {
// Only allow alphanumeric and underscore
let pattern = "^[a-zA-Z0-9_]+$"
return identifier.range(of: pattern, options: .regularExpression) != nil
}
}
enum ValidationError: Error {
case invalidInput
}
Key Prevention Strategies:
-
Never concatenate user input into connection strings.
-
Use whitelisting for database names, hostnames, and other parameters.
-
Validate all inputs with strict patterns (alphanumeric only, no special characters).
-
Use configuration objects instead of raw connection strings when available
-
Strip path traversal sequences (e.g., use
lastPathComponentfor file paths) -
Store connection details in secure configuration files, not user-accessible sources
-
Use environment variables with validation for sensitive credentials
-
Enforce SSL/TLS in connection configuration (don’t allow user to disable)
-
Log connection attempts to detect unauthorized database access
-
Follow the Principle of Least Privilege: Use database accounts with minimal required permissions
Configuration
The detector has the following configurable parameters:
-
sources, that indicates the source kinds to check. -
neutralizations, that indicates the neutralization kinds to check.
Unless you need to change the default behavior, you typically do not need to configure this detector.
References
-
CWE-15 : External Control of System or Configuration Setting.
-
Connection String Parameter Pollution Attacks, by C. Alonso, Blackhat DC 2010.
-
OWASP Top 10 2021 - A03 : Injection.