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
2 changes: 1 addition & 1 deletion requirements-qa.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ pytest==7.4.3
pytest-openfiles==0.5.0
pytest-random-order==1.1.0
bump-my-version==0.17.3
setuptools==70.0.0
setuptools==78.1.1
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ azure-monitor-query==1.4.1
splunk-sdk==2.0.1
colorama==0.4.6
python-json-logger==2.0.7
requests==2.32.3
requests==2.32.4
elasticsearch==8.14.0
2 changes: 1 addition & 1 deletion src/droid/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def init_argparse() -> argparse.ArgumentParser:
parser.add_argument("-p", "--platform", help="Platform target", choices=["splunk", "microsoft_sentinel", "microsoft_xdr", "esql", "eql"])
parser.add_argument("-sx", "--sentinel-xdr", help="Use Microsoft Sentinel as a search head for Microsoft XDR", action="store_true")
parser.add_argument("-u", "--update", help="Update from source", choices=["sigmahq-core"])
parser.add_argument("-l", "--list", help="List items from rules", choices=["unique_fields", "pipelines"])
parser.add_argument("-l", "--list", help="List items from rules", choices=["unique_fields", "pipelines", "validators"])
parser.add_argument("-m", "--mssp", help="Enable MSSP mode", action="store_true")
parser.add_argument("-mo", "--module", help="Module mode to return converted rules as a list", action="store_true")
parser.add_argument("-j", "--json", help="Drop a JSON log file", action="store_true")
Expand Down
11 changes: 10 additions & 1 deletion src/droid/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,13 @@ def list_keys(parameters, logger_param) -> None:
plugins = InstalledSigmaPlugins.autodiscover()
pipeline_resolver = plugins.get_pipeline_resolver()
pipeline_list = list(pipeline_resolver.pipelines.keys())
print(*pipeline_list, sep='\n')
print(*pipeline_list, sep='\n')

elif 'validators' in parameters.list:
plugins = InstalledSigmaPlugins.autodiscover()
validators = plugins.validators
if validators:
validator_names = list(validators.keys())
print(*sorted(validator_names), sep='\n')
else:
print("No validators found in installed pySigma plugins")
42 changes: 39 additions & 3 deletions src/droid/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,48 @@ def __init__(self, base_config, logger_param) -> None:

self.logger.debug("Initializing droid.validate.SigmaValidation")

def validators(self) -> None:
return InstalledSigmaPlugins.autodiscover().validators
def get_installed_validators(self) -> dict:
"""Get all installed validators from pySigma plugins.

This method autodiscovers validators from installed pySigma plugins,
similar to how backends and pipelines are discovered.

Returns:
dict: A dictionary of validator names to validator classes.
"""
plugins = InstalledSigmaPlugins.autodiscover()
validators = plugins.validators
self.logger.debug(f"Discovered {len(validators)} validators from installed plugins")
return validators

def list_validators(self) -> list:
"""List all available validator names.

Returns:
list: A list of validator names.
"""
validators = self.get_installed_validators()
validator_names = list(validators.keys())
self.logger.debug(f"Available validators: {validator_names}")
return validator_names

def init_validator(self) -> None:
"""Initialize the SigmaValidator with installed validators.

Loads the validation configuration from the YAML file and initializes
the SigmaValidator with all autodiscovered validators from pySigma plugins.
"""
validators = self.get_installed_validators()

if validators:
self.logger.info(f"Loaded {len(validators)} validators from installed pySigma plugins")
for validator_name in validators:
self.logger.debug(f" - {validator_name}")
else:
self.logger.warning("No validators discovered from installed pySigma plugins")

with open(self._validation_config_path) as validation_config:
self._rule_validator = SigmaValidator.from_yaml(validation_config.read(), self.validators())
self._rule_validator = SigmaValidator.from_yaml(validation_config.read(), validators)

def init_sigma_rule(self, rule, rule_file) -> None:
try:
Expand Down