Commit 98159da
# Backport
This will backport the following commits from `main` to `8.19`:
- [[Security Solution] Allow partial matches on rule name when searching
installed rules.
(#237496)](#237496)
<!--- Backport version: 9.6.6 -->
### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)
<!--BACKPORT [{"author":{"name":"Steven de
Salas","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-10-28T08:25:18Z","message":"[Security
Solution] Allow partial matches on rule name when searching installed
rules. (#237496)\n\n**Fixes: #237278**\n**Fixes: #97094**\n**Fixes:
#194066**\n\n## Summary\n\nWhen a user navigates to `Rules` > `Detection
Rules (SIEM)` and wishes\nto find all rules matching a partial string on
the rule name (like `win`\nto get all rules about `Windows`) they
receive 0 matches. This is in\ncontrast to the behavior they experience
when searching available\nprebuilt \"Elastic Rules\", where partial name
searches are available.\n\nThis PR fixes this UX inconsistency by
modifying the KQL output\ngenerated by the search query.\n\nWhereas
previously a search for `\"win\"` would have generated the\nfollowing
KQL:\n\n```sql\n(alert.attributes.name: \"win\" OR\n
alert.attributes.params.index: \"win\" OR\n
alert.attributes.params.threat.tactic.id: \"win\" OR\n ...\n```\n\nIt
now treats the `alert.attributes.name` differently, allowing it
to\nmatch on partial terms (ie `*win*` instead of `\"win\"`) and
using\n`.keyword` index for better special character
support.\n\n```sql\n(alert.attributes.name.keyword: *win* OR # <--
here\n alert.attributes.params.index: \"win\" OR \n
alert.attributes.params.threat.tactic.id: \"win\" OR \n ...\n```\n\n###
🕵️ BUT! .. We only do this for single term searches!\n\nPlease note that
this approach only applies to single term searches. For\nmultiple term
searches we maintain the \"old\" way of searching with\nquotations
`\"windows 10 patch\"` instead of `*windows 10 patch*` or
even\n`*windows* *10* *patch*`.\n\nThe reasoning here is that since
search results are NOT sorted by score,\nwe want to avoid returning too
many matches (wildcard searches match on\n_any_ combination of the
terms, ie those with `windows` or `10` or\n`patch`) which would confuse
the user just as they are trying to narrow\ndown their search results!!
(ie 🤔 why am I getting `Linux patch` rules\nwhen I'm asking for `windows
10 patch`??).\n\n## How to test:\n\nTo test this PR please checkout the
relevant branch and run an instance\nof kibana/elasticsearch
locally.\n\n1. `Security App` > `Rules` > `Detection Rules (SIEM)` \n2.
A table of installed rules should appear. Remove all installed\nElastic
rules.\n3. `Elastic Rules` (filter) > Tick to select all > `Select all X
Rules`\n> `Bulk actions` > `Delete` > `Delete`\n4. Go to `Add Elastic
Rules`\n5. `Search rules by name` > `win` > `Enter`\n6. You should see 5
pages of results (~84 rules)\n7. `Install All`\n8. All Elastic rules
have been installed > `Go back to installed Elastic\nrules`\n9. Search
by rule name > `win` > `Enter`\n10. You should see 5 pages of results
(~84 rules - same as in Step 6.)\n\nPlease feel free to try some
additional search queries. \n\n<details>\n<summary>\n\n### 👉 Click for
additional testing ideas\n\n</summary>\n\nHere are some single term
searches:\n - `goog`\n - `proc`\n - `sql` (should include `Postgresql`
and `MSSQL`)\n - `shell` (should include `Powershell`)\n - `inject`
(should include `injection`)\n - `git` (should include `GitHub`)\n -
`.exe`\n - `pub/sub` (exact matches only)\n - `user-agent` (exact
matches only)\n - `/bin`\n - `CVE-2025` (should include partial
matches)\n - `-` (should return matches with dash in the name like
`user-agent`)\n- `_` (should return matches with dash in the name like
`CAP_SYS_ADMIN`)\n - `|` (should return no matches - no elastic rules
with this)\n\nAnd behavior for multiple term searches:\n- `AWS` (check
the count), then `AWS IAM` (there should be less results\nfor `AWS
IAM`)\n- `pub/sub topic` (should be less than for `pub/sub`, note that
`pub/sub\ntop` partial match has no matches!)\n- `root` then `root cert`
then `root certificate` (the second has no\nresults, `root certificate`
should only return exact matches)\n- `proc`, then `process`, then
`process injection`, then `potential\nprocess injection` (each should
return less results)\n\n\n</details>\n\n##
Screenshots\n\n\n\n\n\n\n##
Special character support\n\nNote that by switching to wildcard searches
(ie `*win*`) on the\n`.keyword` index and fully escaping special
characters in KQL we'll\n**_ALSO_** be allowing special character
searches on single search\nterms.\n\nFor example, searching by
`user-agent` will return results that only\nmatch `User-Agent` but not
`user` or `agent` individually.\n\nSome other useful example of these
approach are searches for: `Pub/Sub`,\n`CVE-2025`, `/bin`, `_`,
`.exe`.\n\nThis support, in addition for escaping the backslash `\\`
character will\nallow us to close the next TWO ISSUES in this epic 🥳
wohoo!!\n\n👉 #97094 (special chars in rule name) and,\n👉 #194066
(special chars in tags)\n\n<img width=\"800\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/5411d8e8-b3f7-4a3f-9863-c64cc2a7df2c\"\n/>\n\n<img
width=\"800\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/c3589add-9f80-4646-807a-3f0c8a2ec5a7\"\n/>\n\n\n\n###
Testing special character support.\n\nIn addition to the steps above
(installing all elastic rules), we can:\n\n1. Create a rule with special
characters: ie `Rule with special chars\n(&, *, #, $, ?, >, @, \\, /,
\", ‘, {, [, ;)`\n2. Try some single term matches:\n - `@`\n - `&`
(additional elastic rules with this term should appear).\n - `*` \n -
`\"`\n - `:`\n - `>`\n - `{`\n - `\\` (backslash, this used to break the
search under #97094)\n\n## Risks\n\nThese are some of the risks that
could be identified by using this\napproach.\n\n### 1. Dependencies that
reuse query logic\n\nNote that the `searchTerm -> KQL` conversion for
searching for rules is\nused a few places.\n\n- Installed Rules\n- Rule
Monitoring\n- Bulk actions\n\n**Note**: All these paths are tested
manually, and form part of the\nautomated tests.\n\n### 2. Performance
(ie `allowLeadingWildcards`)\n\nWe're using wildcard searches before and
after the search term (ie\n`*win*`) in order to replicate the behavior
across both 'prebuilt' and\n'installed' rules tables. The wildcard AFTER
the term (`win*` =>\nmatching terms like `Windows`) is no problem but
the one BEFORE (`*win`\n=> matching terms like `Darwin`) could create an
issue.\n\nOur
[KQL\ndocumentation](https://www.elastic.co/docs/reference/query-languages/kql#_filter_for_documents_using_wildcards)\nwarns
that Kibana UI Advanced Settings have\n`query:allowLeadingWildcards`
turned off by default. This is for\nperformance reasons as a leading
wildcard can have a large impact when\nsearching indexes that have
millions of terms associated with them.\n\n<img width=\"2784\"
height=\"2120\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/9e0a754c-c30b-453e-a3ae-60a104b13fde\"\n/>\n\n>
By default, leading wildcards are not allowed for performance
reasons.\nYou can modify this with
the\n[query:allowLeadingWildcards](https://www.elastic.co/docs/reference/kibana/advanced-settings#query-allowleadingwildcards)\nadvanced
setting.\n\nPlease note that the [Query DSL docs
also\nwarn](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-query-string-query#query-string-wildcard)\nabout
avoiding this approach.\n\nThere is also more info and additional
warnings under [Lucene
API\ndocs](https://lucene.apache.org/core/9_12_3/core/org/apache/lucene/search/WildcardQuery.html).\n\nThe
risk here is two pronged:\n\n1. Users with a lot (millions?) of
detection rules will likely have a\ndegraded search experience as
queries will take longer to execute.\n\n2. Leading wildcards appear to
be working by default (in contrast to\nwhat is stated in the
documentation). But the mere _existence_ of\nvarious settings to avoid
them\n([`allowLeadingWildcards`](https://www.elastic.co/docs/reference/kibana/advanced-settings#query-allowleadingwildcards),\n[`allow_leading_wildcard`](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-query-string-query#query-string-wildcard),\n[`analyze_wildcards`](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-query-string-query#query-string-wildcard))\nis
a risk, because some users may have a special setup we've not been\nable
to anticipate in our testing, leading to potential issues like
this\none: https://github.com/elastic/kibana/issues/57828\n\n###
Mitigating factors:\n\n1. Please note that in the case of security
detection rules, the\nprebuilt rules package is _only ~1500 rules_!
Users do not manage\nmillions of rules, they generally manage low
thousands or even hundreds.\nWe've tested 100K rules successfully and
there was [_no perceivable\ndifference in terms of
search\nperformance_](https://github.com/elastic/kibana/pull/237496#issuecomment-3389956730).\nAnd
this seems to be a realistic test when checking actual usage stats\n(our
10 largest users in Sep'25 had between 60-160K installed). Also,\ndue to
current limits on pagination and bulk action logic we would\nlikely hit
different kinds of problems here _before_ search performance\nbecomes an
issue.\n\n2. We've tested all the documented ways to disable leading
wildcards,\nincluding disabling them manually (under `Server Management
> Advanced\nSettings`) and explicitly in the `kibana.yml`. None of them
seemed to\naffect searches carried out on Saved Objects. This is because
our\nsolution uses
the\n[`alerting`](http://github.com/elastic/kibana/tree/main/x-pack/platform/plugins/shared/alerting)\nplugin
under the hood which [converts the filter to KQL without\nreferring to
any UI
Advanced\nSettings](https://github.com/elastic/kibana/blob/91cab0e1369473846dc2712aa7dfe38b8580a9a5/x-pack/platform/plugins/shared/alerting/server/rules_client/common/build_kuery_node_filter.ts#L23).\nAnd
since there is no explicit setting for `allowLeadingWildcards`
the\ndefault setting of `true` gets applied instead [inside
the\n`grammar.peggy`\nfile](https://github.com/elastic/kibana/blob/91cab0e1369473846dc2712aa7dfe38b8580a9a5/src/platform/packages/shared/kbn-es-query/src/kuery/grammar/grammar.peggy#L12).\n\n###
Risks that were found acceptable\n\nIn the search for any possible
settings that might affect the rollout of\nchanges under this PR [we did
find
a\nsetting](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-wildcard-query#_allow_expensive_queries_7)\ninside
`elasticsearch.yml` that causes problems with the
proposed\nsolution.\n\n**TL/DR** 👉
`search.allow_expensive_queries=false` breaks the search.💥🤯\n\n<img
width=\"600\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/8d523d15-f832-4488-8c78-4ed60c474d44\"\n/>\n\nHowever
we also found bigger problems, _this setting also prevents
the\ninstallation of prebuilt rules_ (see below), which are a
cornerstone of\nour security solution.\n\n<img width=\"600\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/2b8d91e8-29b9-4f06-9f76-6b1edb999fd1\"\n/>\n\nIn
other words, the setting `search.allow_expensive_queries=true`
has\nbecome _a de-facto requirement of Detection Rules_, that has not
yet\nbeen documented. Hence we including it to
the\n[documentation](https://www.elastic.co/docs/solutions/security/detect-and-alert/detections-requirements)\nas
part of this PR.\n\nNote also that the errors here are not limited to
detection rules.\n\nWe found that the setting _also compromised or
outright broke a lot of\nfunctionality in Kibana_ 💥🤯 (including Fleet,
API Keys, Timelines, Saved\nObject search, Tags, Server Monitoring etc).
More about this is\n[documented in this
internal\ndocument](https://docs.google.com/document/d/1HLOXQZFcm1-KBj9DHTqwcF3wDdLOE6CcgUzqzZA2CAg/edit?tab=t.0).\nAnd
in this [internal
slack\nthread](https://elastic.slack.com/archives/C02HA9E8221/p1760694975799469).\nSo
we're assuming that most if not all of our users will have it set
to\n`true`.\n\n## Checklist\n\nCheck the PR satisfies following
conditions. \n\n- [x] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common scenarios\n- [x] [Flaky
Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1)
was\nused on any tests changed\n- [x] The PR description includes the
appropriate Release Notes section,\nand the correct `release_note:*`
label is applied per
the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n-
[x] Follow the
[backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand
apply applicable `backport:*` labels.\n- [x] Changes have been
socialized with the PM and rest of the team.\n- [x] All identified Risks
have been properly documented and\ninvestigated.
([internal\ninvestigation](https://docs.google.com/document/d/1HLOXQZFcm1-KBj9DHTqwcF3wDdLOE6CcgUzqzZA2CAg/edit?tab=t.0))\n-
[x] New requirements added to the technical docs
(PR\n[#3543](elastic/docs-content#3543),
see\n[here](https://www.elastic.co/docs/solutions/security/detect-and-alert/detections-requirements))","sha":"433902b9b40c9fb3f4db5346008a61efaed3df31","branchLabelMapping":{"^v9.3.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:fix","Team:Detections
and Resp","Team: SecuritySolution","Feature:Rule
Management","Team:Detection Rule
Management","ci:cloud-deploy","ci:project-deploy-security","backport:version","v9.3.0","v8.19.7","v9.1.7","v9.2.1"],"title":"[Security
Solution] Allow partial matches on rule name when searching installed
rules.","number":237496,"url":"https://github.com/elastic/kibana/pull/237496","mergeCommit":{"message":"[Security
Solution] Allow partial matches on rule name when searching installed
rules. (#237496)\n\n**Fixes: #237278**\n**Fixes: #97094**\n**Fixes:
#194066**\n\n## Summary\n\nWhen a user navigates to `Rules` > `Detection
Rules (SIEM)` and wishes\nto find all rules matching a partial string on
the rule name (like `win`\nto get all rules about `Windows`) they
receive 0 matches. This is in\ncontrast to the behavior they experience
when searching available\nprebuilt \"Elastic Rules\", where partial name
searches are available.\n\nThis PR fixes this UX inconsistency by
modifying the KQL output\ngenerated by the search query.\n\nWhereas
previously a search for `\"win\"` would have generated the\nfollowing
KQL:\n\n```sql\n(alert.attributes.name: \"win\" OR\n
alert.attributes.params.index: \"win\" OR\n
alert.attributes.params.threat.tactic.id: \"win\" OR\n ...\n```\n\nIt
now treats the `alert.attributes.name` differently, allowing it
to\nmatch on partial terms (ie `*win*` instead of `\"win\"`) and
using\n`.keyword` index for better special character
support.\n\n```sql\n(alert.attributes.name.keyword: *win* OR # <--
here\n alert.attributes.params.index: \"win\" OR \n
alert.attributes.params.threat.tactic.id: \"win\" OR \n ...\n```\n\n###
🕵️ BUT! .. We only do this for single term searches!\n\nPlease note that
this approach only applies to single term searches. For\nmultiple term
searches we maintain the \"old\" way of searching with\nquotations
`\"windows 10 patch\"` instead of `*windows 10 patch*` or
even\n`*windows* *10* *patch*`.\n\nThe reasoning here is that since
search results are NOT sorted by score,\nwe want to avoid returning too
many matches (wildcard searches match on\n_any_ combination of the
terms, ie those with `windows` or `10` or\n`patch`) which would confuse
the user just as they are trying to narrow\ndown their search results!!
(ie 🤔 why am I getting `Linux patch` rules\nwhen I'm asking for `windows
10 patch`??).\n\n## How to test:\n\nTo test this PR please checkout the
relevant branch and run an instance\nof kibana/elasticsearch
locally.\n\n1. `Security App` > `Rules` > `Detection Rules (SIEM)` \n2.
A table of installed rules should appear. Remove all installed\nElastic
rules.\n3. `Elastic Rules` (filter) > Tick to select all > `Select all X
Rules`\n> `Bulk actions` > `Delete` > `Delete`\n4. Go to `Add Elastic
Rules`\n5. `Search rules by name` > `win` > `Enter`\n6. You should see 5
pages of results (~84 rules)\n7. `Install All`\n8. All Elastic rules
have been installed > `Go back to installed Elastic\nrules`\n9. Search
by rule name > `win` > `Enter`\n10. You should see 5 pages of results
(~84 rules - same as in Step 6.)\n\nPlease feel free to try some
additional search queries. \n\n<details>\n<summary>\n\n### 👉 Click for
additional testing ideas\n\n</summary>\n\nHere are some single term
searches:\n - `goog`\n - `proc`\n - `sql` (should include `Postgresql`
and `MSSQL`)\n - `shell` (should include `Powershell`)\n - `inject`
(should include `injection`)\n - `git` (should include `GitHub`)\n -
`.exe`\n - `pub/sub` (exact matches only)\n - `user-agent` (exact
matches only)\n - `/bin`\n - `CVE-2025` (should include partial
matches)\n - `-` (should return matches with dash in the name like
`user-agent`)\n- `_` (should return matches with dash in the name like
`CAP_SYS_ADMIN`)\n - `|` (should return no matches - no elastic rules
with this)\n\nAnd behavior for multiple term searches:\n- `AWS` (check
the count), then `AWS IAM` (there should be less results\nfor `AWS
IAM`)\n- `pub/sub topic` (should be less than for `pub/sub`, note that
`pub/sub\ntop` partial match has no matches!)\n- `root` then `root cert`
then `root certificate` (the second has no\nresults, `root certificate`
should only return exact matches)\n- `proc`, then `process`, then
`process injection`, then `potential\nprocess injection` (each should
return less results)\n\n\n</details>\n\n##
Screenshots\n\n\n\n\n\n\n##
Special character support\n\nNote that by switching to wildcard searches
(ie `*win*`) on the\n`.keyword` index and fully escaping special
characters in KQL we'll\n**_ALSO_** be allowing special character
searches on single search\nterms.\n\nFor example, searching by
`user-agent` will return results that only\nmatch `User-Agent` but not
`user` or `agent` individually.\n\nSome other useful example of these
approach are searches for: `Pub/Sub`,\n`CVE-2025`, `/bin`, `_`,
`.exe`.\n\nThis support, in addition for escaping the backslash `\\`
character will\nallow us to close the next TWO ISSUES in this epic 🥳
wohoo!!\n\n👉 #97094 (special chars in rule name) and,\n👉 #194066
(special chars in tags)\n\n<img width=\"800\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/5411d8e8-b3f7-4a3f-9863-c64cc2a7df2c\"\n/>\n\n<img
width=\"800\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/c3589add-9f80-4646-807a-3f0c8a2ec5a7\"\n/>\n\n\n\n###
Testing special character support.\n\nIn addition to the steps above
(installing all elastic rules), we can:\n\n1. Create a rule with special
characters: ie `Rule with special chars\n(&, *, #, $, ?, >, @, \\, /,
\", ‘, {, [, ;)`\n2. Try some single term matches:\n - `@`\n - `&`
(additional elastic rules with this term should appear).\n - `*` \n -
`\"`\n - `:`\n - `>`\n - `{`\n - `\\` (backslash, this used to break the
search under #97094)\n\n## Risks\n\nThese are some of the risks that
could be identified by using this\napproach.\n\n### 1. Dependencies that
reuse query logic\n\nNote that the `searchTerm -> KQL` conversion for
searching for rules is\nused a few places.\n\n- Installed Rules\n- Rule
Monitoring\n- Bulk actions\n\n**Note**: All these paths are tested
manually, and form part of the\nautomated tests.\n\n### 2. Performance
(ie `allowLeadingWildcards`)\n\nWe're using wildcard searches before and
after the search term (ie\n`*win*`) in order to replicate the behavior
across both 'prebuilt' and\n'installed' rules tables. The wildcard AFTER
the term (`win*` =>\nmatching terms like `Windows`) is no problem but
the one BEFORE (`*win`\n=> matching terms like `Darwin`) could create an
issue.\n\nOur
[KQL\ndocumentation](https://www.elastic.co/docs/reference/query-languages/kql#_filter_for_documents_using_wildcards)\nwarns
that Kibana UI Advanced Settings have\n`query:allowLeadingWildcards`
turned off by default. This is for\nperformance reasons as a leading
wildcard can have a large impact when\nsearching indexes that have
millions of terms associated with them.\n\n<img width=\"2784\"
height=\"2120\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/9e0a754c-c30b-453e-a3ae-60a104b13fde\"\n/>\n\n>
By default, leading wildcards are not allowed for performance
reasons.\nYou can modify this with
the\n[query:allowLeadingWildcards](https://www.elastic.co/docs/reference/kibana/advanced-settings#query-allowleadingwildcards)\nadvanced
setting.\n\nPlease note that the [Query DSL docs
also\nwarn](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-query-string-query#query-string-wildcard)\nabout
avoiding this approach.\n\nThere is also more info and additional
warnings under [Lucene
API\ndocs](https://lucene.apache.org/core/9_12_3/core/org/apache/lucene/search/WildcardQuery.html).\n\nThe
risk here is two pronged:\n\n1. Users with a lot (millions?) of
detection rules will likely have a\ndegraded search experience as
queries will take longer to execute.\n\n2. Leading wildcards appear to
be working by default (in contrast to\nwhat is stated in the
documentation). But the mere _existence_ of\nvarious settings to avoid
them\n([`allowLeadingWildcards`](https://www.elastic.co/docs/reference/kibana/advanced-settings#query-allowleadingwildcards),\n[`allow_leading_wildcard`](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-query-string-query#query-string-wildcard),\n[`analyze_wildcards`](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-query-string-query#query-string-wildcard))\nis
a risk, because some users may have a special setup we've not been\nable
to anticipate in our testing, leading to potential issues like
this\none: https://github.com/elastic/kibana/issues/57828\n\n###
Mitigating factors:\n\n1. Please note that in the case of security
detection rules, the\nprebuilt rules package is _only ~1500 rules_!
Users do not manage\nmillions of rules, they generally manage low
thousands or even hundreds.\nWe've tested 100K rules successfully and
there was [_no perceivable\ndifference in terms of
search\nperformance_](https://github.com/elastic/kibana/pull/237496#issuecomment-3389956730).\nAnd
this seems to be a realistic test when checking actual usage stats\n(our
10 largest users in Sep'25 had between 60-160K installed). Also,\ndue to
current limits on pagination and bulk action logic we would\nlikely hit
different kinds of problems here _before_ search performance\nbecomes an
issue.\n\n2. We've tested all the documented ways to disable leading
wildcards,\nincluding disabling them manually (under `Server Management
> Advanced\nSettings`) and explicitly in the `kibana.yml`. None of them
seemed to\naffect searches carried out on Saved Objects. This is because
our\nsolution uses
the\n[`alerting`](http://github.com/elastic/kibana/tree/main/x-pack/platform/plugins/shared/alerting)\nplugin
under the hood which [converts the filter to KQL without\nreferring to
any UI
Advanced\nSettings](https://github.com/elastic/kibana/blob/91cab0e1369473846dc2712aa7dfe38b8580a9a5/x-pack/platform/plugins/shared/alerting/server/rules_client/common/build_kuery_node_filter.ts#L23).\nAnd
since there is no explicit setting for `allowLeadingWildcards`
the\ndefault setting of `true` gets applied instead [inside
the\n`grammar.peggy`\nfile](https://github.com/elastic/kibana/blob/91cab0e1369473846dc2712aa7dfe38b8580a9a5/src/platform/packages/shared/kbn-es-query/src/kuery/grammar/grammar.peggy#L12).\n\n###
Risks that were found acceptable\n\nIn the search for any possible
settings that might affect the rollout of\nchanges under this PR [we did
find
a\nsetting](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-wildcard-query#_allow_expensive_queries_7)\ninside
`elasticsearch.yml` that causes problems with the
proposed\nsolution.\n\n**TL/DR** 👉
`search.allow_expensive_queries=false` breaks the search.💥🤯\n\n<img
width=\"600\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/8d523d15-f832-4488-8c78-4ed60c474d44\"\n/>\n\nHowever
we also found bigger problems, _this setting also prevents
the\ninstallation of prebuilt rules_ (see below), which are a
cornerstone of\nour security solution.\n\n<img width=\"600\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/2b8d91e8-29b9-4f06-9f76-6b1edb999fd1\"\n/>\n\nIn
other words, the setting `search.allow_expensive_queries=true`
has\nbecome _a de-facto requirement of Detection Rules_, that has not
yet\nbeen documented. Hence we including it to
the\n[documentation](https://www.elastic.co/docs/solutions/security/detect-and-alert/detections-requirements)\nas
part of this PR.\n\nNote also that the errors here are not limited to
detection rules.\n\nWe found that the setting _also compromised or
outright broke a lot of\nfunctionality in Kibana_ 💥🤯 (including Fleet,
API Keys, Timelines, Saved\nObject search, Tags, Server Monitoring etc).
More about this is\n[documented in this
internal\ndocument](https://docs.google.com/document/d/1HLOXQZFcm1-KBj9DHTqwcF3wDdLOE6CcgUzqzZA2CAg/edit?tab=t.0).\nAnd
in this [internal
slack\nthread](https://elastic.slack.com/archives/C02HA9E8221/p1760694975799469).\nSo
we're assuming that most if not all of our users will have it set
to\n`true`.\n\n## Checklist\n\nCheck the PR satisfies following
conditions. \n\n- [x] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common scenarios\n- [x] [Flaky
Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1)
was\nused on any tests changed\n- [x] The PR description includes the
appropriate Release Notes section,\nand the correct `release_note:*`
label is applied per
the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n-
[x] Follow the
[backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand
apply applicable `backport:*` labels.\n- [x] Changes have been
socialized with the PM and rest of the team.\n- [x] All identified Risks
have been properly documented and\ninvestigated.
([internal\ninvestigation](https://docs.google.com/document/d/1HLOXQZFcm1-KBj9DHTqwcF3wDdLOE6CcgUzqzZA2CAg/edit?tab=t.0))\n-
[x] New requirements added to the technical docs
(PR\n[#3543](elastic/docs-content#3543),
see\n[here](https://www.elastic.co/docs/solutions/security/detect-and-alert/detections-requirements))","sha":"433902b9b40c9fb3f4db5346008a61efaed3df31"}},"sourceBranch":"main","suggestedTargetBranches":["8.19","9.1","9.2"],"targetPullRequestStates":[{"branch":"main","label":"v9.3.0","branchLabelMappingKey":"^v9.3.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/237496","number":237496,"mergeCommit":{"message":"[Security
Solution] Allow partial matches on rule name when searching installed
rules. (#237496)\n\n**Fixes: #237278**\n**Fixes: #97094**\n**Fixes:
#194066**\n\n## Summary\n\nWhen a user navigates to `Rules` > `Detection
Rules (SIEM)` and wishes\nto find all rules matching a partial string on
the rule name (like `win`\nto get all rules about `Windows`) they
receive 0 matches. This is in\ncontrast to the behavior they experience
when searching available\nprebuilt \"Elastic Rules\", where partial name
searches are available.\n\nThis PR fixes this UX inconsistency by
modifying the KQL output\ngenerated by the search query.\n\nWhereas
previously a search for `\"win\"` would have generated the\nfollowing
KQL:\n\n```sql\n(alert.attributes.name: \"win\" OR\n
alert.attributes.params.index: \"win\" OR\n
alert.attributes.params.threat.tactic.id: \"win\" OR\n ...\n```\n\nIt
now treats the `alert.attributes.name` differently, allowing it
to\nmatch on partial terms (ie `*win*` instead of `\"win\"`) and
using\n`.keyword` index for better special character
support.\n\n```sql\n(alert.attributes.name.keyword: *win* OR # <--
here\n alert.attributes.params.index: \"win\" OR \n
alert.attributes.params.threat.tactic.id: \"win\" OR \n ...\n```\n\n###
🕵️ BUT! .. We only do this for single term searches!\n\nPlease note that
this approach only applies to single term searches. For\nmultiple term
searches we maintain the \"old\" way of searching with\nquotations
`\"windows 10 patch\"` instead of `*windows 10 patch*` or
even\n`*windows* *10* *patch*`.\n\nThe reasoning here is that since
search results are NOT sorted by score,\nwe want to avoid returning too
many matches (wildcard searches match on\n_any_ combination of the
terms, ie those with `windows` or `10` or\n`patch`) which would confuse
the user just as they are trying to narrow\ndown their search results!!
(ie 🤔 why am I getting `Linux patch` rules\nwhen I'm asking for `windows
10 patch`??).\n\n## How to test:\n\nTo test this PR please checkout the
relevant branch and run an instance\nof kibana/elasticsearch
locally.\n\n1. `Security App` > `Rules` > `Detection Rules (SIEM)` \n2.
A table of installed rules should appear. Remove all installed\nElastic
rules.\n3. `Elastic Rules` (filter) > Tick to select all > `Select all X
Rules`\n> `Bulk actions` > `Delete` > `Delete`\n4. Go to `Add Elastic
Rules`\n5. `Search rules by name` > `win` > `Enter`\n6. You should see 5
pages of results (~84 rules)\n7. `Install All`\n8. All Elastic rules
have been installed > `Go back to installed Elastic\nrules`\n9. Search
by rule name > `win` > `Enter`\n10. You should see 5 pages of results
(~84 rules - same as in Step 6.)\n\nPlease feel free to try some
additional search queries. \n\n<details>\n<summary>\n\n### 👉 Click for
additional testing ideas\n\n</summary>\n\nHere are some single term
searches:\n - `goog`\n - `proc`\n - `sql` (should include `Postgresql`
and `MSSQL`)\n - `shell` (should include `Powershell`)\n - `inject`
(should include `injection`)\n - `git` (should include `GitHub`)\n -
`.exe`\n - `pub/sub` (exact matches only)\n - `user-agent` (exact
matches only)\n - `/bin`\n - `CVE-2025` (should include partial
matches)\n - `-` (should return matches with dash in the name like
`user-agent`)\n- `_` (should return matches with dash in the name like
`CAP_SYS_ADMIN`)\n - `|` (should return no matches - no elastic rules
with this)\n\nAnd behavior for multiple term searches:\n- `AWS` (check
the count), then `AWS IAM` (there should be less results\nfor `AWS
IAM`)\n- `pub/sub topic` (should be less than for `pub/sub`, note that
`pub/sub\ntop` partial match has no matches!)\n- `root` then `root cert`
then `root certificate` (the second has no\nresults, `root certificate`
should only return exact matches)\n- `proc`, then `process`, then
`process injection`, then `potential\nprocess injection` (each should
return less results)\n\n\n</details>\n\n##
Screenshots\n\n\n\n\n\n\n##
Special character support\n\nNote that by switching to wildcard searches
(ie `*win*`) on the\n`.keyword` index and fully escaping special
characters in KQL we'll\n**_ALSO_** be allowing special character
searches on single search\nterms.\n\nFor example, searching by
`user-agent` will return results that only\nmatch `User-Agent` but not
`user` or `agent` individually.\n\nSome other useful example of these
approach are searches for: `Pub/Sub`,\n`CVE-2025`, `/bin`, `_`,
`.exe`.\n\nThis support, in addition for escaping the backslash `\\`
character will\nallow us to close the next TWO ISSUES in this epic 🥳
wohoo!!\n\n👉 #97094 (special chars in rule name) and,\n👉 #194066
(special chars in tags)\n\n<img width=\"800\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/5411d8e8-b3f7-4a3f-9863-c64cc2a7df2c\"\n/>\n\n<img
width=\"800\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/c3589add-9f80-4646-807a-3f0c8a2ec5a7\"\n/>\n\n\n\n###
Testing special character support.\n\nIn addition to the steps above
(installing all elastic rules), we can:\n\n1. Create a rule with special
characters: ie `Rule with special chars\n(&, *, #, $, ?, >, @, \\, /,
\", ‘, {, [, ;)`\n2. Try some single term matches:\n - `@`\n - `&`
(additional elastic rules with this term should appear).\n - `*` \n -
`\"`\n - `:`\n - `>`\n - `{`\n - `\\` (backslash, this used to break the
search under #97094)\n\n## Risks\n\nThese are some of the risks that
could be identified by using this\napproach.\n\n### 1. Dependencies that
reuse query logic\n\nNote that the `searchTerm -> KQL` conversion for
searching for rules is\nused a few places.\n\n- Installed Rules\n- Rule
Monitoring\n- Bulk actions\n\n**Note**: All these paths are tested
manually, and form part of the\nautomated tests.\n\n### 2. Performance
(ie `allowLeadingWildcards`)\n\nWe're using wildcard searches before and
after the search term (ie\n`*win*`) in order to replicate the behavior
across both 'prebuilt' and\n'installed' rules tables. The wildcard AFTER
the term (`win*` =>\nmatching terms like `Windows`) is no problem but
the one BEFORE (`*win`\n=> matching terms like `Darwin`) could create an
issue.\n\nOur
[KQL\ndocumentation](https://www.elastic.co/docs/reference/query-languages/kql#_filter_for_documents_using_wildcards)\nwarns
that Kibana UI Advanced Settings have\n`query:allowLeadingWildcards`
turned off by default. This is for\nperformance reasons as a leading
wildcard can have a large impact when\nsearching indexes that have
millions of terms associated with them.\n\n<img width=\"2784\"
height=\"2120\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/9e0a754c-c30b-453e-a3ae-60a104b13fde\"\n/>\n\n>
By default, leading wildcards are not allowed for performance
reasons.\nYou can modify this with
the\n[query:allowLeadingWildcards](https://www.elastic.co/docs/reference/kibana/advanced-settings#query-allowleadingwildcards)\nadvanced
setting.\n\nPlease note that the [Query DSL docs
also\nwarn](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-query-string-query#query-string-wildcard)\nabout
avoiding this approach.\n\nThere is also more info and additional
warnings under [Lucene
API\ndocs](https://lucene.apache.org/core/9_12_3/core/org/apache/lucene/search/WildcardQuery.html).\n\nThe
risk here is two pronged:\n\n1. Users with a lot (millions?) of
detection rules will likely have a\ndegraded search experience as
queries will take longer to execute.\n\n2. Leading wildcards appear to
be working by default (in contrast to\nwhat is stated in the
documentation). But the mere _existence_ of\nvarious settings to avoid
them\n([`allowLeadingWildcards`](https://www.elastic.co/docs/reference/kibana/advanced-settings#query-allowleadingwildcards),\n[`allow_leading_wildcard`](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-query-string-query#query-string-wildcard),\n[`analyze_wildcards`](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-query-string-query#query-string-wildcard))\nis
a risk, because some users may have a special setup we've not been\nable
to anticipate in our testing, leading to potential issues like
this\none: https://github.com/elastic/kibana/issues/57828\n\n###
Mitigating factors:\n\n1. Please note that in the case of security
detection rules, the\nprebuilt rules package is _only ~1500 rules_!
Users do not manage\nmillions of rules, they generally manage low
thousands or even hundreds.\nWe've tested 100K rules successfully and
there was [_no perceivable\ndifference in terms of
search\nperformance_](https://github.com/elastic/kibana/pull/237496#issuecomment-3389956730).\nAnd
this seems to be a realistic test when checking actual usage stats\n(our
10 largest users in Sep'25 had between 60-160K installed). Also,\ndue to
current limits on pagination and bulk action logic we would\nlikely hit
different kinds of problems here _before_ search performance\nbecomes an
issue.\n\n2. We've tested all the documented ways to disable leading
wildcards,\nincluding disabling them manually (under `Server Management
> Advanced\nSettings`) and explicitly in the `kibana.yml`. None of them
seemed to\naffect searches carried out on Saved Objects. This is because
our\nsolution uses
the\n[`alerting`](http://github.com/elastic/kibana/tree/main/x-pack/platform/plugins/shared/alerting)\nplugin
under the hood which [converts the filter to KQL without\nreferring to
any UI
Advanced\nSettings](https://github.com/elastic/kibana/blob/91cab0e1369473846dc2712aa7dfe38b8580a9a5/x-pack/platform/plugins/shared/alerting/server/rules_client/common/build_kuery_node_filter.ts#L23).\nAnd
since there is no explicit setting for `allowLeadingWildcards`
the\ndefault setting of `true` gets applied instead [inside
the\n`grammar.peggy`\nfile](https://github.com/elastic/kibana/blob/91cab0e1369473846dc2712aa7dfe38b8580a9a5/src/platform/packages/shared/kbn-es-query/src/kuery/grammar/grammar.peggy#L12).\n\n###
Risks that were found acceptable\n\nIn the search for any possible
settings that might affect the rollout of\nchanges under this PR [we did
find
a\nsetting](https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-wildcard-query#_allow_expensive_queries_7)\ninside
`elasticsearch.yml` that causes problems with the
proposed\nsolution.\n\n**TL/DR** 👉
`search.allow_expensive_queries=false` breaks the search.💥🤯\n\n<img
width=\"600\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/8d523d15-f832-4488-8c78-4ed60c474d44\"\n/>\n\nHowever
we also found bigger problems, _this setting also prevents
the\ninstallation of prebuilt rules_ (see below), which are a
cornerstone of\nour security solution.\n\n<img width=\"600\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/2b8d91e8-29b9-4f06-9f76-6b1edb999fd1\"\n/>\n\nIn
other words, the setting `search.allow_expensive_queries=true`
has\nbecome _a de-facto requirement of Detection Rules_, that has not
yet\nbeen documented. Hence we including it to
the\n[documentation](https://www.elastic.co/docs/solutions/security/detect-and-alert/detections-requirements)\nas
part of this PR.\n\nNote also that the errors here are not limited to
detection rules.\n\nWe found that the setting _also compromised or
outright broke a lot of\nfunctionality in Kibana_ 💥🤯 (including Fleet,
API Keys, Timelines, Saved\nObject search, Tags, Server Monitoring etc).
More about this is\n[documented in this
internal\ndocument](https://docs.google.com/document/d/1HLOXQZFcm1-KBj9DHTqwcF3wDdLOE6CcgUzqzZA2CAg/edit?tab=t.0).\nAnd
in this [internal
slack\nthread](https://elastic.slack.com/archives/C02HA9E8221/p1760694975799469).\nSo
we're assuming that most if not all of our users will have it set
to\n`true`.\n\n## Checklist\n\nCheck the PR satisfies following
conditions. \n\n- [x] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common scenarios\n- [x] [Flaky
Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1)
was\nused on any tests changed\n- [x] The PR description includes the
appropriate Release Notes section,\nand the correct `release_note:*`
label is applied per
the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n-
[x] Follow the
[backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand
apply applicable `backport:*` labels.\n- [x] Changes have been
socialized with the PM and rest of the team.\n- [x] All identified Risks
have been properly documented and\ninvestigated.
([internal\ninvestigation](https://docs.google.com/document/d/1HLOXQZFcm1-KBj9DHTqwcF3wDdLOE6CcgUzqzZA2CAg/edit?tab=t.0))\n-
[x] New requirements added to the technical docs
(PR\n[#3543](elastic/docs-content#3543),
see\n[here](https://www.elastic.co/docs/solutions/security/detect-and-alert/detections-requirements))","sha":"433902b9b40c9fb3f4db5346008a61efaed3df31"}},{"branch":"8.19","label":"v8.19.7","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"9.1","label":"v9.1.7","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"9.2","label":"v9.2.1","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->
Co-authored-by: Steven de Salas <[email protected]>
1 parent 9305480 commit 98159da
File tree
8 files changed
+460
-46
lines changed- x-pack/solutions/security
- plugins/security_solution
- common
- detection_engine/rule_management
- utils
- public/detection_engine
- rule_management_ui/pages/coverage_overview
- rule_management/api
- test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_management/basic_license_essentials_tier
8 files changed
+460
-46
lines changedLines changed: 91 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
| 18 | + | |
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
24 | 36 | | |
25 | 37 | | |
26 | 38 | | |
27 | 39 | | |
28 | | - | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
29 | 50 | | |
30 | 51 | | |
31 | 52 | | |
32 | | - | |
33 | | - | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
34 | 58 | | |
35 | 59 | | |
36 | | - | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
37 | 70 | | |
38 | 71 | | |
39 | 72 | | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
40 | 113 | | |
41 | 114 | | |
42 | 115 | | |
| |||
74 | 147 | | |
75 | 148 | | |
76 | 149 | | |
77 | | - | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
78 | 163 | | |
79 | 164 | | |
80 | 165 | | |
| |||
Lines changed: 32 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| |||
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
63 | | - | |
| 63 | + | |
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
| |||
106 | 106 | | |
107 | 107 | | |
108 | 108 | | |
109 | | - | |
110 | 109 | | |
111 | 110 | | |
112 | 111 | | |
| |||
116 | 115 | | |
117 | 116 | | |
118 | 117 | | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | | - | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
124 | 148 | | |
125 | 149 | | |
126 | 150 | | |
| |||
Lines changed: 47 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
9 | 14 | | |
10 | | - | |
| 15 | + | |
11 | 16 | | |
12 | 17 | | |
13 | 18 | | |
14 | 19 | | |
15 | 20 | | |
16 | | - | |
| 21 | + | |
17 | 22 | | |
18 | 23 | | |
19 | 24 | | |
| |||
42 | 47 | | |
43 | 48 | | |
44 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
45 | 55 | | |
46 | 56 | | |
47 | 57 | | |
48 | | - | |
| 58 | + | |
49 | 59 | | |
50 | 60 | | |
51 | 61 | | |
| |||
65 | 75 | | |
66 | 76 | | |
67 | 77 | | |
68 | | - | |
| 78 | + | |
69 | 79 | | |
70 | 80 | | |
71 | 81 | | |
72 | 82 | | |
73 | 83 | | |
74 | | - | |
| 84 | + | |
75 | 85 | | |
76 | 86 | | |
77 | 87 | | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
Lines changed: 43 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
| 36 | + | |
40 | 37 | | |
41 | | - | |
| 38 | + | |
| 39 | + | |
42 | 40 | | |
43 | 41 | | |
44 | | - | |
| 42 | + | |
45 | 43 | | |
46 | 44 | | |
47 | | - | |
| 45 | + | |
48 | 46 | | |
49 | 47 | | |
50 | 48 | | |
51 | 49 | | |
| 50 | + | |
| 51 | + | |
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
55 | | - | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
0 commit comments