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

Matching engine: add a cookie matching input object (revival) #21496

Closed
wants to merge 23 commits into from

Conversation

aguinet
Copy link
Contributor

@aguinet aguinet commented May 29, 2022

(Revival of #16344)

Commit Message: Matching: add HttpRequestCookieMatchInput data input
Additional Description:

This allows matching data extracted from cookies. It also adds a new parseCookieValues API in Http::Utility, which allows to return the potential multiple values that could be set in malicious HTTP requests, like in this case:

Cookie: mykey=a;mykey=b

To be in pair with what is already done with the HTTP header input matcher, this input matcher returns, in this case, a,b.

I've done only the request side, but if these patches are fine for you, I can also add the response side, and factorize the code in a similar way that what's done for headers!

Risk Level: Low
Testing: adapting current unit tests
Docs Changes: New API in Http::Testing documented
Release Notes:
Platform Specific Features:
[Optional Runtime guard:]
[Optional Fixes #Issue]
[Optional Deprecated:]
[Optional API Considerations:]

aguinet added 19 commits May 5, 2021 22:12
Create a parseCookieValues API that returns all the values that are
potentially set for a cookie key. This could be done in malicious
requests that try to bypass some filters.

Moreover, modify parseCookieValue's API to use string_view objects.
Indeed, the data from the "Cookies" headers is never transformed, only a
view of it is returned.

Signed-off-by: Adrien Guinet <adrien@reblaze.com>
This allows matching data extracted from cookies.

Signed-off-by: Adrien Guinet <adrien@reblaze.com>
TODO: split this commit in two and squash it into the first two ones

Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Thanks clang-tidy!

Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Copy link
Contributor

@snowp snowp left a comment

Choose a reason for hiding this comment

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

Overall this seems good to me, main question I have is around the common code interface changes

Comment on lines 341 to 343
// max_vals == 0 => infinity, so the condition above will never be true
// in this case.
if (ret.size() == max_vals) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If we default to std::numeric_limits::max instead of treating 0 as special I think this logic would seem a bit cleaner

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in b7f3479

@@ -300,9 +301,25 @@ absl::flat_hash_map<std::string, std::string> parseCookies(const RequestHeaderMa
* Parse a particular value out of a set-cookie
* @param headers supplies the headers to get the set-cookie from.
* @param key the key for the particular set-cookie value to return
* @return std::string the parsed set-cookie value, or "" if none exists
* @return absl::string_view the parsed set-cookie value, or "" if none exists
Copy link
Contributor

Choose a reason for hiding this comment

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

Here and below please document the lifetime of the returned string views

More generally I'd see if there are any concerns about this interface switch, given that a std::string ends up being a bit safer than a string_view, cc @alyssawilk @mattklein123

Copy link
Member

Choose a reason for hiding this comment

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

I'm OK with it, though I agree it makes the function more prone to error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe the safest option for now is indeed to keep std::string. I will revert back to that API.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in b7f3479

* cleaner API for the max_vals argument of parseCookieValues
* get back to using std::string for the return value(s) of the parseCookie* functions

Signed-off-by: Adrien Guinet <adrien@reblaze.com>
@repokitteh-read-only
Copy link

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to (api/envoy/|docs/root/api-docs/).
envoyproxy/api-shepherds assignee is @mattklein123
CC @envoyproxy/api-watchers: FYI only for changes made to (api/envoy/|docs/root/api-docs/).

🐱

Caused by: #21496 was synchronize by aguinet.

see: more, trace.

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

API LGTM with small comment, thanks.

/wait

@@ -60,3 +60,17 @@ message HttpResponseTrailerMatchInput {
string header_name = 1
[(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME strict: false}];
}

// Match input indicates that matching should be done on a specific cookie key.
Copy link
Member

Choose a reason for hiding this comment

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

Please add a release note for this new feature. @kyessenov what do we need to do to get this matcher to show up in the docs? I forget where we landed on this in terms of what is an extension category, etc.

Copy link
Contributor

Choose a reason for hiding this comment

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

  1. Add the new extension to the list of extensions in extension_manifest.yaml. Tag it as implementing the HTTP matcher category.
  2. Add a comment to the proto as in // [#extension: envoy.matching.inputs.cookies]
  3. Reference the extension here: https://github.com/envoyproxy/envoy/blob/main/docs/root/intro/arch_overview/advanced/matching/matching_api.rst#http-input-functions.

I'm working to get (1)-(2) validated once we merge #21413.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @kyessenov for this! Done in 3930b3a

aguinet added 2 commits June 27, 2022 20:33
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
Signed-off-by: Adrien Guinet <adrien@reblaze.com>
@zuriby
Copy link

zuriby commented Jul 1, 2022

@aguinet can you take a quick look what else is missing to get it in?

@github-actions
Copy link

This pull request has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@github-actions github-actions bot added the stale stalebot believes this issue/PR has not been touched recently label Jul 31, 2022
@github-actions
Copy link

github-actions bot commented Aug 7, 2022

This pull request has been automatically closed because it has not had activity in the last 37 days. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@github-actions github-actions bot closed this Aug 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api stale stalebot believes this issue/PR has not been touched recently waiting
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants