Free Swift SAST scanner: find security bugs in Swift code
DepWarden's free Swift SAST scanner checks Swift source code against 10 security rules (including 7 iOS-specific rules). Every rule maps to a CWE and the findings span 4 OWASP Top 10 categories, and every finding comes with an explanation, a fix and a before-and-after example. Paste a file, upload a zip or connect a repository: no account, and the results stay in a private, session-isolated workspace.
Swift builds iOS and macOS apps. Security problems in mobile apps are usually about how the app stores and transmits data, so the rules below concentrate on that.
What DepWarden checks in Swift code
10 rules cover 10 distinct weakness types (1 critical, 4 high, 5 medium and 0 low severity).
| What it checks | Rules | Examples |
|---|---|---|
| Privacy and data leaks | 4 | iOS NSLog with sensitive data; iOS UserDefaults storing sensitive data; iOS Keychain item always accessible (even when locked) |
| Injection (SQL, command, code) | 2 | SQL injection via interpolation; OS command execution |
| Weak cryptography | 2 | iOS URLSession SSL pinning bypassed; Weak hash (MD5/SHA1) |
| Cross-site scripting | 1 | iOS WKWebView JavaScript enabled (non-default check) |
| Insecure configuration | 1 | iOS NSAllowsArbitraryLoads — ATS disabled |
Examples from the Swift rules
iOS URLSession SSL pinning bypassed (CWE-295, critical)
Implementing didReceiveChallenge and calling completionHandler with .useCredential or .performDefaultHandling without validating the server certificate bypasses SSL pinning.
Vulnerable:
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
}Fixed:
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
guard validate(challenge.protectionSpace.serverTrust, against: pinnedCertificates) else {
return completionHandler(.cancelAuthenticationChallenge, nil)
}
completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
}Validate the certificate chain against pinned certificates. Use TrustKit or implement pinning via URLSessionDelegate properly.
iOS NSAllowsArbitraryLoads — ATS disabled (CWE-319, high)
NSAllowsArbitraryLoads=YES disables App Transport Security, allowing connections over plain HTTP to any host.
Vulnerable:
<key>NSAllowsArbitraryLoads</key>
<true/>Fixed:
<key>NSExceptionDomains</key>
<dict>
<key>legacy.example.com</key>
<dict><key>NSExceptionAllowsInsecureHTTPLoads</key><true/></dict>
</dict>Remove this key. If specific hosts require HTTP for legacy reasons, use NSExceptionDomains to limit the exception to those hosts.
iOS NSLog with sensitive data (CWE-532, high)
NSLog output appears in device logs (Console.app, Xcode console) and is readable by other processes on jailbroken devices. Never log passwords, tokens, or PII.
Vulnerable:
NSLog("login password=%@", password)Fixed:
os_log("login attempt for user", type: .info)Remove NSLog statements that include sensitive data. Use os_log with privacy annotations for structured logging.
Run it
- Paste code: open the SAST scanner, choose Swift and paste a file. You get findings in seconds.
- Upload a zip: files with these extensions are scanned: .swift. Dependency folders such as node_modules and vendor are skipped.
- Connect a repo: point DepWarden at a branch and it scans it once or on a schedule, with an emailed report.
- In CI: the GitHub Action runs SAST as its own step and can fail the build on severity. CI use goes through an API key and needs a plan that includes SAST.
- uses: Rushabh5000/depwarden-action@v1
with:
sast-dir: src
sast-fail-on: high
env:
APP_API_KEY: ${{ secrets.APP_API_KEY }}What it does not do
DepWarden's SAST engine uses pattern rules and taint-aware rules that require untrusted input to reach a dangerous call. It is not a full cross-file dataflow engine, so a bug that only appears when data crosses several files can be missed, and every static analyser reports some false positives. Treat findings as leads: review them, fix the real ones and suppress the rest with a written reason. SAST covers the code you write; for the packages you import, run software composition analysis too.
Frequently asked questions
Is there a free Swift SAST tool?
Yes. DepWarden's Swift scanner is free in the browser with no account: paste code, upload a zip or connect a repository. Running SAST from CI through an API key needs a plan that includes SAST.
Which Swift files are scanned?
.swift. Configuration and secret-bearing files such as .env and key files are also checked for hardcoded credentials, whatever language the project uses.
How do I fix what it finds?
Each finding names the weakness (CWE), explains why the code is risky, shows a vulnerable and a fixed version of the pattern, and gives the remediation. Fix the code, then scan again to confirm the finding is gone.
More
Other languages: Python, Java, JavaScript and TypeScript, PHP, Go (Golang), C#, Ruby, Kotlin, and secret scanning. Compare the options in free SAST tools compared, or start with what is SAST and SAST vs SCA.