-
Notifications
You must be signed in to change notification settings - Fork 145
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ASM] Context disposed related exceptions when calling the WAF (#6529)
## Summary of changes We are getting (on netcore only) s[ome ObjectDisposedExceptions](https://app.datadoghq.com/logs?query=source%3Adotnet%20%2AAppSec%2A%20%2Aobjectdisposed%2A&agg_m=count&agg_m_source=base&agg_t=count&clustering_pattern_field_path=message&cols=host%2Cservice&fromUser=true&messageDisplay=inline&refresh_mode=sliding&storage=hot&stream_sort=desc&viz=stream&from_ts=1736611522812&to_ts=1736784322812&live=true) when calling the WAF. Some stack examples: ``` System.ObjectDisposedException at Microsoft.AspNetCore.Http.Features.FeatureReferences`1.ThrowContextDisposed() at Microsoft.AspNetCore.Http.DefaultHttpResponse.get_StatusCode() at Datadog.Trace.AppSec.Coordinator.SecurityCoordinator.HttpTransport.get_StatusCode() at Datadog.Trace.AppSec.Coordinator.SecurityCoordinator.RunWaf(Dictionary`2 args, Boolean lastWafCall, Boolean runWithEphemeral, Boolean isRasp) System.ObjectDisposedException at Microsoft.AspNetCore.Http.Features.FeatureReferences`1.ThrowContextDisposed() at Microsoft.AspNetCore.Http.DefaultHttpContext.get_Items() at Datadog.Trace.AppSec.Coordinator.SecurityCoordinator.HttpTransport.get_ReportedExternalWafsRequestHeaders() at Datadog.Trace.AppSec.Coordinator.SecurityCoordinator.TryReport(IResult result, Boolean blocked, Nullable`1 status) at Datadog.Trace.AppSec.Coordinator.SecurityCoordinator.ReportAndBlock(IResult result) ``` The number of orgs that suffer from it is small. It seems that we are tying to access the HttpContext after disposal. This launches an exception when trying to access the features of the context. The method Uninitialize() of the class DefaultHttpContext is called when the request finishes: ``` public void Uninitialize() { _features = default; _request.Uninitialize(); _response.Uninitialize(); _connection?.Uninitialize(); _websockets?.Uninitialize(); _active = false; } public override IFeatureCollection Features => _features.Collection ?? ContextDisposed(); ``` When we try to access some values from the context such as the return code, we eventually get this exception. Why this could happen? Two possible explanations have been identified: 1) Manual call to the method Uninitialize of DefaultHttpContext. While it's not commonly called, this method can be actually called from the controller because it's public. 2) Racing conditions. If we launch some threads in a controller that, for instance, read files. RASP will try to call the WAF. These threads might be still running after the request has been closed. While RASP checks for closed spans, it could happen that RASP would call the WAF at the same time as the request and span closes. If we detect that the context has been uninitialized, we should stop using it. Unfortunately, there is no reliable way to detect if the context is disposed before getting it's features. In the previous Uninitialize method, the field _active is private. We cannot get the features without getting the exception and the fields _response, _request, _connection and _websockets set their features to default, but these feature fields are not exposed. Given that, we can only capture the exception and assume that the context has been disposed and we should not try to access it anymore (or use reflection). Some sample code has been added to our sample pages in order to reproduce the situation. In .net framework, we are not getting these exceptions when trying to access the context with a similar code. This is consistent with the results got from the telemetry logs. While we are accessing the context in several parts of our code, it seems that all the exceptions observed were thrown in the method RunWaf(). No other ObjectDisposed exception was found out of this scope so, for now, we are protecting only this part of the code. The sample code that calls the manual uninitialization of the tracer would also make the Asp.Netcore framework to launch an exception after finishing the request. This exception prevents the tracer to close the root span. ## Reason for change ## Implementation details ## Test coverage ## Other details <!-- Fixes #{issue} --> <!--⚠️ Note: where possible, please obtain 2 approvals prior to merging. Unless CODEOWNERS specifies otherwise, for external teams it is typically best to have one review from a team member, and one review from apm-dotnet. Trivial changes do not require 2 reviews. -->
- Loading branch information
1 parent
ab90a2d
commit 27f35a0
Showing
9 changed files
with
226 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.