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
25 changes: 24 additions & 1 deletion crates/rsigma-eval/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ Each transformation item in a pipeline can have:

| Type | Fields | Description |
|------|--------|-------------|
| `field_name_mapping` | `mapping: {k: v}` | Rename fields via a mapping dict |
| `field_name_mapping` | `mapping: {k: v \| [v1, v2, ...]}` | Rename fields via a mapping dict; list values expand the matched detection item into an OR over the alternatives (one-to-many, pySigma-compatible) |
| `field_name_prefix_mapping` | `mapping: {prefix: replacement}` | Rename fields matching a prefix |
| `field_name_prefix` | `prefix` | Add a prefix to all field names |
| `field_name_suffix` | `suffix` | Add a suffix to all field names |
Expand Down Expand Up @@ -437,6 +437,29 @@ let event = JsonEvent::borrow(&json!({"process.command_line": "whoami"}));
let matches = engine.evaluate(&event);
```

`field_name_mapping` also accepts a list of alternatives, matching pySigma's
`FieldMappingTransformation`. The matched detection item is expanded into an
OR over the alternatives — when the surrounding `AllOf` selection has other
items, they're preserved across each branch via a Cartesian expansion so the
`AND` / `OR` semantics stay correct:

```yaml
name: Hashes mapping
transformations:
- type: field_name_mapping
mapping:
Hashes:
- file.hash.md5
- file.hash.sha1
- file.hash.sha256
```

After applying this pipeline, a rule selecting `Hashes: 'abc123'` matches an
event populating *any* of `file.hash.md5`, `file.hash.sha1`, or
`file.hash.sha256`. Correlation rules (`group_by`, `aliases`, threshold
`field`) consume only the first listed alternative since those positions are
inherently scalar.

**With correlations:**

```rust
Expand Down
9 changes: 7 additions & 2 deletions crates/rsigma-eval/src/pipeline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,12 @@ fn apply_correlation_transformation(
) -> Result<bool> {
match transformation {
Transformation::FieldNameMapping { mapping } => {
remap_correlation_fields(corr, |name| mapping.get(name).cloned());
// Correlation fields (group_by, aliases mapping values, threshold
// field) are scalar — OR over multiple alternatives isn't
// expressible there, so we use the first listed alternative.
remap_correlation_fields(corr, |name| {
mapping.get(name).and_then(|alts| alts.first().cloned())
});
Ok(true)
}

Expand Down Expand Up @@ -470,7 +475,7 @@ fn parse_transformation(obj: &serde_yaml::Mapping) -> Result<Transformation> {

match type_str {
"field_name_mapping" => {
let mapping = parse_string_mapping(obj.get(ykey("mapping")))?;
let mapping = parse_string_or_list_mapping(obj.get(ykey("mapping")))?;
Ok(Transformation::FieldNameMapping { mapping })
}

Expand Down
Loading