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

Add mechanism for early http header validation #92220

Merged
merged 54 commits into from
Mar 31, 2023

Conversation

Tim-Brooks
Copy link
Contributor

Currently we only check the http header objections after the full request has
been read. This commit offers the ability to validate the headers prior to
reading the full message and short circuit as appropriate.

@Tim-Brooks Tim-Brooks added >non-issue :Distributed Coordination/Network Http and internode communication implementations v8.7.0 labels Dec 8, 2022
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-distributed (Team:Distributed)

@elasticsearchmachine elasticsearchmachine added the Team:Distributed (Obsolete) Meta label for distributed team (obsolete). Replaced by Distributed Indexing/Coordination. label Dec 8, 2022
Comment on lines 58 to 63
} else if (state == STATE.FORWARDING_DATA) {
assert pending.isEmpty();
if (httpObject instanceof LastHttpContent) {
state = STATE.WAITING_TO_START;
}
ctx.fireChannelRead(httpObject);
Copy link
Contributor

Choose a reason for hiding this comment

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

Background

Security is used to convey the authentication information (when successful) in thread-local variables that we call the threadContext.
In essence, all the code that's run by a thread with some authentication information in the threadContext is said to run "as" the "subject" from that authentication information.
Today, the SecurityRestFilter sets and clears the threadContext, in a try-block, before and after executing the request handler.

Question

Assuming authentication is successful, and here we're forwarding httpObjects to the next pipeline handler. We need to ensure that the threadContext contains the authentication information, when the complete request gets to the RestController.

Is is correct to set the threadContext to contain the authentication when we forward the LastHttpContent message?

I think the downstream pipeline handler, upon seeing this message will assemble the complete request and forward it further, under the same thread call stack, i.e. not enqueue it, like it does with the other httpObjects and wait for some other event to forward the complete request, in which case the threadContext will not be populated correctly.

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. We cannot propagate this through thread locals at this point. As additional context switching could happen. If there is information from Authentication that we need to propagate, the Validator will have to return it and we can find some mechanism to shove it in the http request object until "handling" where we can set the thread context.

Copy link
Contributor

Choose a reason for hiding this comment

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

we can find some mechanism to shove it in the http request object until "handling" where we can set the thread context.

We discussed to wrap and decorate the HttpRequest that we forward with the authn result. That looks good, but the problem is that the HttpRequest is not available from the FullHttpRequest that the RestController ultimately deals with, so it cannot get hold of the authn result either (in order to set it in the thread context that runs the request handler).
In order to expose the authn result to the FullHttpRequest we'll need to extend the HttpObjectAggregator slightly (more precisely extend #beginAggregation to return an implementation of FullHttpMessage that contains the authn result from the HttpMessage start parameter).

I'm going to try implementing this.

@albertzaharovits
Copy link
Contributor

@Tim-Brooks I'm going to push to this branch of yours in order to get it merged.
The intent is for it to work to support the strategy described in #93656 .

Let me know if you prefer I create a branch on my fork, incorporate the changes here, and iterate on that instead.

@albertzaharovits albertzaharovits self-assigned this Mar 8, 2023
@albertzaharovits
Copy link
Contributor

@Tim-Brooks This is ready for your review.

I'll be adding a few more tests soon, but I think this is now looking very polished.

@albertzaharovits
Copy link
Contributor

albertzaharovits commented Mar 28, 2023

ping @Tim-Brooks

}
})
.addLast("aggregator", aggregator);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can we remove this formatting change?

Copy link
Contributor

Choose a reason for hiding this comment

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

I've pushed d6d7b87 to stuff some inline comments following an addLast such that spotless doesn't kick in to combine multiple addLast on the same line.

Copy link
Contributor Author

@Tim-Brooks Tim-Brooks left a comment

Choose a reason for hiding this comment

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

One minor request

@Tim-Brooks
Copy link
Contributor Author

LGTM

Copy link
Contributor

@jakelandis jakelandis left a comment

Choose a reason for hiding this comment

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

Note - I only have a surface level understanding of the change. However since this was join effort by Tim and Albert I wanted to provided a 3rd party approval.

@albertzaharovits albertzaharovits self-requested a review March 30, 2023 17:34
Copy link
Contributor

@albertzaharovits albertzaharovits left a comment

Choose a reason for hiding this comment

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

LGTM 💯

@albertzaharovits albertzaharovits merged commit 2ac20c0 into elastic:main Mar 31, 2023
albertzaharovits added a commit to albertzaharovits/elasticsearch that referenced this pull request Jun 8, 2023
This introduces a way to validate HTTP headers prior to reading
the request body.

Co-authored-by: Albert Zaharovits <[email protected]>
albertzaharovits added a commit that referenced this pull request Aug 23, 2023
This is a backport of multiple work items related to authentication enhancements for HTTP,
which were originally merged in the 8.8 - 8.9 releases.
Hence, the HTTP (only the netty4-based implementation (default), not the NIO one) authentication
implementation gets a throughput boost (especially for requests failing authn).

Relates to: ES-6188 #92220 #95112
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Distributed Coordination/Network Http and internode communication implementations >non-issue Team:Distributed (Obsolete) Meta label for distributed team (obsolete). Replaced by Distributed Indexing/Coordination. v8.8.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants