Skip to content

Commit c886ea5

Browse files
committed
DjangoQ2 Scan Queue QA + Updated defaults
1 parent a5c30c0 commit c886ea5

File tree

6 files changed

+67
-47
lines changed

6 files changed

+67
-47
lines changed

mobsf/MobSF/settings.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -345,8 +345,8 @@
345345
ASYNC_ANALYSIS_TIMEOUT = int(os.getenv('MOBSF_ASYNC_ANALYSIS_TIMEOUT', '60'))
346346
Q_CLUSTER = {
347347
'name': 'scan_queue',
348-
'workers': int(os.getenv('MOBSF_ASYNC_WORKERS', 3)),
349-
'recycle': 5,
348+
'workers': int(os.getenv('MOBSF_ASYNC_WORKERS', '2')),
349+
'recycle': 100,
350350
'timeout': ASYNC_ANALYSIS_TIMEOUT * 60,
351351
'retry': (ASYNC_ANALYSIS_TIMEOUT * 60) + 100,
352352
'compress': True,

mobsf/StaticAnalyzer/views/android/apk.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@
7676
)
7777
from mobsf.StaticAnalyzer.views.common.async_task import (
7878
async_analysis,
79-
enqueued_task_init,
80-
update_enqueued_task,
79+
mark_task_completed,
80+
mark_task_started,
8181
)
8282
from mobsf.MobSF.views.authorization import (
8383
Permissions,
@@ -148,7 +148,7 @@ def apk_analysis_task(checksum, app_dic, rescan, queue=False):
148148
try:
149149
if queue:
150150
settings.ASYNC_ANALYSIS = True
151-
enqueued_task_init(checksum)
151+
mark_task_started(checksum)
152152
append_scan_status(checksum, 'init')
153153
get_size_and_hashes(app_dic)
154154
msg = 'Extracting APK'
@@ -232,12 +232,12 @@ def apk_analysis_task(checksum, app_dic, rescan, queue=False):
232232
rescan,
233233
)
234234
if queue:
235-
return update_enqueued_task(
235+
return mark_task_completed(
236236
checksum, app_dic['subject'], 'Success')
237237
return context, None
238238
except Exception as exp:
239239
if queue:
240-
return update_enqueued_task(
240+
return mark_task_completed(
241241
checksum, 'Failed', repr(exp))
242242
return context, repr(exp)
243243
finally:
@@ -288,7 +288,7 @@ def src_analysis_task(checksum, app_dic, rescan, pro_type, queue=False):
288288
try:
289289
if queue:
290290
settings.ASYNC_ANALYSIS = True
291-
enqueued_task_init(checksum)
291+
mark_task_started(checksum)
292292
cert_dic = {
293293
'certificate_info': '',
294294
'certificate_status': '',
@@ -353,11 +353,11 @@ def src_analysis_task(checksum, app_dic, rescan, pro_type, queue=False):
353353
rescan,
354354
)
355355
if queue:
356-
return update_enqueued_task(
356+
return mark_task_completed(
357357
checksum, app_dic['subject'], 'Success')
358358
except Exception as exp:
359359
if queue:
360-
return update_enqueued_task(
360+
return mark_task_completed(
361361
checksum, 'Failed', repr(exp))
362362
return context
363363

mobsf/StaticAnalyzer/views/android/icon_analysis.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ def get_icon_apk_res(app_dic):
190190
icon_src = icon_name
191191

192192
if icon_name and icon_name.endswith('.xml'):
193+
# Handle XML icon case
193194
apktool_res = False
194195
# Can be vector XML/XML pointing to vector files
195196
# Convert AXML to XML for vector
@@ -216,10 +217,11 @@ def get_icon_apk_res(app_dic):
216217
else:
217218
# if we cannot find from xml
218219
icon_src = guess_icon_path(str(res_path))
219-
else:
220+
elif icon_name:
220221
# We found png icon, the easy path
221222
icon_src = (app_dir / icon_name).as_posix()
222223

224+
# Log warning if correct icon is not found
223225
if icon_src.endswith('.xml'):
224226
logger.warning('Cannot find icon file from xml')
225227
icon_src = ''

mobsf/StaticAnalyzer/views/common/async_task.py

+42-25
Original file line numberDiff line numberDiff line change
@@ -48,35 +48,52 @@ def detect_timeout(sender, task, **kwargs):
4848

4949
def async_analysis(checksum, api, file_name, func, *args, **kwargs):
5050
"""Async Analysis Task."""
51-
# Check if the task is already completed
51+
# Check if the scan is already completed and successful
52+
scan_completed = False
5253
recent = RecentScansDB.objects.filter(MD5=checksum)
53-
scan_completed = recent[0].APP_NAME or recent[0].PACKAGE_NAME
54-
# Check if the task is updated within the last 60 minutes
55-
active_recently = recent[0].TIMESTAMP >= timezone.now() - timedelta(
56-
minutes=settings.ASYNC_ANALYSIS_TIMEOUT)
54+
if recent.exists() and (recent[0].APP_NAME or recent[0].PACKAGE_NAME):
55+
# Successful scan will have APP_NAME or PACKAGE_NAME
56+
scan_completed = True
57+
# Check if task is already completed within the last 60 minutes
58+
# Can be success or failed
59+
completed_at_recently = EnqueuedTask.objects.filter(
60+
checksum=checksum,
61+
completed_at__gte=timezone.now() - timedelta(
62+
minutes=settings.ASYNC_ANALYSIS_TIMEOUT),
63+
).exists()
64+
5765
# Check if the task is already enqueued within the last 60 minutes
5866
queued_recently = EnqueuedTask.objects.filter(
5967
checksum=checksum,
6068
created_at__gte=timezone.now() - timedelta(
6169
minutes=settings.ASYNC_ANALYSIS_TIMEOUT),
6270
).exists()
71+
# Check if the task is already started within the last 60 minutes
72+
started_at_recently = EnqueuedTask.objects.filter(
73+
checksum=checksum,
74+
started_at__gte=timezone.now() - timedelta(
75+
minutes=settings.ASYNC_ANALYSIS_TIMEOUT),
76+
).exists()
6377

64-
# Additional checks on recent queue
65-
if queued_recently:
66-
if scan_completed:
67-
# scan already completed recently
68-
msg = 'Analysis already completed in the last 60 minutes'
69-
logger.warning(msg)
70-
if api:
71-
return {'task_id': None, 'message': msg}
72-
return HttpResponseRedirect('/tasks?q=completed')
73-
elif active_recently:
74-
# scan not completed but active recently
75-
msg = 'Analysis already enqueued in the last 60 minutes'
76-
logger.warning(msg)
77-
if api:
78-
return {'task_id': None, 'message': msg}
79-
return HttpResponseRedirect('/tasks?q=queued')
78+
# Prevent duplicate scans in the last 60 minutes
79+
if scan_completed and completed_at_recently:
80+
# scan task already completed with success/failure recently
81+
msg = ('Analysis already completed/failed in the '
82+
f'last {settings.ASYNC_ANALYSIS_TIMEOUT} minutes. '
83+
'Please try again later.')
84+
logger.warning(msg)
85+
if api:
86+
return {'task_id': None, 'message': msg}
87+
return HttpResponseRedirect('/tasks?q=completed')
88+
elif queued_recently or started_at_recently:
89+
# scan not completed but queued or started recently
90+
msg = ('Analysis already enqueued in the '
91+
f'last {settings.ASYNC_ANALYSIS_TIMEOUT} minutes. '
92+
'Please wait for the current scan to complete.')
93+
logger.warning(msg)
94+
if api:
95+
return {'task_id': None, 'message': msg}
96+
return HttpResponseRedirect('/tasks?q=queued')
8097

8198
# Clear old tasks
8299
queue_size = settings.QUEUE_MAX_SIZE
@@ -108,15 +125,15 @@ def async_analysis(checksum, api, file_name, func, *args, **kwargs):
108125
return HttpResponseRedirect('/tasks')
109126

110127

111-
def enqueued_task_init(checksum):
112-
"""Store Task start."""
128+
def mark_task_started(checksum):
129+
"""Register the enqued task and others that matches the checksum as started."""
113130
EnqueuedTask.objects.filter(checksum=checksum).update(
114131
started_at=timezone.now(),
115132
)
116133

117134

118-
def update_enqueued_task(checksum, app_name, status):
119-
"""Update the Enqueued Task and others that matches the checksum."""
135+
def mark_task_completed(checksum, app_name, status):
136+
"""Update the enqueued task and others that matches the checksum as completed."""
120137
EnqueuedTask.objects.filter(checksum=checksum).update(
121138
app_name=app_name[:254],
122139
completed_at=timezone.now(),

mobsf/StaticAnalyzer/views/ios/ipa.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@
5555
)
5656
from mobsf.StaticAnalyzer.views.common.async_task import (
5757
async_analysis,
58-
enqueued_task_init,
59-
update_enqueued_task,
58+
mark_task_completed,
59+
mark_task_started,
6060
)
6161
from mobsf.MalwareAnalyzer.views.MalwareDomainCheck import (
6262
MalwareDomainCheck,
@@ -170,7 +170,7 @@ def ipa_analysis_task(checksum, app_dic, rescan, queue=False):
170170
try:
171171
if queue:
172172
settings.ASYNC_ANALYSIS = True
173-
enqueued_task_init(checksum)
173+
mark_task_started(checksum)
174174
append_scan_status(checksum, 'init')
175175
msg = 'iOS Binary (IPA) Analysis Started'
176176
logger.info(msg)
@@ -181,11 +181,12 @@ def ipa_analysis_task(checksum, app_dic, rescan, queue=False):
181181
msg = ('IPA is malformed! MobSF cannot find Payload directory')
182182
append_scan_status(checksum, 'IPA is malformed', msg)
183183
if queue:
184-
return update_enqueued_task(
184+
return mark_task_completed(
185185
checksum, 'Failed', msg)
186186
return context, msg
187-
common_analysis('ipa', app_dic, checksum)
188187

188+
# Common Analysis
189+
common_analysis('ipa', app_dic, checksum)
189190
# IPA Binary Analysis
190191
bin_dict = binary_analysis(
191192
checksum,
@@ -224,12 +225,12 @@ def ipa_analysis_task(checksum, app_dic, rescan, queue=False):
224225
rescan)
225226
if queue:
226227
subject = get_scan_subject(app_dic, bin_dict)
227-
return update_enqueued_task(
228+
return mark_task_completed(
228229
checksum, subject, 'Success')
229230
return context, None
230231
except Exception as exp:
231232
if queue:
232-
return update_enqueued_task(
233+
return mark_task_completed(
233234
checksum, 'Failed', repr(exp))
234235
return context, repr(exp)
235236

@@ -275,7 +276,7 @@ def ios_analysis_task(checksum, app_dic, rescan, queue=False):
275276
try:
276277
if queue:
277278
settings.ASYNC_ANALYSIS = True
278-
enqueued_task_init(checksum)
279+
mark_task_started(checksum)
279280
logger.info('iOS Source Code Analysis Started')
280281
get_size_and_hashes(app_dic)
281282

@@ -316,11 +317,11 @@ def ios_analysis_task(checksum, app_dic, rescan, queue=False):
316317
rescan)
317318
if queue:
318319
subject = get_scan_subject(app_dic, bin_dict)
319-
return update_enqueued_task(
320+
return mark_task_completed(
320321
checksum, subject, 'Success')
321322
except Exception as exp:
322323
if queue:
323-
return update_enqueued_task(
324+
return mark_task_completed(
324325
checksum, 'Failed', repr(exp))
325326
return context
326327

mobsf/templates/general/tasks.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ <h3 class="box-title"><i class="fa fa-rocket"></i> Scan Queue</h3>
275275
if (q && q === 'completed') {
276276
Swal.fire(
277277
'Scan Task Recently Completed!',
278-
'The scan was recently completed.',
278+
'The scan was recently processed.',
279279
'warning'
280280
)
281281
} else if (q && q === 'queued') {

0 commit comments

Comments
 (0)