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

#2116 Escaping unsafe pattern values of Regex constructor ​​derived from URL query parameter values containing special Regex chars #2150

Merged
merged 7 commits into from
Sep 20, 2024

Conversation

int0x81
Copy link
Contributor

@int0x81 int0x81 commented Sep 13, 2024

Fixes #2116

Bug

When the downstream URL was created dynamically by a path like api/{path} and the URL contained malicious characters, the request might result in a 500 response from the server. This happened because malicious characters were used for dynamic Regex creation.

Solution

All parameters that are used for template replacements are now Regex-escaped before they are used in the Regex constructor.

@raman-m raman-m changed the title Bugfix for Issue 2116 #2116 Escaping unsafe pattern values of Regex constructor ​​derived from URL query parameter values containing unsafe regexp chars Sep 13, 2024
@raman-m raman-m added bug Identified as a potential bug Routing Ocelot feature: Routing labels Sep 13, 2024
@raman-m raman-m added this to the v23.3 Hotfixes milestone Sep 13, 2024
@raman-m raman-m changed the title #2116 Escaping unsafe pattern values of Regex constructor ​​derived from URL query parameter values containing unsafe regexp chars #2116 Escaping unsafe pattern values of Regex constructor ​​derived from URL query parameter values containing special Regex chars Sep 13, 2024
@raman-m
Copy link
Member

raman-m commented Sep 13, 2024

Hello Finn!
Welcome to the world of Ocelot! 🐅
Thank you for creating the PR!

Could we please scan the codebase and other Regex constructors for potentially similar issues?
This search query will help you...

Copy link
Member

@raman-m raman-m left a comment

Choose a reason for hiding this comment

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

test/Ocelot.AcceptanceTests/PathToDownstreamUrlTests.cs Outdated Show resolved Hide resolved
test/Ocelot.AcceptanceTests/PathToDownstreamUrlTests.cs Outdated Show resolved Hide resolved
Copy link
Member

@ggnaegi ggnaegi left a comment

Choose a reason for hiding this comment

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

Hello, sound for me! Thanks a lot @int0x81!

Comment on lines +616 to +617
[InlineData("api/debug()")] // no query
[InlineData("api/debug%28%29")] // debug()
Copy link
Member

@raman-m raman-m Sep 19, 2024

Choose a reason for hiding this comment

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

TODO Special chars in values of query strings

Hello @ggnaegi,
I would like to delay my approval until we have made a decision on the additional test case:

Suggested change
[InlineData("api/debug()")] // no query
[InlineData("api/debug%28%29")] // debug()
[InlineData("api/debug()")] // no query
[InlineData("api/debug%28%29")] // encoded debug()
[InlineData("api/debug()?special=(\\,*,+,?,|,{,},[,],(,),^,$,.,#, ,)&2=(2)&3=[3]&4={4}")] // with query

The third test has revealed issues within the middleware logic, indicating that this test case is likely to fail. The MergeQueryStringsWithoutDuplicateValues method struggles to handle URLs containing query strings with special characters, such as Regex patterns and reserved URL specification characters. This issue became apparent in release 20.0.0 during the refactoring of the MergeQueryStringsWithoutDuplicateValues method, which aimed to integrate existing and new logic (for example OData filters in query parameters, with bug fixes, with new feature for query string placeholders). Regrettably, the method fails to process special characters in parameter values.

Would you recommend addressing the design bottleneck within this bug fix, or would creating a new TODO task be a better approach to ensure the current release proceeds without delay?

Copy link
Member

@raman-m raman-m Sep 19, 2024

Choose a reason for hiding this comment

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

If you don't mind I will submit a small code-review commit... → 0c150e5

Copy link
Member

@ggnaegi ggnaegi Sep 19, 2024

Choose a reason for hiding this comment

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

@raman-m the whole thing is a mess, @int0x81 who is new to ocelot said straight away that the implementation could be optimized. For now, I would suggest merging the current changes, refactorings are out of scope in my opinion. @int0x81 would be happy to create a follow up issue and PR.

Copy link
Member

@raman-m raman-m left a comment

Choose a reason for hiding this comment

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

It looks good to me!
I've marked the message as the follow-up TODO task.
@ggnaegi, because you're Assignee and if we're done, please press the magic Squash button 🪄

@ggnaegi ggnaegi merged commit 58d87c9 into ThreeMammals:develop Sep 20, 2024
1 check passed
@ggnaegi
Copy link
Member

ggnaegi commented Sep 20, 2024

Squashed and Merged it is!

@int0x81 int0x81 deleted the bugfix/2116_regex_handling branch September 21, 2024 11:53
raman-m added a commit that referenced this pull request Oct 3, 2024
…Blue Olympic Balumbes release

* #2084 Apply default config file paths in `GetMergedOcelotJson` when providing the `folder` argument of `AddOcelot` (#2120)

* Adding unit test first

* Fixing default global config file not being found in folder

* Adding PR trait to test

* Backing out whitespace changes

* Code review by @raman-m

* Create Configuration feature folder and move test classes

* Adjust namespace and review what we have

* Acceptance tests for #2084 user scenario

---------

Co-authored-by: Raman Maksimchuk <[email protected]>

