Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security Solution][Detections] Reduce detection engine reliance on _source #89371

Merged
merged 9 commits into from
Feb 4, 2021

Conversation

marshallmain
Copy link
Contributor

@marshallmain marshallmain commented Jan 26, 2021

Summary

Changes by rule type:

  • KQL
    • Runtime fields in source documents will be evaluated against value list exceptions
  • Threshold
    • Timestamp for generated alert is now extracted from fields instead of _source, so if the timestamp override is a runtime field then @timestamp will be correctly populated
    • threshold_result.value now uses the bucket key rather than extracting the value from _source - so if the key is a runtime field it will be correctly populated. This also fixes a bug where if the field being aggregated on was an array of values then threshold_result.value would contain the full array rather than the single value from the array that was actually being used as the key
  • ML
    • Runtime fields in source documents will be evaluated against value list exceptions
  • Threat match
    • Runtime fields can now be used in the indicator match indices
    • Runtime fields in source documents will be evaluated against value list exceptions
  • EQL

Remaining dependencies on _source

  • Building the alert document that goes into .siem-signals
    • We rely on the parent and ancestor information for signals on signals and this info is only available in _source - fields flattens arrays of objects which makes it impossible to reconstruct the original array of objects
    • Merging _source and fields does not work for arrays of objects because not all objects in the array have the same set of fields. For example,
[{
  field1: 1
},
{
  field1: 2,
  field2: 3
}]

would flatten to

fields: {
  field1: [1, 2]
  field2: [3]
}

If field2 is overwritten by a runtime field, then we don't have enough information to merge the field2 from fields with the array of objects from _source.

It's also possible to have runtime fields that can't be represented by a JSON structure at all.

fields: {
  field1: [1],
  field1.sub_field: [2]
}

This situation is possible to create with field1 coming from the _source of a document and field1.sub_field defined as a runtime field, however, these fields and values can't be represented as a single object.

  • One solution would be to only merge fields from fields that don't conflict with existing fields in _source
    • However, this may not store all runtime fields
  • Another solution would be to ask the ES team for the ability to retrieve only runtime fields from fields and store those in their own section of the alert document
    • Maybe possible to identify the runtime fields by comparing with _source, but it's much easier if ES can specify whether each field is runtime in the response
  • Hybrid approach
    • Get runtime fields from fields response and then merge the runtime fields that do NOT conflict into _source
    • Store all runtime fields in a separate section as well for completeness

Checklist

Delete any items that are not applicable to this PR.

For maintainers

@marshallmain marshallmain added Feature:Detection Rules Security Solution rules and Detection Engine Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. v7.12.0 v8.0.0 labels Jan 27, 2021
@marshallmain marshallmain marked this pull request as ready for review January 27, 2021 16:54
@marshallmain marshallmain requested review from a team as code owners January 27, 2021 16:54
@elasticmachine
Copy link
Contributor

Pinging @elastic/security-solution (Team: SecuritySolution)

@elasticmachine
Copy link
Contributor

Pinging @elastic/security-detections-response (Team:Detections and Resp)

@marshallmain
Copy link
Contributor Author

@elasticmachine merge upstream

@marshallmain
Copy link
Contributor Author

@elasticmachine merge upstream

@marshallmain
Copy link
Contributor Author

@elasticmachine merge upstream

@marshallmain
Copy link
Contributor Author

jenkins test this

@marshallmain
Copy link
Contributor Author

@elasticmachine merge upstream

@spong spong requested a review from a team February 2, 2021 23:08
if (eventItem == null) {
return true;
} else if (tuple.operator === 'included') {
const eventItem = item.fields ? item.fields[tuple.field] : undefined;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super nit: wonder if we're gonna be doing this a lot if it's worth just creating a tiny util to extract x field from fields.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah if it becomes a common pattern I'd support pulling it out into a function

// only create a signal if the event is not in the value list
return !tuple.matchedSet.has(JSON.stringify(eventItem));
} else if (tuple.operator === 'excluded') {
if (eventItem == null) {
return false;
}
// only create a signal if the event is in the value list
return tuple.matchedSet.has(JSON.stringify(eventItem));
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since there's only two operators, not sure this else path ever hits.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't be hit, but since the operator is a string it's possible for it to get into an invalid state so it's good to handle that possibility. Looking at it again we'd probably want to return true in that case so an invalid exception operator doesn't allowlist everything, but I think that's an issue for a separate PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Wonder if we'd want to log there too. Worry about just letting through invalid states.

Copy link
Contributor

@yctercero yctercero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - really interesting reading up on runtime fields! I pulled down and tested creating various rule types. Looks great, thanks!

@marshallmain
Copy link
Contributor Author

@elasticmachine merge upstream

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

✅ unchanged

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@marshallmain marshallmain merged commit e013389 into elastic:master Feb 4, 2021
@marshallmain marshallmain deleted the drop-source branch February 4, 2021 15:20
marshallmain added a commit that referenced this pull request Feb 4, 2021
…source (#89371) (#90287)

* First pass at switching rules to depend on fields instead of _source

* Fix tests

* Change operator: excluded logic so missing fields are allowlisted

Co-authored-by: Kibana Machine <[email protected]>

Co-authored-by: Kibana Machine <[email protected]>
gmmorris added a commit to gmmorris/kibana that referenced this pull request Feb 4, 2021
* master: (244 commits)
  [maps] Top hits per entity--change to title to use recent, minor edits (elastic#89254)
  [DOCS] Update installation details (elastic#90354)
  RFC for automatically generated typescript API documentation for every plugins public services, types, and functionality (elastic#86704)
  Elastic Maps Server config is `host` not `hostname` (elastic#90234)
  Use doc link services in index pattern management (elastic#89937)
  [Fleet] Managed Agent Policy (elastic#88688)
  [Workplace Search] Fix Source Settings bug  (elastic#90242)
  [Enterprise Search] Refactor MockRouter test helper to not store payload (elastic#90206)
  Use doc link service in more Stack Monitoring pages (elastic#89050)
  [App Search] Relevance Tuning logic - actions and selectors only, no listeners (elastic#89313)
  Remove UI filters from UI (elastic#89793)
  Use newfeed.service config for all newsfeeds (elastic#90252)
  skip flaky suite (elastic#85086)
  Add readme to geo containment alert covering test alert setup (elastic#89625)
  [APM] Enabling yesterday option when 24 hours is selected (elastic#90017)
  Test user for maps tests under import geoJSON tests (elastic#86015)
  [Lens] Hide column in table (elastic#88680)
  [Security Solution][Detections] Reduce detection engine reliance on _source (elastic#89371)
  [Discover] Minor cleanup (elastic#90260)
  [Search Session][Management] Rename "cancel" button and delete "Reload" button (elastic#90015)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Detection Rules Security Solution rules and Detection Engine release_note:enhancement Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. v7.12.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants