Skip to content

Commit 25c4322

Browse files
authored
Merge pull request #81 from MobSF/march2024
[SECURITY] Fix SSRF in applink check, dependency update.
2 parents e29e85c + 61fd40b commit 25c4322

File tree

5 files changed

+109
-34
lines changed

5 files changed

+109
-34
lines changed

Pipfile.lock

Lines changed: 29 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mobsfscan/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
__title__ = 'mobsfscan'
77
__authors__ = 'Ajin Abraham'
88
__copyright__ = f'Copyright {datetime.now().year} Ajin Abraham, OpenSecurity'
9-
__version__ = '0.3.6'
9+
__version__ = '0.3.7'
1010
__version_info__ = tuple(int(i) for i in __version__.split('.'))
1111
__all__ = [
1212
'__title__',

mobsfscan/manifest.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111

1212
from mobsfscan.logger import init_logger
1313
from mobsfscan.manifest_metadata import metadata
14-
14+
from mobsfscan.utils import (
15+
is_number,
16+
valid_host,
17+
)
1518

1619
logger = init_logger(__name__)
1720
ANDROID_8_0_LEVEL = 26
@@ -50,6 +53,7 @@
5053
'32': '12L',
5154
'33': '13',
5255
'34': '14',
56+
'35': '15',
5357
}
5458

5559

@@ -349,9 +353,14 @@ def assetlinks_check(self, intent):
349353
port = applink.get('@android:port')
350354
scheme = applink.get('@android:scheme')
351355
# Collect possible well-known paths
352-
if scheme and scheme in ('http', 'https') and host:
353-
host = host.replace('*.', '')
354-
if port:
356+
if (scheme
357+
and scheme in ('http', 'https')
358+
and host
359+
and host != '*'):
360+
host = host.replace('*.', '').replace('#', '')
361+
if not valid_host(host):
362+
continue
363+
if port and is_number(port):
355364
c_url = f'{scheme}://{host}:{port}{well_known_path}'
356365
else:
357366
c_url = f'{scheme}://{host}{well_known_path}'

mobsfscan/utils.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# -*- coding: utf_8 -*-
22
"""Logger Config."""
3+
import socket
4+
import unicodedata
5+
from urllib.parse import urlparse
36
from pathlib import Path
47

58
import mobsfscan.settings as config
@@ -112,3 +115,59 @@ def get_best_practices(extension):
112115
all_rules[rule['id']] = rule
113116
ids.add(rule['id'])
114117
return ids, all_rules
118+
119+
120+
def is_number(s):
121+
if not s:
122+
return False
123+
if s == 'NaN':
124+
return False
125+
try:
126+
float(s)
127+
return True
128+
except ValueError:
129+
pass
130+
try:
131+
unicodedata.numeric(s)
132+
return True
133+
except (TypeError, ValueError):
134+
pass
135+
return False
136+
137+
138+
def valid_host(host):
139+
"""Check if host is valid."""
140+
try:
141+
prefixs = ('http://', 'https://')
142+
if not host.startswith(prefixs):
143+
host = f'http://{host}'
144+
parsed = urlparse(host)
145+
domain = parsed.netloc
146+
path = parsed.path
147+
if len(domain) == 0:
148+
# No valid domain
149+
return False
150+
if len(path) > 0:
151+
# Only host is allowed
152+
return False
153+
if ':' in domain:
154+
# IPv6
155+
return False
156+
# Local network
157+
invalid_prefix = (
158+
'127.',
159+
'192.',
160+
'10.',
161+
'172.',
162+
'169',
163+
'0.',
164+
'localhost')
165+
if domain.startswith(invalid_prefix):
166+
return False
167+
ip = socket.gethostbyname(domain)
168+
if ip.startswith(invalid_prefix):
169+
# Resolve dns to get IP
170+
return False
171+
return True
172+
except Exception:
173+
return False

requirements.txt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
attrs==21.4.0
22
boltons==21.0.0
33
bracex==2.4
4-
certifi==2023.11.17
4+
certifi==2024.2.2
55
charset-normalizer==3.3.2
66
click==8.1.7
77
click-option-group==0.5.6
@@ -11,13 +11,13 @@ face==22.0.0
1111
glom==22.1.0
1212
idna==3.6
1313
jschema-to-python==1.2.3
14-
jsonpickle==3.0.2
14+
jsonpickle==3.0.3
1515
jsonschema==4.17.3
1616
libsast==2.0.3
1717
packaging==21.3
1818
pbr==6.0.0
19-
peewee==3.17.0
20-
pyparsing==3.1.1
19+
peewee==3.17.1
20+
pyparsing==3.1.2
2121
pyrsistent==0.20.0
2222
python-lsp-jsonrpc==1.0.0
2323
PyYAML==6.0.1
@@ -28,9 +28,9 @@ sarif-om==1.0.4
2828
semgrep==0.117.0
2929
tabulate==0.9.0
3030
tomli==2.0.1
31-
tqdm==4.66.1
32-
typing_extensions==4.9.0
31+
tqdm==4.66.2
32+
typing_extensions==4.10.0
3333
ujson==5.9.0
3434
urllib3==1.26.18
35-
wcmatch==8.5
35+
wcmatch==8.5.1
3636
xmltodict==0.13.0

0 commit comments

Comments
 (0)