Skip to content
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
14 changes: 3 additions & 11 deletions requirements/prod.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1668,14 +1668,6 @@ jsonschema-specifications==2025.9.1 \
drf-spectacular-sidecar==2026.3.1 \
--hash=sha256:5b7fedad66e3851f2f442480792c08115d79217959d01645b93d3d2258938be1 \
--hash=sha256:864edb83e022e13e3941c325c3cc0c954c843fa2e1d0bc95e81887664b2d3dad
yara-x==1.14.0 \
--hash=sha256:0ab8b94caa6596ac72b7e0c9e91b8c053b18361b215f3dafe4d8261cbfb033a1 \
--hash=sha256:4a1d6753ec52877ae136f11e32461d0d773844611f8761f8df7e8ff4197dcccf \
--hash=sha256:52a0a943aa3bbf68a0ed9482ae19056021f92e8a197e96008c7cf7cf2c6cf921 \
--hash=sha256:55f96cf0c3a87ff0f691ad6646bb6c973ad2990cc920fee67a25b65864785a11 \
--hash=sha256:60e9bea642a41af74416ba93feeee9fa08f94787f9ea4ff3706aa1a7791e2afa \
--hash=sha256:63264ca7814fed17303b641ebe2ff59924e73df62876ec06d5b31307e7b45adc \
--hash=sha256:7e0bec7248480296e76d4c7cd1666380c847e7db93d7abd957d8ff994e3f31bf \
--hash=sha256:dbae6139cbc4e03c9e2bc6bdc76bc26d55719a5cbf2e05eb93afa1e91a27d96b \
--hash=sha256:e4686bfa0f57b8e77a94c5e0a8dbab56b76fc45d7e4a6524c7adb81a1316f00a \
--hash=sha256:ec43a67f2d52ac06ae390a204ac5bde9a68a9d756521f9fec0274ae3080717f6
# our own fork of yara-x
https://github.com/mozilla/yara-x/releases/download/2026.03.30/yara_x-1.14.0-cp38-abi3-manylinux_2_34_x86_64.whl \
--hash=sha256:7373882d4865b20ee301ec968b9425e6ee2619fc5753af3520fccfd790586b9c
20 changes: 17 additions & 3 deletions src/olympia/scanners/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
)
from olympia.devhub.tasks import validation_task
from olympia.files.models import FileManifest, FileUpload
from olympia.files.utils import SafeZip
from olympia.files.utils import ManifestJSONExtractor, SafeZip
from olympia.versions.models import Version

from .models import (
Expand Down Expand Up @@ -523,6 +523,8 @@ def _run_yara_for_path(scanner_result, path, definition=None):
# override them later when matching.
externals = ScannerRule.get_yara_externals()

zip_file = SafeZip(source=path, ignore_filename_errors=True)

if waffle.switch_is_active('use-yara-x'):
compiler = yara_x.Compiler()
# Initialize the global variables (externals).
Expand All @@ -533,6 +535,19 @@ def _run_yara_for_path(scanner_result, path, definition=None):
# Create a scanner instance so that we can override the externals
# per file (in the `_scan()` function).
scanner = yara_x.Scanner(compiler.build())
options = yara_x.ScanOptions()
options.set_module_metadata(
'amo',
json.dumps(
{
'manifest': (
ManifestJSONExtractor(zip_file.read('manifest.json')).data
if zip_file.exists('manifest.json')
else {}
)
}
).encode('utf-8'),
)

def _scan(data, externals):
for k, v in externals.items():
Expand All @@ -549,7 +564,7 @@ def _scan(data, externals):
meta=dict(match.metadata),
tags=match.tags,
)
for match in scanner.scan(data).matching_rules
for match in scanner.scan_with_options(data, options).matching_rules
]

else:
Expand All @@ -558,7 +573,6 @@ def _scan(data, externals):
def _scan(data, externals):
return rules.match(data=data, externals=externals)

zip_file = SafeZip(source=path, ignore_filename_errors=True)
for zip_info in zip_file.info_list:
if not zip_info.is_dir():
file_content = zip_file.read(zip_info)
Expand Down
28 changes: 27 additions & 1 deletion src/olympia/scanners/tests/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1746,7 +1746,33 @@ def test_run_in_binary_mode(self):

@override_switch(name='use-yara-x', active=True)
class TestRunYaraX(TestRunYara):
pass
def test_amo_module(self):
self.upload = self.get_upload('webextension.xpi')
rule = ScannerRule.objects.create(
name='match_id',
scanner=YARA,
definition="""
import "amo"

rule match_id {
condition:
amo.manifest.get_value("$.applications.gecko.id") == "@webextension-guid"
and not is_manifest_file
}
""",
)

run_yara(self.results, self.upload.pk)

yara_results = ScannerResult.objects.all()
yara_result = yara_results[0]
assert yara_result.upload == self.upload
assert len(yara_result.results) == 1
assert yara_result.results[0] == {
'rule': rule.name,
'tags': [],
'meta': {'filename': 'index.js'},
}


class TestRunQueryRuleMixin:
Expand Down
Loading