[HOTFIX] Regex + Rule Update (#2232)

* IOS Swift Rules updates
  *  Updated or added rules `ios_biometric_bool`, `ios_biometric_acl`, `ios_keychain_weak_acl_device_passcode`, `ios_keychain_weak_accessibility_value`, `ios_insecure_random_no_generator`, `ios_biometry_hardened`
 * Regex Hardening: Fixes possible Regex DoS in rules and MobSF code base
This commit is contained in:
Ajin Abraham
2023-08-10 01:16:12 -07:00
committed by GitHub
parent 9e57c5767d
commit 28b7fdeca5
10 changed files with 126 additions and 56 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ from mobsf.install.windows.setup import windows_config_local
logger = logging.getLogger(__name__)
VERSION = '3.7.1'
VERSION = '3.7.2'
BANNER = """
__ __ _ ____ _____ _____ _____
| \/ | ___ | |__/ ___|| ___|_ _|___ /|___ |
+1 -1
View File
@@ -601,7 +601,7 @@ def cmd_injection_check(data):
def strict_package_check(user_input):
"""Strict package name check."""
pat = re.compile(r'^\w+\.*[\w\.\$]+$')
pat = re.compile(r'^([A-Za-z]{1}[\w]*\.)+[A-Za-z][\w]*$')
resp = re.match(pat, user_input)
if not resp:
logger.error('Invalid package/class name')
@@ -137,12 +137,12 @@
message: Cryptographic Asymmetric Key Generation
selection: 'The application generate asymmetric cryptographic keys {}.'
choice:
- - - 'java\.security\.KeyPairGenerator|\.getInstance\(.*(?:RSA|rsa)'
- - - 'java\.security\.KeyPairGenerator|\.getInstance\(.{0,48}(?:RSA|rsa)'
- 512|768|1024
- >-
not in accordance with FCS_CKM.1.1(1) using key generation algorithm RSA
schemes and cryptographic key sizes of 1024-bit or lower
- - - 'java\.security\.KeyPairGenerator|\.getInstance\(.*(?:RSA|rsa)'
- - - 'java\.security\.KeyPairGenerator|\.getInstance\(.{0,48}(?:RSA|rsa)'
- 2048|3072|4096
- >-
in accordance with a specified cryptographic key generation algorithm
@@ -156,7 +156,7 @@
A password/passphrase shall perform [Password-based Key Derivation
Functions] {}.
choice:
- - \.getInstance\(\"PBKDF2|PBEKeySpec\(.*?\)
- - \.getInstance\(\"PBKDF2|PBEKeySpec\(.{0,48}?\)
- in accordance with a specified cryptographic algorithm.
class: Selection-Based Security Functional Requirements
- id: FCS_COP.1.1(1)
@@ -165,9 +165,9 @@
message: Cryptographic Operation - Encryption/Decryption
selection: 'The application perform encryption/decryption {}.'
choice:
- - '\.getInstance\(.*(?:AES/ECB/|/aes/ecb/|AES/CTR/|aes/ctr/)'
- - '\.getInstance\(.{0,48}(?:AES/ECB/|/aes/ecb/|AES/CTR/|aes/ctr/)'
- 'not in accordance with FCS_COP.1.1(1), AES-ECB mode is being used'
- - '\.getInstance\(.*(?:AES/CBC/|aes/cbc|AES/GCM/|aes/gcm/)'
- - '\.getInstance\(.{0,48}(?:AES/CBC/|aes/cbc|AES/GCM/|aes/gcm/)'
- >-
in accordance with a specified cryptographic algorithm AES-CBC (as
defined in NIST SP 800-38A) mode or AES-GCM (as defined in NIST SP
@@ -179,12 +179,12 @@
message: Cryptographic Operation - Hashing
selection: 'The application perform cryptographic hashing services {}.'
choice:
- - 'DigestUtils\.md5\(|\.getInstance\(.*(?:md4|md5|rc2|rc4|RC4|RC2|MD4|MD5)'
- - 'DigestUtils\.md5\(|\.getInstance\(.{0,48}(?:md4|md5|rc2|rc4|RC4|RC2|MD4|MD5)'
- >-
not in accordance with FCS_COP.1.1(2) and uses the cryptographic
algorithm RC2/RC4/MD4/MD5
- - >-
\.getInstance\(.*(?:\.SHA1|\.SHA256|\.SHA384|\.SHA512|SHA-1|SHA-256|SHA-384|SHA-512|sha-1|sha-256|sha-384|sha-512)
\.getInstance\(.{0,48}(?:\.SHA1|\.SHA256|\.SHA384|\.SHA512|SHA-1|SHA-256|SHA-384|SHA-512|sha-1|sha-256|sha-384|sha-512)
- >-
in accordance with a specified cryptographic algorithm
SHA-1/SHA-256/SHA-384/SHA-512 and message digest sizes 160/256/384/512
@@ -200,11 +200,11 @@
choice:
- - - >-
\.VerifyStringENC|\.signStringENC|\.signHashENC|\.initVerify\(|\.verify\(|\.initSign\(|\.sign\(
- 'CkRsa\(|\.getInstance\(.*(?:RSA|rsa)'
- 'CkRsa\(|\.getInstance\(.{0,48}(?:RSA|rsa)'
- RSA schemes using cryptographic key sizes of 2048-bit or greater
- - - >-
\.VerifyStringENC|\.signStringENC|\.signHashENC|\.initVerify\(|\.verify\(|\.initSign\(|\.sign\(
- 'CkEcc\(|\.getInstance\(.*(?:ECDSA|ecdsa)'
- 'CkEcc\(|\.getInstance\(.{0,48}(?:ECDSA|ecdsa)'
- 'ECDSA schemes using "NIST curves" P-256, P-384'
class: Selection-Based Security Functional Requirements
- id: FCS_COP.1.1(4)
@@ -243,7 +243,7 @@
message: HTTPS Protocol
selection: The application implement HTTPS using TLS.
choice:
- - \.getInstance\(.*TLS|HttpsURLConnection| Scheme \(\"https
- - \.getInstance\(.{0,48}TLS|HttpsURLConnection| Scheme \(\"https
- null
- - \.tlsVersions\(TlsVersion
- null
@@ -257,7 +257,7 @@
invalid.
choice:
- - >-
SSLPeerUnverifiedException\(|CertificateException|\(.*SSLException|CertPathValidatorException
SSLPeerUnverifiedException\(|CertificateException|\(.{0,48}SSLException|CertPathValidatorException
- >-
not establish the connection or request application authorization to
establish the connection
@@ -274,7 +274,7 @@
- RFC 5280 certificate validation and certificate path validation
- - checkClientTrusted
- The certificate path must terminate with a trusted CA certificate
- - \.getBasicConstraints\(\).*0|\.getBasicConstraints\(\) >.* -1
- - \.getBasicConstraints\(\).{0,48}0|\.getBasicConstraints\(\) >.{0,48} -1
- >-
The application validate a certificate path by ensuring the presence of
the basicConstraints extension and that the CA flag is set to TRUE for
@@ -295,7 +295,7 @@
The application treat a certificate as a CA certificate only if the
basicConstraints extension is present and the CA flag is set to TRUE.
choice:
- - \.getBasicConstraints\(\).*0|\.getBasicConstraints\(\) >.* -1
- - \.getBasicConstraints\(\).{0,48}0|\.getBasicConstraints\(\) >.{0,48} -1
- null
class: Selection-Based Security Functional Requirements
- id: FIA_X509_EXT.2.1
@@ -351,6 +351,6 @@
- \.generateKey\(
- null
- - - SecureRandom\(
- \.generateSecret\(|SecretKeySpec\(.*AES
- \.generateSecret\(|SecretKeySpec\(.{0,48}AES
- null
class: Optional Security Functional Requirements
@@ -46,7 +46,7 @@
modified by any application.
type: RegexAnd
pattern:
- \.loadUrl\(.*getExternalStorageDirectory\(
- \.loadUrl\(.{0,48}getExternalStorageDirectory\(
- webkit\.WebView
severity: high
input_case: exact
@@ -551,7 +551,7 @@
scheme is to prevent a number of attacks on RSA that only work when the
encryption is performed without padding.
type: Regex
pattern: Cipher\.getinstance\(\"rsa/.+/nopadding
pattern: Cipher\.getinstance\(\"rsa/.{1,48}/nopadding
severity: high
input_case: lower
metadata:
@@ -565,7 +565,7 @@
type: RegexOr
pattern:
- MODE_WORLD_WRITABLE
- 'openFileOutput\(\s*".+"\s*,\s*2\s*\)'
- 'openFileOutput\(\s*".{1,48}"\s*,\s*2\s*\)'
severity: high
input_case: exact
metadata:
@@ -579,7 +579,7 @@
type: RegexOr
pattern:
- MODE_WORLD_READABLE
- 'openFileOutput\(\s*".+"\s*,\s*1\s*\)'
- 'openFileOutput\(\s*".{1,48}"\s*,\s*1\s*\)'
severity: high
input_case: exact
metadata:
@@ -591,7 +591,7 @@
- id: android_world_read_write
message: The file is World Readable and Writable. Any App can read/write to the file
type: Regex
pattern: 'openFileOutput\(\s*".+"\s*,\s*3\s*\)'
pattern: 'openFileOutput\(\s*".{1,48}"\s*,\s*3\s*\)'
severity: high
input_case: exact
metadata:
@@ -605,8 +605,8 @@
type: RegexOr
input_case: exact
pattern:
- \.getInstance\(.*md4
- \.getInstance\(.*MD4
- \.getInstance\(.{0,48}md4
- \.getInstance\(.{0,48}MD4
severity: high
metadata:
cvss: 7.4
@@ -618,14 +618,14 @@
message: Weak Encryption algorithm used
input_case: exact
pattern:
- \.getInstance\(.*rc2
- \.getInstance\(.*RC2
- \.getInstance\(.*rc4
- \.getInstance\(.*RC4
- \.getInstance\(.*blowfish
- \.getInstance\(.*BLOWFISH
- Cipher\.getInstance\(.*DES
- Cipher\.getInstance\(.*des
- \.getInstance\(.{0,48}rc2
- \.getInstance\(.{0,48}RC2
- \.getInstance\(.{0,48}rc4
- \.getInstance\(.{0,48}RC4
- \.getInstance\(.{0,48}blowfish
- \.getInstance\(.{0,48}BLOWFISH
- Cipher\.getInstance\(.{0,48}DES
- Cipher\.getInstance\(.{0,48}des
severity: high
type: RegexOr
metadata:
@@ -638,8 +638,8 @@
message: The App uses the encryption mode CBC with PKCS5/PKCS7 padding. This configuration is vulnerable to padding oracle attacks.
input_case: exact
pattern:
- \.getInstance\(.*\/CBC\/PKCS5Padding
- \.getInstance\(.*\/CBC\/PKCS7Padding
- \.getInstance\(.{0,48}\/CBC\/PKCS5Padding
- \.getInstance\(.{0,48}\/CBC\/PKCS7Padding
severity: high
type: RegexOr
metadata:
@@ -652,8 +652,8 @@
message: MD5 is a weak hash known to have hash collisions.
input_case: exact
pattern:
- \.getInstance\(.*MD5
- \.getInstance\(.*md5
- \.getInstance\(.{0,48}MD5
- \.getInstance\(.{0,48}md5
- DigestUtils\.md5\(
severity: warning
type: RegexOr
@@ -667,10 +667,10 @@
message: SHA-1 is a weak hash known to have hash collisions.
input_case: exact
pattern:
- \.getInstance\(.*SHA-1
- \.getInstance\(.*sha-1
- \.getInstance\(.*SHA1
- \.getInstance\(.*sha1
- \.getInstance\(.{0,48}SHA-1
- \.getInstance\(.{0,48}sha-1
- \.getInstance\(.{0,48}SHA1
- \.getInstance\(.{0,48}sha1
- DigestUtils\.sha\(
severity: warning
type: RegexOr
@@ -726,7 +726,7 @@
passwords, keys etc.
input_case: lower
pattern: >-
(password\s*=\s*[\'|\"].+[\'|\"]\s{0,5})|(pass\s*=\s*[\'|\"].+[\'|\"]\s{0,5})|(username\s*=\s*[\'|\"].+[\'|\"]\s{0,5})|(secret\s*=\s*[\'|\"].+[\'|\"]\s{0,5})|(key\s*=\s*[\'|\"].+[\'|\"]\s{0,5})
(password\s*=\s*[\'|\"].{1,100}[\'|\"]\s{0,5})|(pass\s*=\s*[\'|\"].{1,100}[\'|\"]\s{0,5})|(username\s*=\s*[\'|\"].{1,100}[\'|\"]\s{0,5})|(secret\s*=\s*[\'|\"].{1,100}[\'|\"]\s{0,5})|(key\s*=\s*[\'|\"].{1,100}[\'|\"]\s{0,5})
severity: warning
type: Regex
metadata:
@@ -625,8 +625,9 @@ def get_app_name_from_file(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
data = f.read()
app_name_match = re.search(r'<string name=\"app_name\">(.*)</string>',
data)
app_name_match = re.search(
r'<string name=\"app_name\">(.{0,300})</string>',
data)
if (not app_name_match) or (len(app_name_match.group()) <= 0):
# Did not find app_name in current file.
@@ -25,7 +25,6 @@
- id: api_encryption
message: Encryption API
input_case: exact
severity: info
pattern: CommonCrypto|CryptoKit
type: Regex
severity: info
@@ -13,7 +13,7 @@
message: Files may contain hardcoded sensitive information like usernames,
passwords, keys etc.
input_case: lower
pattern: (password\s*=\s*[\'|\"].+[\'|\"]\s{0,5})|(pass\s*=\s*[\'|\"].+[\'|\"]\s{0,5})|(username\s*=\s*[\'|\"].+[\'|\"]\s{0,5})|(secret\s*=\s*[\'|\"].+[\'|\"]\s{0,5})|(key\s*=\s*[\'|\"].+[\'|\"]\s{0,5})
pattern: (password\s*=\s*[\'|\"].{1,100}[\'|\"]\s{0,5})|(pass\s*=\s*[\'|\"].{1,100}[\'|\"]\s{0,5})|(username\s*=\s*[\'|\"].{1,100}[\'|\"]\s{0,5})|(secret\s*=\s*[\'|\"].{1,100}[\'|\"]\s{0,5})|(key\s*=\s*[\'|\"].{1,100}[\'|\"]\s{0,5})
severity: high
type: Regex
metadata:
@@ -114,7 +114,7 @@
The App may contain banned API(s). These API(s) are insecure and must not be
used.
input_case: exact
pattern: '\s+(strcpy\(|memcpy\(|strcat\(|strncat\(|strncpy\(|sprintf\(|sprintf\(|gets\()'
pattern: '( strcpy\(| memcpy\(| strcat\(| strncat\(| strncpy\(| sprintf\(| sprintf\(| gets\()'
severity: high
type: Regex
metadata:
@@ -13,7 +13,7 @@
message: Files may contain hardcoded sensitive information like usernames,
passwords, keys etc.
input_case: lower
pattern: (password\s*=\s*[\'|\"].+[\'|\"]\s{0,5})|(pass\s*=\s*[\'|\"].+[\'|\"]\s{0,5})|(username\s*=\s*[\'|\"].+[\'|\"]\s{0,5})|(secret\s*=\s*[\'|\"].+[\'|\"]\s{0,5})|(key\s*=\s*[\'|\"].+[\'|\"]\s{0,5})
pattern: (password\s*=\s*[\'|\"].{1,100}[\'|\"]\s{0,5})|(pass\s*=\s*[\'|\"].{1,100}[\'|\"]\s{0,5})|(username\s*=\s*[\'|\"].{1,100}[\'|\"]\s{0,5})|(secret\s*=\s*[\'|\"].{1,100}[\'|\"]\s{0,5})|(key\s*=\s*[\'|\"].{1,100}[\'|\"]\s{0,5})
severity: high
type: Regex
metadata:
@@ -112,7 +112,7 @@
- id: ios_swift_log
message: The App logs information. Sensitive information should never be logged.
input_case: exact
pattern: (print|NSLog|os_log|OSLog|os_signpost)\(.*\)
pattern: (print|NSLog|os_log|OSLog|os_signpost)\(
severity: info
type: Regex
metadata:
@@ -192,7 +192,7 @@
- id: ios_custom_keyboard_disabled
message: This App may have custom keyboards disabled.
input_case: exact
pattern: extensionPointIdentifier == .*\.keyboard
pattern: extensionPointIdentifier == .{0,100}\.keyboard
severity: good
type: Regex
metadata:
@@ -254,18 +254,88 @@
cwe: ''
masvs: resilience-5
owasp-mobile: ''
- id: ios_biometric_bool
message: 'Biometric authentication should be based on iOS Keychain, not based on bool.'
- id: ios_biometry_hardened
message: 'Biometric authentication uses `.biometryCurrentSet`. This will remove data protected with this ACL from Keychain when device biometry is updated.'
input_case: exact
pattern: \.evaluatePolicy\(.deviceOwnerAuthentication
severity: warning
type: Regex
pattern:
- \.biometryCurrentSet
- SecAccessControlCreateWithFlags\(
severity: good
type: RegexAnd
metadata:
cvss: 0
cwe: ''
masvs: auth-8
owasp-mobile: m1
ref: https://github.com/MobSF/owasp-mstg/blob/master/Document/0x06f-Testing-Local-Authentication.md#local-authentication-framework
- id: ios_biometric_bool
message: 'Biometric authentication should be hardware and keychain backed, local authentication returns a boolean that can be bypassed by runtime instrumentation tools like Frida.'
input_case: exact
pattern:
- \.evaluatePolicy\(
- \.deviceOwnerAuthentication
- LAContext\(
severity: warning
type: RegexAnd
metadata:
cvss: 5
cwe: cwe-303
masvs: auth-8
owasp-mobile: m1
ref: https://github.com/MobSF/owasp-mstg/blob/master/Document/0x06f-Testing-Local-Authentication.md#local-authentication-framework
- id: ios_biometric_acl
message: Weak biometric ACL flag is associated with a key stored in Keychain. With `.biometryAny/.userPresence/.touchIDAny` flag, an attacker with the ability to add a biometry to the device can authenticate as the user. Use `.biometryCurrentSet/.touchIDCurrentSet` instead.
input_case: exact
pattern:
- \.biometryAny|\.userPresence|\.touchIDAny
- SecAccessControlCreateWithFlags\(
severity: high
type: RegexAnd
metadata:
cvss: 2
cwe: cwe-305
masvs: auth-8
owasp-mobile: m1
ref: https://github.com/MobSF/owasp-mstg/blob/master/Document/0x06f-Testing-Local-Authentication.md#local-authentication-framework
- id: ios_keychain_weak_acl_device_passcode
message: A key stored in the Keychain is not making use of stronger biometric backed ACL. Use `.biometryCurrentSet` instead.
input_case: exact
pattern:
- \.devicePasscode
- SecAccessControlCreateWithFlags\(
severity: warning
type: RegexAnd
metadata:
cvss: 2
cwe: cwe-305
masvs: auth-8
owasp-mobile: m1
ref: https://github.com/MobSF/owasp-mstg/blob/master/Document/0x06f-Testing-Local-Authentication.md
- id: ios_keychain_weak_accessibility_value
message: A key stored in the Keychain is using a weak accessibility value. Use stronger ACLs like `kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly/kSecAttrAccessibleWhenUnlocked/kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly`.
input_case: exact
pattern: kSecAttrAccessibleAlways|kSecAttrAccessibleAfterFirstUnlock
severity: warning
type: Regex
metadata:
cvss: 1
cwe: cwe-305
masvs: auth-8
owasp-mobile: m1
ref: https://github.com/MobSF/owasp-mstg/blob/master/Document/0x06f-Testing-Local-Authentication.md
- id: ios_insecure_random_no_generator
message: The App uses an insecure Random Number Generator.
input_case: exact
pattern: ((Int|Bool|Float|Double)\.random\()|arc4random.{0,10}\(|SystemRandomNumberGenerator\(|rand\(| random\(
severity: warning
type: Regex
metadata:
cvss: 2.0
input_case: exact
cwe: cwe-330
owasp-mobile: m5
masvs: crypto-6
ref: https://github.com/MobSF/owasp-mstg/blob/master/Document/0x04g-Testing-Cryptography.md#weak-random-number-generators
- id: ios_file_no_special
message: The file has no special protections associated with it.
input_case: exact
@@ -400,7 +470,7 @@
- id: ios_open_urls
message: Opening App with URLs can lead to potential security leaks.
input_case: exact
pattern: 'func application\(.*open url: URL'
pattern: 'func application\(.{0,48}open url: URL'
severity: warning
type: Regex
metadata:
+1 -1
View File
@@ -179,7 +179,7 @@ def tools_binskim():
# Search for the version number
folder = re.search(
b'Microsoft\\.CodeAnalysis\\.BinSkim\\..*(\'|\") ', output)
b'Microsoft\\.CodeAnalysis\\.BinSkim\\..{0,300}(\'|\") ', output)
try:
# Substring-Foo for removing b'X's in python3
if sys.version_info.major == 3:
+1 -1
View File
@@ -225,7 +225,7 @@
// Is valid file extensions
function isValidExt(file_name){
var val = file_name.toLowerCase();
var regex = new RegExp("(.*?)\.(ipa|apk|apks|xapk|jar|aar|zip|appx)$");
var regex = new RegExp("^(.{1,300}?)\.(ipa|apk|apks|xapk|jar|aar|zip|appx)$");
val = val.replace(/^.*[\\\/]/, '');
if (!(regex.test(val))) {
_('status').innerText = "Please upload APK/APKS/XAPK/JAR/AAR/IPA/ZIP/APPX only!";