* Bump Steeltoe.Discovery.Eureka from 3.2.5 to 3.2.8 in /src/Ocelot.Provider.Eureka (#2122)

* Bump Steeltoe.Discovery.Eureka in /src/Ocelot.Provider.Eureka

Bumps [Steeltoe.Discovery.Eureka](https://github.com/SteeltoeOSS/Steeltoe) from 3.2.5 to 3.2.8.
- [Release notes](https://github.com/SteeltoeOSS/Steeltoe/releases)
- [Changelog](https://github.com/SteeltoeOSS/Steeltoe/blob/main/Steeltoe.Release.ruleset)
- [Commits](SteeltoeOSS/Steeltoe@3.2.5...3.2.8)

---
updated-dependencies:
- dependency-name: Steeltoe.Discovery.Eureka
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* Bump Steeltoe.Discovery.ClientCore from 3.2.5 to 3.2.8

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Raman Maksimchuk <[email protected]>

* #2110 Review load balancing and independent fetching the list of services in `Kube` provider (#2111)

* Move the creation of the services list from the class field to the method, to prevent modification list from different threads

* Early return after data checking

* Add unit test for concurrent get list of services

* Add logging for invalid service configuration error in RoundRobin load balancer

* Code review by @raman-m

* Workaround for mistakes made during acceptance testing of load balancing versus service discovery, where tests designed for parallel requests were mistakenly executed sequentially. This resulted in load balancers being loaded by sequential `HttpClient` calls, which was a significant oversight.

* Let's DRY StickySessionsTests

* Add acceptance tests, but...
RoundRobin is not actually RoundRobin 😁 -> 😆

* Independent static indexing iterators per route via service names

* Stabilize `CookieStickySessions` load balancer.
Review tests after refactoring of `RoundRobin` load balancer

* Refactor Lease operation for load balancing.
Review LeastConnection load balancer

* Leasing mechanism in Round Robin load balancer

* Acceptance tests, final version

* Apply Retry pattern for K8s endpoint integration

* Fix IDE warnings and messages

* Follow suggestions and fix issues from code review by @ggnaegi

* Bump KubeClient from 2.4.10 to 2.5.8

* Fix warnings

* Final version of `Retry` pattern

---------

Co-authored-by: Raman Maksimchuk <[email protected]>

* Downgrade the Warning to Information on missing `Content-Length` header in `MultiplexingMiddleware` (#2146)

* fix: downgrade the warning to information on missing content-length header

* chore: add route name to logs

* test: fixing multiplexing middleware tests

* Code review by @raman-m

---------

Co-authored-by: Paul Roy <[email protected]>
Co-authored-by: Raman Maksimchuk <[email protected]>

* Correct the broken link to the GraphQL sample's `README.md` (#2149)

Signed-off-by: Emmanuel Ferdman <[email protected]>
Co-authored-by: Raman Maksimchuk <[email protected]>

* #2116 Escaping unsafe pattern values of `Regex` constructor ​​derived from URL query parameter values containing special `Regex` chars (#2150)

* regex escape handling for url templates

* refactored regex method to lamda version

* Quick code review by @raman-m

* added acceptance test for url regex bug

* moved acceptance test to routing tests

* Convert to theory: define 2 test cases

---------

Co-authored-by: Raman Maksimchuk <[email protected]>

* #2119 Review load balancing (2nd round) and redesign `DefaultConsulServiceBuilder` with `ConsulProviderFactory` refactoring to make it thread safe and friendly (#2151)

* Review tests

* History of Service Discovery testing: add traits

* LoadBalancer traits

* #2119 Steps to Reproduce

* Reuse service handlers of `ConcurrentSteps`

* Reuse service counters of `ConcurrentSteps`

* Add LoadBalancer namespace and move classes

* Move `Lease`

* Move `LeaseEventArgs`

* Analyze load balancers aka `ILoadBalancerAnalyzer` interface objects

* Prefer using named local methods as delegates over anonymous methods for awesome call stack, ensuring the delegate's typed result matches the typed balancer's creator. Additionally, employ an IServiceProvider workaround.

* Review load balancing. Assert service & leasing counters as concurrent step. Final version of acceptance test.

* Fixed naming violation for asynchronous methods: `Lease` -> `LeaseAsync`

* Fix ugly reflection issue of dymanic detection in favor of static type property

* Propagate the `ConsulRegistryConfiguration` object through `HttpContext` in the scoped version of the default service builder, utilizing the injected `IHttpContextAccessor` object.
Update `ConsulProviderFactory`.
Update docs.
Update tests.

* Add tests from clean experiment

* Final review of the tests

* Review `IHttpContextAccessor` logic.
Convert anonymous delegates to named ones in placeholders processing

* Tried to enhance more, but failed

---------

Signed-off-by: dependabot[bot] <[email protected]>
Signed-off-by: Emmanuel Ferdman <[email protected]>
Co-authored-by: Ben Bartholomew <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Roman <[email protected]>
Co-authored-by: Paul Roy <[email protected]>
Co-authored-by: Paul Roy <[email protected]>
Co-authored-by: Emmanuel Ferdman <[email protected]>
Co-authored-by: Finn <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Identified as a potential bug Routing Ocelot feature: Routing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Regex exception when route template placeholder contains invalid character )
3 participants