Skip to content

Commit

Permalink
Merge pull request #78 from CybercentreCanada/bugfix/regression
Browse files Browse the repository at this point in the history
Fix bug with generating metadata for all rules within rules file
  • Loading branch information
cccs-rs authored May 7, 2024
2 parents 620d31d + dd87bf2 commit 63a019b
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 5 deletions.
42 changes: 42 additions & 0 deletions pipelines/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: tests

trigger: ["*"]
pr: ["*"]

pool:
vmImage: "ubuntu-20.04"

jobs:
- job: run_test
strategy:
matrix:
Python3_8:
python.version: "3.8"
Python3_9:
python.version: "3.9"
Python3_10:
python.version: "3.10"
Python3_11:
python.version: "3.11"
Python3_12:
python.version: "3.12"

timeoutInMinutes: 10

steps:
- task: UsePythonVersion@0
displayName: Set python version
inputs:
versionSpec: "$(python.version)"
- script: |
[ ! -d "$(pwd)/tests" ] && echo "No tests found" && exit
[ -f $(pwd)/requirements.txt ] && sudo env "PATH=$PATH" python -m pip install -U --no-cache-dir -r $(pwd)/requirements.txt
[ -f $(pwd)/tests/requirements.txt ] && sudo env "PATH=$PATH" python -m pip install -U --no-cache-dir -r $(pwd)/tests/requirements.txt
sudo rm -rf /tmp/* /var/lib/apt/lists/* ~/.cache/pip
displayName: Setup environment
- script: |
[ ! -d "$(pwd)/tests" ] && echo "No tests found" && exit
export REPO_NAME=${BUILD_REPOSITORY_NAME##*/}
python -m pytest -p no:cacheprovider --durations=10 -rsx -vv
displayName: Test
1 change: 1 addition & 0 deletions tests/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pytest
64 changes: 64 additions & 0 deletions tests/test_run_yara_validator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from tempfile import NamedTemporaryFile

from yara_validator.validator import run_yara_validator

RULES = b"""
rule x
{
meta:
version = "1.0"
score = "0"
minimum_yara = "3.5"
date = "2024-05-07"
modified = "2024-05-07"
status = "RELEASED"
sharing = "TLP:CLEAR"
author = "CCCS"
description = "Fake rule for testing"
category = "TOOL"
tool = "exemplar"
source = "CCCS"
strings:
$ = "x"
condition:
all of them
}
rule y
{
meta:
version = "1.0"
score = "0"
minimum_yara = "3.5"
date = "2024-05-07"
modified = "2024-05-07"
status = "RELEASED"
sharing = "TLP:CLEAR"
author = "CCCS"
description = "Fake rule for testing"
category = "TOOL"
tool = "exemplar"
source = "CCCS"
strings:
$ = "y"
condition:
all of them
}
"""

def test_required_fields():
# Bug: Metadata generation only worked on the first rule within a ruleset
with NamedTemporaryFile() as tf:
tf.write(RULES)
tf.seek(0)

for rule in run_yara_validator(tf.name, generate_values=True).yara_rules:
fingerprint, id = None, None
for m in rule.rule_plyara['metadata']:
if 'id' in m:
id = m['id']
elif 'fingerprint' in m:
fingerprint = m['fingerprint']

# Ensure the fingerprint and the id metadata fields were generated for all rules
assert fingerprint and id
14 changes: 9 additions & 5 deletions yara_validator/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def run_yara_validator(yara_file, generate_values=True, check_import_modules=Tru
.format(str(validator_configuration.get(STRING_ENCODING).get(VALUE)))
yara_file_processor.update_file_error(True, str(yara_file_processor.original_rule_file.name), file_response)
return yara_file_processor

with open(CONFIG_VALUES_YAML_PATH, 'r', encoding='utf8') as yaml_file:
scheme = yaml.safe_load(yaml_file)

Expand All @@ -150,10 +150,8 @@ def run_yara_validator(yara_file, generate_values=True, check_import_modules=Tru

for rule in yara_file_processor.yara_rules:
try:
validator.reset()
rule.add_rule_return(validator.validation(rule.rule_plyara, rule.rule_string, generate_values))
# reset the counter here since we are evaluating 'per rule'
for key, value in validator.required_fields.items():
validator.required_fields_index[value.position].count = 0
except Exception as e:
raise Exception(
f"{rule.rule_plyara.get('rule_name', None)} produced the following exception: {str(e)}. Halting validation..")
Expand Down Expand Up @@ -419,6 +417,13 @@ def __init__(self, stix_data_path, validator_yaml, validator_yaml_values, yara_c

previous_position_values = None

def reset(self):
# Reset back to factory settings for required field validation
for value in self.required_fields.values():
self.required_fields_index[value.position].count = 0
value.found = False
value.valid = False

def reindex_metadata_keys(self):
"""
Reindex the starting index of the positional objects contained in self.required_fields_index. This is so that
Expand Down Expand Up @@ -910,4 +915,3 @@ def import_yara_cfg(self):
# check if any metadata in child-parent relationship are missing
self.validate_child_parent_metadata(self.yara_config, metadata_in_child_parent_relationship)
self.metadata_keys_regex = self.metadata_keys_regex[:-1]

0 comments on commit 63a019b

Please sign in to comment.