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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/new_meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ body:
- type: textarea
attributes:
label: Tasking
value: "\n### Meta Tasks\n- [ ] Provide Week 1 Update Comment\n- [ ] Provide Week 2 Update or Closeout Comment\n"
value: "```[tasklist]\n### Meta Tasks\n- [ ] Provide Week 1 Update Comment\n- [ ] Provide Week 2 Update or Closeout Comment\n```"
render:

- type: textarea
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/attack-coverage-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
git add docs-dev/"ATT\&CK-coverage.md"

- name: Create Pull Request
uses: peter-evans/create-pull-request@6cd32fd93684475c31847837f87bb135d40a2b79 # v7.0.3
uses: peter-evans/create-pull-request@v7.0.3
with:
assignees: '${{github.actor}}'
delete-branch: true
Expand Down
23 changes: 0 additions & 23 deletions .github/workflows/docs-build.yml

This file was deleted.

14 changes: 0 additions & 14 deletions .github/workflows/docs-cleanup.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/kibana-mitre-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:

- name: Get MITRE Attack changed files
id: changed-attack-files
uses: tj-actions/changed-files@2f7c5bfce28377bc069a65ba478de0a74aa0ca32 # v46.0.1
uses: tj-actions/changed-files@v44
with:
files: detection_rules/etc/attack-v*.json.gz

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lock-versions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
description: 'List of branches to lock versions (ordered, comma separated)'
required: true
# 7.17 was intentionally skipped because it was added late and was bug fix only
default: '8.14,8.15,8.16,8.17,8.18,9.0'
default: '8.12,8.13,8.14,8.15,8.16,8.17'

jobs:
pr:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Unit Tests

on:
push:
branches: [ "main", "7.*", "8.*", "9.*" ]
branches: [ "main", "7.*", "8.*" ]
pull_request:
branches: [ "*" ]

Expand Down
1 change: 0 additions & 1 deletion .github/workflows/react-tests-dispatcher.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ on:
- '!rules/integrations/o365/*.toml'
- '!rules/integrations/okta/*.toml'
- '!rules/integrations/problemchild/*.toml'
- '!rules/integrations/pad/*.toml'

jobs:
dispatch:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/version-code-and-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
git push origin "dev-v$version"

- name: Run Release Drafter
uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6.1.0
uses: release-drafter/release-drafter@v6
with:
config-name: release-drafter.yml
env:
Expand Down
4 changes: 1 addition & 3 deletions CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,6 @@ Options:
-e, --overwrite-exceptions Overwrite exceptions in existing rules
-ac, --overwrite-action-connectors
Overwrite action connectors in existing rules
-nt, --no-tactic-filename Allow rule filenames without tactic prefix. Use this if rules have been exported with this flag.
-h, --help Show this message and exit.
```

Expand Down Expand Up @@ -482,7 +481,7 @@ Options:

### Exporting rules

This command should be run with the `CUSTOM_RULES_DIR` envvar set, that way proper validation is applied to versioning when the rules are downloaded. See the [custom rules docs](docs-dev/custom-rules-management.md) for more information.
This command should be run with the `CUSTOM_RULES_DIR` envvar set, that way proper validation is applied to versioning when the rules are downloaded. See the [custom rules docs](docs-dev/custom-rules.md) for more information.

```
python -m detection_rules kibana export-rules -h
Expand Down Expand Up @@ -521,7 +520,6 @@ Options:
-e, --export-exceptions Include exceptions in export
-s, --skip-errors Skip errors when exporting rules
-sv, --strip-version Strip the version fields from all rules
-nt, --no-tactic-filename Exclude tactic prefix in exported filenames for rules. Use same flag for import-rules to prevent warnings and disable its unit test.
-h, --help Show this message and exit.

