-
Notifications
You must be signed in to change notification settings - Fork 395
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add Swift rules * add nosemgrep * add category * add nosemgrep * fix name conflict
- Loading branch information
1 parent
4c49b7a
commit d5bec93
Showing
6 changed files
with
362 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
let username = getUsername() | ||
let passphrase = getPass() | ||
|
||
|
||
// okid: swift-user-defaults | ||
UserDefaults.standard.set(username, forKey: "userName") | ||
// ruleid: swift-user-defaults | ||
UserDefaults.standard.set(passphrase, forKey: "passphrase") | ||
// ruleid: swift-user-defaults | ||
UserDefaults.standard.set(passWord, forKey: "userPassword") | ||
|
||
// ruleid: swift-user-defaults | ||
UserDefaults.standard.set("12717-127163-a71367-127ahc", forKey: "apiKey") | ||
|
||
let apiKey = "12717-127163-a71367-127ahc" | ||
// ruleid: swift-user-defaults | ||
UserDefaults.standard.set(apiKey, forKey: "GOOGLE_TOKEN") | ||
|
||
|
||
let key = "1sdad3SADSD33131" | ||
// ruleid: swift-user-defaults | ||
UserDefaults.standard.set(key, forKey: "cryptoKey") | ||
|
||
|
||
let key = "foobar" | ||
// ruleid: swift-user-defaults | ||
UserDefaults.standard.set(key, forKey: "clientSecret") | ||
|
||
|
||
let key = "foobar" | ||
// ruleid: swift-user-defaults | ||
UserDefaults.standard.set(key, forKey: "rsaPrivateKey") | ||
|
||
// ruleid: swift-user-defaults | ||
UserDefaults.standard.set(passphrase, forKey: "pass_phrase") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
rules: | ||
- id: swift-user-defaults | ||
message: >- | ||
Potentially sensitive data was observed to be stored in UserDefaults, which is not adequate protection | ||
of sensitive information. For data of a sensitive nature, applications should leverage the Keychain. | ||
severity: WARNING | ||
metadata: | ||
likelihood: LOW | ||
impact: HIGH | ||
confidence: MEDIUM | ||
category: security | ||
cwe: | ||
- 'CWE-311: Missing Encryption of Sensitive Data' | ||
masvs: | ||
- 'MASVS-STORAGE-1: The app securely stores sensitive data' | ||
owasp: | ||
- A03:2017 - Sensitive Data Exposure | ||
- A04:2021 - Insecure Design | ||
references: | ||
- https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/ValidatingInput.html | ||
- https://mas.owasp.org/MASVS/controls/MASVS-STORAGE-1/ | ||
subcategory: | ||
- vuln | ||
technology: | ||
- ios | ||
- macos | ||
languages: | ||
- swift | ||
options: | ||
taint_propagation: true | ||
patterns: | ||
- pattern-either: | ||
- patterns: | ||
- pattern-either: | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: $KEY) | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: $KEY) | ||
- metavariable-regex: | ||
metavariable: $VALUE | ||
regex: (?i).*(passcode|password|pass_word|passphrase|pass_code|pass_word|pass_phrase)$ | ||
- focus-metavariable: $VALUE | ||
- patterns: | ||
- pattern-either: | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: $KEY) | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: $KEY) | ||
- metavariable-regex: | ||
metavariable: $KEY | ||
regex: (?i).*(passcode|password|pass_word|passphrase|pass_code|pass_word|pass_phrase)$ | ||
- focus-metavariable: $KEY | ||
- patterns: | ||
- pattern-either: | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: $KEY) | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: $KEY) | ||
- metavariable-regex: | ||
metavariable: $VALUE | ||
regex: (?i).*(api_key|apikey)$ | ||
- focus-metavariable: $VALUE | ||
- patterns: | ||
- pattern-either: | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: $KEY) | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: $KEY) | ||
- metavariable-regex: | ||
metavariable: $KEY | ||
regex: (?i).*(api_key|apikey)$ | ||
- focus-metavariable: $KEY | ||
- patterns: | ||
- pattern-either: | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: $KEY) | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: $KEY) | ||
- metavariable-regex: | ||
metavariable: $VALUE | ||
regex: (?i).*(secretkey|secret_key|secrettoken|secret_token|clientsecret|client_secret)$ | ||
- focus-metavariable: $VALUE | ||
- patterns: | ||
- pattern-either: | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: $KEY) | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: $KEY) | ||
- metavariable-regex: | ||
metavariable: $KEY | ||
regex: (?i).*(secretkey|secret_key|secrettoken|secret_token|clientsecret|client_secret)$ | ||
- focus-metavariable: $KEY | ||
- patterns: | ||
- pattern-either: | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: $KEY) | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: $KEY) | ||
- metavariable-regex: | ||
metavariable: $VALUE | ||
regex: (?i).*(cryptkey|cryptokey|crypto_key|cryptionkey|symmetrickey|privatekey|symmetric_key|private_key)$ | ||
- focus-metavariable: $VALUE | ||
- patterns: | ||
- pattern-either: | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set("$VALUE", forKey: $KEY) | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: "$KEY") | ||
- pattern: | | ||
UserDefaults.standard.set($VALUE, forKey: $KEY) | ||
- metavariable-regex: | ||
metavariable: $KEY | ||
regex: (?i).*(cryptkey|cryptokey|crypto_key|cryptionkey|symmetrickey|privatekey|symmetric_key|private_key)$ | ||
- focus-metavariable: $KEY |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
let username = someField.text() | ||
let password = a.text() | ||
|
||
let sql = "SELECT * FROM semgrep_users WHERE username = '\(username)' AND password = '\(password)'" | ||
|
||
// ruleid:swift-potential-sqlite-injection | ||
let result = sqlite3_exec(db, sql, nil, nil, nil) | ||
sqlite3_close(db) | ||
|
||
let sql = "SELECT * FROM semgrep_users WHERE username = 'admin' AND password = '\(password)'" | ||
// ruleid:swift-potential-sqlite-injection | ||
let result = sqlite3_exec(db, sql, nil, nil, nil) | ||
sqlite3_close(db) | ||
|
||
|
||
let sql = "SELECT * FROM semgrep_users WHERE username = ? AND password = ?" | ||
var stmt: OpaquePointer? | ||
// okid:swift-potential-sqlite-injection | ||
if sqlite3_prepare_v2(db, sql, -1, &stmt, nil) == SQLITE_OK { | ||
sqlite3_bind_text(stmt, 1, username, -1, nil) | ||
sqlite3_bind_text(stmt, 2, password, -1, nil) | ||
if sqlite3_step(stmt) == SQLITE_DONE { | ||
// SUCCESS | ||
} | ||
} | ||
|
||
sqlite3_finalize(stmt) | ||
sqlite3_close(db) | ||
|
||
let sql = "SELECT * FROM semgrep_users WHERE username = 'admin' AND password = 'admin'" | ||
// okid:swift-potential-sqlite-injection | ||
let result = sqlite3_exec(db, sql, nil, nil, nil) | ||
sqlite3_close(db) | ||
|
||
|
||
let theUsername = "admin" | ||
let sql = "SELECT * FROM semgrep_users WHERE username = '" + theUsername + "' AND password = 'admin'" | ||
// FP but cant do much about this I dont think | ||
// ruleid:swift-potential-sqlite-injection | ||
let result = sqlite3_exec(db, sql, nil, nil, nil) | ||
sqlite3_close(db) | ||
|
||
let newUser = getUsernameFromServer() | ||
let sql = "SELECT * FROM semgrep_users WHERE username = '" + newUser + "' AND password = 'admin'" | ||
// ruleid:swift-potential-sqlite-injection | ||
let result = sqlite3_exec(db, sql, nil, nil, nil) | ||
sqlite3_close(db) | ||
|
||
|
||
let sql = "SELECT * FROM semgrep_users WHERE username = 'admin' AND password = '" + password + "'" | ||
// ruleid:swift-potential-sqlite-injection | ||
let result = sqlite3_exec(db, sql, nil, nil, nil) | ||
sqlite3_close(db) | ||
|
||
|
||
let sql = "SELECT * FROM semgrep_users WHERE username = ? AND password = '" + password + "'" | ||
// ruleid:swift-potential-sqlite-injection | ||
if sqlite3_prepare_v2(db, sql, -1, &stmt, nil) == SQLITE_OK { | ||
sqlite3_bind_text(stmt, 1, username, -1, nil) | ||
if sqlite3_step(stmt) == SQLITE_DONE { | ||
// SUCCESS | ||
} | ||
} | ||
|
||
sqlite3_finalize(stmt) | ||
sqlite3_close(db) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
rules: | ||
- id: swift-potential-sqlite-injection | ||
message: >- | ||
Potential Client-side SQL injection which has different impacts depending on the SQL use-case. The | ||
impact may include the circumvention of local authentication mechanisms, obtaining of sensitive data | ||
from the app, or manipulation of client-side behavior. It wasn't possible to make certain that the | ||
source is untrusted, but the application should avoid concatenating dynamic data into SQL queries | ||
and should instead leverage parameterized queries. | ||
severity: WARNING | ||
metadata: | ||
likelihood: MEDIUM | ||
impact: MEDIUM | ||
confidence: LOW | ||
category: security | ||
cwe: | ||
- "CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')" | ||
masvs: | ||
- 'MASVS-CODE-4: The app validates and sanitizes all untrusted inputs.' | ||
references: | ||
- https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/ValidatingInput.html | ||
subcategory: | ||
- vuln | ||
technology: | ||
- ios | ||
- macos | ||
languages: | ||
- swift | ||
mode: taint | ||
pattern-sources: | ||
- pattern-either: | ||
- pattern: | | ||
"...\($X)..." | ||
- pattern: | | ||
$SQL = "..." + $X | ||
- pattern: | | ||
$SQL = $X + "..." | ||
pattern-sinks: | ||
- patterns: | ||
- pattern-either: | ||
- pattern: sqlite3_exec($DB, $SQL, ...) | ||
- pattern: sqlite3_prepare_v2($DB, $SQL, ...) | ||
- focus-metavariable: | ||
- $SQL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
let prefs = WKPreferences() | ||
// ruleid: swift-webview-config-allows-js-open-windows | ||
prefs.JavaScriptCanOpenWindowsAutomatically = true | ||
let config = WKWebViewConfiguration() | ||
config.defaultWebpagePreferences = prefs | ||
|
||
WKWebView(frame: .zero, configuration: config) | ||
|
||
let prefs2 = WKPreferences() | ||
prefs2.JavaScriptCanOpenWindowsAutomatically = true | ||
// okid: swift-webview-config-allows-js-open-windows | ||
prefs2.JavaScriptCanOpenWindowsAutomatically = false | ||
let config = WKWebViewConfiguration() | ||
config.defaultWebpagePreferences = prefs2 | ||
|
||
WKWebView(frame: .zero, configuration: config) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
rules: | ||
- id: swift-webview-config-allows-js-open-windows | ||
message: >- | ||
Webviews were observed that explictly allow JavaScript in an WKWebview to open windows automatically. | ||
Consider disabling this functionality if not required, following the principle of least privelege. | ||
severity: WARNING | ||
metadata: | ||
likelihood: LOW | ||
impact: LOW | ||
confidence: HIGH | ||
category: security | ||
cwe: | ||
- 'CWE-272: Least Privilege Violation' | ||
masvs: | ||
- 'MASVS-PLATFORM-2: The app uses WebViews securely' | ||
references: | ||
- https://mas.owasp.org/MASVS/controls/MASVS-PLATFORM-2/ | ||
- https://developer.apple.com/documentation/webkit/wkpreferences/1536573-javascriptcanopenwindowsautomati | ||
subcategory: | ||
- audit | ||
technology: | ||
- ios | ||
- macos | ||
languages: | ||
- swift | ||
patterns: | ||
- pattern: | | ||
$P = WKPreferences() | ||
... | ||
- pattern-either: | ||
- patterns: | ||
- pattern-inside: | | ||
$P.JavaScriptCanOpenWindowsAutomatically = $FALSE | ||
... | ||
$P.JavaScriptCanOpenWindowsAutomatically = $TRUE | ||
# nosemgrep | ||
- pattern-not-inside: | | ||
... | ||
$P.JavaScriptCanOpenWindowsAutomatically = $TRUE | ||
... | ||
$P.JavaScriptCanOpenWindowsAutomatically = $FALSE | ||
- pattern: | | ||
$P.JavaScriptCanOpenWindowsAutomatically = true | ||
- metavariable-regex: | ||
metavariable: $TRUE | ||
regex: ^(true)$ | ||
- metavariable-regex: | ||
metavariable: $TRUE | ||
regex: (.*(?!true)) | ||
- patterns: | ||
- pattern: | | ||
$P.JavaScriptCanOpenWindowsAutomatically = true | ||
# nosemgrep | ||
- pattern-not-inside: | | ||
... | ||
$P.JavaScriptCanOpenWindowsAutomatically = ... | ||
... | ||
$P.JavaScriptCanOpenWindowsAutomatically = ... |