Static Application Security Testing (SAST)
Static Application Security Testing (SAST)
SAST analyzes source code to identify security vulnerabilities without executing the application.
Automated SAST Implementation:
// iOS - Custom SAST scanner
import Foundation
class StaticSecurityAnalyzer {
struct SecurityIssue {
let severity: Severity
let category: String
let description: String
let file: String
let line: Int
let recommendation: String
enum Severity {
case critical, high, medium, low, info
}
}
// Analyze Swift source files
func analyzeSourceCode(at path: String) -> [SecurityIssue] {
var issues: [SecurityIssue] = []
let fileManager = FileManager.default
guard let enumerator = fileManager.enumerator(atPath: path) else { return issues }
while let file = enumerator.nextObject() as? String {
if file.hasSuffix(".swift") {
let filePath = (path as NSString).appendingPathComponent(file)
issues.append(contentsOf: analyzeSwiftFile(at: filePath))
}
}
return issues
}
private func analyzeSwiftFile(at path: String) -> [SecurityIssue] {
var issues: [SecurityIssue] = []
guard let content = try? String(contentsOfFile: path) else { return issues }
let lines = content.components(separatedBy: .newlines)
for (index, line) in lines.enumerated() {
// Check for hardcoded secrets
if let issue = checkForHardcodedSecrets(line: line, lineNumber: index + 1, file: path) {
issues.append(issue)
}
// Check for insecure random number generation
if let issue = checkForInsecureRandom(line: line, lineNumber: index + 1, file: path) {
issues.append(issue)
}
// Check for disabled certificate validation
if let issue = checkForDisabledCertValidation(line: line, lineNumber: index + 1, file: path) {
issues.append(issue)
}
// Check for insecure data storage
if let issue = checkForInsecureStorage(line: line, lineNumber: index + 1, file: path) {
issues.append(issue)
}
}
return issues
}
private func checkForHardcodedSecrets(line: String, lineNumber: Int, file: String) -> SecurityIssue? {
let patterns = [
("password\\s*=\\s*\"[^\"]+\"", "Hardcoded password detected"),
("apiKey\\s*=\\s*\"[^\"]+\"", "Hardcoded API key detected"),
("secret\\s*=\\s*\"[^\"]+\"", "Hardcoded secret detected"),
("token\\s*=\\s*\"[^\"]+\"", "Hardcoded token detected")
]
for (pattern, message) in patterns {
if let _ = line.range(of: pattern, options: .regularExpression) {
return SecurityIssue(
severity: .critical,
category: "Hardcoded Secrets",
description: message,
file: file,
line: lineNumber,
recommendation: "Use Keychain or environment variables for sensitive data"
)
}
}
return nil
}
private func checkForInsecureRandom(line: String, lineNumber: Int, file: String) -> SecurityIssue? {
if line.contains("arc4random()") || line.contains("rand()") {
return SecurityIssue(
severity: .medium,
category: "Weak Cryptography",
description: "Insecure random number generation",
file: file,
line: lineNumber,
recommendation: "Use SecRandomCopyBytes for cryptographic randomness"
)
}
return nil
}
}