Skip to content

Commit 609e789

Browse files
fix(asm): update required address when new rules are updated [backport 1.20] (#8425)
Backport ac9bc9b from #8420 to 1.20. Required waf addresses were not updated in the appsec processor after a remote config rules update. Hence, it was possible for some custom rules to be ignored. This PR fixes this. ## Checklist - [x] Change(s) are motivated and described in the PR description - [x] Testing strategy is described if automated tests are not included in the PR - [x] Risks are described (performance impact, potential for breakage, maintainability) - [x] Change is maintainable (easy to change, telemetry, documentation) - [x] [Library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) are followed or label `changelog/no-changelog` is set - [x] Documentation is included (in-code, generated user docs, [public corp docs](https://github.com/DataDog/documentation/)) - [x] Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) - [x] If this PR changes the public interface, I've notified `@DataDog/apm-tees`. - [x] If change touches code that signs or publishes builds or packages, or handles credentials of any kind, I've requested a review from `@DataDog/security-design-and-guidance`. ## Reviewer Checklist - [x] Title is accurate - [x] All changes are related to the pull request's stated goal - [x] Description motivates each change - [x] Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - [x] Testing strategy adequately addresses listed risks - [x] Change is maintainable (easy to change, telemetry, documentation) - [x] Release note makes sense to a user of the library - [x] Author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - [x] Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)
1 parent 482394e commit 609e789

File tree

3 files changed

+66
-7
lines changed

3 files changed

+66
-7
lines changed

ddtrace/appsec/processor.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,16 @@ def __attrs_post_init__(self):
195195
# Partial of DDAS-0005-00
196196
log.warning("[DDAS-0005-00] WAF initialization failed")
197197
raise
198+
self._update_required()
199+
200+
def _update_required(self):
201+
self._addresses_to_keep.clear()
198202
for address in self._ddwaf.required_data:
199-
self._mark_needed(address)
203+
self._addresses_to_keep.add(address)
200204
# we always need the request headers
201-
self._mark_needed(WAF_DATA_NAMES.REQUEST_HEADERS_NO_COOKIES)
205+
self._addresses_to_keep.add(WAF_DATA_NAMES.REQUEST_HEADERS_NO_COOKIES)
202206
# we always need the response headers
203-
self._mark_needed(WAF_DATA_NAMES.RESPONSE_HEADERS_NO_COOKIES)
207+
self._addresses_to_keep.add(WAF_DATA_NAMES.RESPONSE_HEADERS_NO_COOKIES)
204208

205209
def _update_actions(self, rules):
206210
new_actions = rules.get("actions", [])
@@ -227,6 +231,7 @@ def _update_rules(self, new_rules):
227231
error_msg = "Error updating ASM rules. Invalid rules"
228232
log.debug(error_msg)
229233
_set_waf_error_metric(error_msg, "", self._ddwaf.info)
234+
self._update_required()
230235
return result
231236

232237
def on_span_start(self, span):
@@ -412,10 +417,6 @@ def update_metric(name, value):
412417
span.set_tag_str(ORIGIN_KEY, APPSEC.ORIGIN_VALUE)
413418
return waf_results.derivatives
414419

415-
def _mark_needed(self, address):
416-
# type: (str) -> None
417-
self._addresses_to_keep.add(address)
418-
419420
def _is_needed(self, address):
420421
# type: (str) -> bool
421422
return address in self._addresses_to_keep
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
fixes:
3+
- |
4+
ASM: This fix resolves an issue where rules updated through remote config were not
5+
properly updating required WAF addresses. This could lead to custom rules being ignored.

tests/appsec/test_processor.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,3 +677,56 @@ def test_asm_context_registration(tracer_appsec):
677677
span.span_type = SpanTypes.HTTP
678678
assert core.get_item("asm_env") is not None
679679
assert core.get_item("asm_env") is None
680+
681+
682+
def test_required_addresses():
683+
with override_env(dict(DD_APPSEC_RULES=RULES_GOOD_PATH)):
684+
processor = AppSecSpanProcessor()
685+
686+
assert processor._addresses_to_keep == {
687+
"grpc.server.request.message",
688+
"http.client_ip",
689+
"server.request.body",
690+
"server.request.cookies",
691+
"server.request.headers.no_cookies",
692+
"server.request.path_params",
693+
"server.request.query",
694+
"server.response.headers.no_cookies",
695+
"usr.id",
696+
}
697+
698+
processor._update_rules(
699+
{
700+
"custom_rules": [
701+
{
702+
"conditions": [
703+
{
704+
"operator": "match_regex",
705+
"parameters": {
706+
"inputs": [{"address": "server.request.method"}],
707+
"options": {"case_sensitive": False},
708+
"regex": "GET",
709+
},
710+
}
711+
],
712+
"id": "32b243c7-26eb-4046-adf4-custom",
713+
"name": "test required",
714+
"tags": {"category": "attack_attempt", "custom": "1", "type": "custom"},
715+
"transformers": [],
716+
}
717+
]
718+
}
719+
)
720+
721+
assert processor._addresses_to_keep == {
722+
"grpc.server.request.message",
723+
"http.client_ip",
724+
"server.request.body",
725+
"server.request.cookies",
726+
"server.request.headers.no_cookies",
727+
"server.request.method", # New required address
728+
"server.request.path_params",
729+
"server.request.query",
730+
"server.response.headers.no_cookies",
731+
"usr.id",
732+
}

0 commit comments

Comments
 (0)