```
Expand Down
27 changes: 12 additions & 15 deletions detection_rules/cli_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
dict_filter)
from .schemas import definitions
from .utils import clear_caches, rulename_to_filename
from .config import parse_rules_config

RULES_CONFIG = parse_rules_config()


def single_collection(f):
Expand Down Expand Up @@ -69,15 +66,11 @@ def multi_collection(f):
@click.option("--directory", "-d", multiple=True, type=click.Path(file_okay=False), required=False,
help="Recursively load rules from a directory")
@click.option("--rule-id", "-id", multiple=True, required=False)
@click.option("--no-tactic-filename", "-nt", is_flag=True, required=False,
help="Allow rule filenames without tactic prefix. "
"Use this if rules have been exported with this flag.")
@functools.wraps(f)
def get_collection(*args, **kwargs):
rule_id: List[str] = kwargs.pop("rule_id", [])
rule_files: List[str] = kwargs.pop("rule_file")
directories: List[str] = kwargs.pop("directory")
no_tactic_filename: bool = kwargs.pop("no_tactic_filename", False)

rules = RuleCollection()

Expand Down Expand Up @@ -106,10 +99,7 @@ def get_collection(*args, **kwargs):
for rule in rules:
threat = rule.contents.data.get("threat")
first_tactic = threat[0].tactic.name if threat else ""
# Check if flag or config is set to not include tactic in the filename
no_tactic_filename = no_tactic_filename or RULES_CONFIG.no_tactic_filename
tactic_name = None if no_tactic_filename else first_tactic
rule_name = rulename_to_filename(rule.contents.data.name, tactic_name=tactic_name)
rule_name = rulename_to_filename(rule.contents.data.name, tactic_name=first_tactic)
if rule.path.name != rule_name:
click.secho(
f"WARNING: Rule path does not match required path: {rule.path.name} != {rule_name}", fg="yellow"
Expand Down Expand Up @@ -220,11 +210,18 @@ def rule_prompt(path=None, rule_type=None, required_only=True, save=True, verbos
# DEFAULT_PREBUILT_RULES_DIRS[0] is a required directory just as a suggestion
suggested_path = Path(DEFAULT_PREBUILT_RULES_DIRS[0]) / contents['name']
path = Path(path or input(f'File path for rule [{suggested_path}]: ') or suggested_path).resolve()
# Inherit maturity and optionally local dates from the rule if it already exists
# Inherit maturity from the rule already exists
maturity = "development"
if path.exists():
rules = RuleCollection()
rules.load_file(path)
if rules:
maturity = rules.rules[0].contents.metadata.maturity

meta = {
"creation_date": kwargs.get("creation_date") or creation_date,
"updated_date": kwargs.get("updated_date") or creation_date,
"maturity": "development" or kwargs.get("maturity"),
"creation_date": creation_date,
"updated_date": creation_date,
"maturity": maturity,
}

try:
Expand Down
5 changes: 0 additions & 5 deletions detection_rules/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ class RulesConfig:
exception_dir: Optional[Path] = None
normalize_kql_keywords: bool = True
bypass_optional_elastic_validation: bool = False
no_tactic_filename: bool = False

def __post_init__(self):
"""Perform post validation on packages.yaml file."""
Expand Down Expand Up @@ -312,10 +311,6 @@ def parse_rules_config(path: Optional[Path] = None) -> RulesConfig:
if contents['bypass_optional_elastic_validation']:
set_all_validation_bypass(contents['bypass_optional_elastic_validation'])

# no_tactic_filename
contents['no_tactic_filename'] = loaded.get('no_tactic_filename', False)

# return the config
try:
rules_config = RulesConfig(test_config=test_config, **contents)
except (ValueError, TypeError) as e:
Expand Down
2 changes: 1 addition & 1 deletion detection_rules/custom_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from .utils import ROOT_DIR, get_etc_path, load_etc_dump

DEFAULT_CONFIG_PATH = Path(get_etc_path('_config.yaml'))
CUSTOM_RULES_DOC_PATH = Path(ROOT_DIR).joinpath(REPO_DOCS_DIR, 'custom-rules-management.md')
CUSTOM_RULES_DOC_PATH = Path(ROOT_DIR).joinpath(REPO_DOCS_DIR, 'custom-rules.md')


@root.group('custom-rules')
Expand Down
5 changes: 0 additions & 5 deletions detection_rules/etc/_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,3 @@ normalize_kql_keywords: False
# If set in this file, the path should be relative to the location of this config. If passed as an environment variable,
# it should be the full path
# Note: Using the `custom-rules setup-config <name>` command will generate a config called `test_config.yaml`

# To prevent the tactic prefix from being added to the rule filename, set the line below to True
# This config line can be used instead of specifying the `--no-tactic-filename` flag in the CLI
# Mind that for unit tests, you also want to disable the filename test in the test_config.yaml
# no_tactic_filename: True
Loading
Loading