Static Analysis
What is Static Analysis?
Static analysis examines source code without executing it. It finds bugs, security vulnerabilities, and code quality issues automatically.
Xcode Analyzer
Built into Xcode, the analyzer detects:
- Memory management issues
- Logic errors
- Dead code
- API misuse
Run it via Product, Analyze (Cmd+Shift+B).
SwiftLint for Security
SwiftLint enforces code style and can detect security anti-patterns:
# .swiftlint.yml
disabled_rules:
- trailing_whitespace
opt_in_rules:
- empty_count
- closure_spacing
- force_unwrapping
- implicitly_unwrapped_optional
# Custom rules for security
custom_rules:
no_print:
name: "No Print Statements"
regex: 'print\('
message: "Remove print statements in production code"
severity: warning
no_nslog:
name: "No NSLog"
regex: 'NSLog\('
message: "Use os_log instead of NSLog"
severity: warning
Swift Security Linting Tools
- SwiftLint: Code style and custom security rules
- Periphery: Detect unused code that may contain vulnerabilities
- SonarQube: Comprehensive static analysis with security rules
Automated Security Checks
Add security checks to your CI pipeline:
# Run SwiftLint with security rules
swiftlint lint --reporter json > lint-report.json
# Run Xcode analyzer
xcodebuild analyze -scheme MyApp -resultBundlePath analysis.xcresult
# Check for hardcoded secrets
grep -rn "api_key\|secret\|password" --include="*.swift" .
Manual Review Checklist
Security Code Review Checklist
Use this checklist when reviewing code for security:
Authentication & Authorization
- Tokens are stored in Keychain, not UserDefaults
- Biometric authentication is properly implemented
- Session timeout is enforced
- Logout clears all sensitive data
Data Storage
- Sensitive data uses appropriate file protection
- No sensitive data in logs or analytics
- Keychain items use ThisDeviceOnly
- CoreData uses encryption if storing sensitive data
Network Security
- All API calls use HTTPS
- Certificate pinning is implemented
- ATS exceptions are justified and documented
- No sensitive data in URL parameters
Input Validation
- All user input is validated
- SQL queries use parameterized statements
- URL schemes are validated
- WebView content is restricted
Privacy
- Only necessary permissions are requested
- Usage descriptions are clear and accurate
- App Tracking Transparency is implemented
- Data collection is minimized
Review Process
- Start with the most sensitive areas (auth, payments, data storage)
- Trace data flow from input to storage
- Check error handling paths for information leaks
- Verify third-party library versions for known vulnerabilities
- Test with malformed input
Common Findings
- API keys hardcoded in source
- Sensitive data logged in debug builds
- Weak encryption algorithms
- Missing certificate pinning
- Overly permissive entitlements
Common Security Issues
Issue: Insecure Keychain Access
// BAD: Default Keychain accessibility
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: key,
kSecValueData as String: data
]
// GOOD: With proper accessibility and biometric protection
let access = SecAccessControlCreateWithFlags(
kCFAllocatorDefault,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
[.biometryCurrentSet],
nil
)!
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: key,
kSecValueData as String: data,
kSecAttrAccessControl as String: access
]
Issue: WebView JavaScript Bridge
// BAD: Exposing sensitive methods to JavaScript
let controller = WKUserContentContainer()
controller.add(self, name: "getAuthToken")
controller.add(self, name: "deleteAccount")
// GOOD: Minimal bridge with validation
func userContentController(_ controller: WKUserContentController, didReceive message: WKScriptMessage) {
guard message.name == "getData" else { return }
guard let query = message.body as? String else { return }
// Validate and sanitize input
let sanitized = query.replacingOccurrences(of: "[^a-zA-Z0-9]", with: "", options: .regularExpression)
let result = fetchData(sanitized)
// Return result
}
Issue: URL Scheme Hijacking
// BAD: No URL validation
func application(_ app: UIApplication, open url: URL) -> Bool {
let token = url.lastPathComponent // Attacker can craft malicious URL
processToken(token)
return true
}
// GOOD: Validate URL scheme and host
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
guard url.scheme == "myapp" else { return false }
guard url.host == "auth" else { return false }
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false) else { return false }
guard let token = components.queryItems?.first(where: { $0.name == "token" })?.value else { return false }
// Validate token format
guard token.count == 32, token.allSatisfy({ $0.isLetter || $0.isNumber }) else { return false }
processToken(token)
return true
}
Issue: Sensitive Data in Backups
// Exclude sensitive files from iTunes/iCloud backup
func excludeFromBackup(url: URL) throws {
var resourceValues = URLResourceValues()
resourceValues.isExcludedFromBackup = true
try url.setResourceValues(resourceValues)
}
Quiz
1. What does the Xcode Analyzer detect?
2. Which tool enforces custom security rules in Swift code?
3. What should you check first during a security code review?
4. How do you exclude files from iCloud backup?
Flashcards
Question
What are the main categories in a security code review?
Click to reveal answer
Answer
Authentication and authorization, data storage, network security, input validation, privacy controls, and third-party library security.
Question
What is the benefit of adding security rules to SwiftLint?
Click to reveal answer
Answer
SwiftLint can automatically detect security anti-patterns like print statements, force unwrapping, and hardcoded secrets during CI builds.
Question
Why should sensitive files be excluded from backups?
Click to reveal answer
Answer
Backups may be accessed by unauthorized users or stored insecurely. Excluding sensitive files prevents credential and token exposure.
Revision Notes
Key Takeaways
- 1. Static analysis catches security issues before runtime
- 2. Use a checklist to ensure consistent security reviews
- 3. SwiftLint can enforce custom security rules
- 4. Focus review on authentication, payments, and data storage
- 5. Automate security checks in CI/CD pipeline
Interview Tips
- • Describe your approach to security code review
- • List common security issues you would look for
- • Explain how to automate security checks in CI
- • Discuss how you would review an authentication system
Cheat Sheet
Security Code Review Quick Reference
- Xcode Analyzer for static analysis
- SwiftLint for custom security rules
- Review auth, payments, and data storage first
- Trace data flow from input to storage
- Check for hardcoded secrets in CI
- Validate all URL schemes and inputs