Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Develop into Release #3038

Merged
merged 1 commit into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions swift/lang/storage/sensitive-storage-userdefaults.swift
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")
144 changes: 144 additions & 0 deletions swift/lang/storage/sensitive-storage-userdefaults.yaml
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
66 changes: 66 additions & 0 deletions swift/sqllite/sqllite-injection-audit.swift
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)
43 changes: 43 additions & 0 deletions swift/sqllite/sqllite-injection-audit.yaml
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
16 changes: 16 additions & 0 deletions swift/webview/webview-js-window.swift
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)
58 changes: 58 additions & 0 deletions swift/webview/webview-js-window.yaml
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 = ...