http filter: add CSRF filter#6470
Merged
mattklein123 merged 18 commits intoenvoyproxy:masterfrom Apr 23, 2019
Merged
Conversation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Signed-off-by: Derek Schaller dschaller@lyft.com
For an explanation of how to fill out the fields, please see the relevant section
in PULL_REQUESTS.md
Description: Add a Cross-Site Request Forgery filter
Risk Level: Low
Testing: Change includes unit and integration tests and I manually tested the filter as well.
Docs Changes: Included
Release Notes: Included
Fixes #245
Cross-Site Request Forgery (CSRF) HTTP Filter
CSRF (also known as XSRF, Sea Surf, and Session Riding) is an attack that occurs when a malicious third-party exploits a vulnerability (generally through social engineering) that allows them to submit a malicious request on the user’s behalf. The request relies on the victim having a valid session on the destination site and utilizes this to assume the identity and permissions of the user.
Possible Mitigation Patterns
There are a few different popular mitigation patterns that exist and some of those are either entirely stateful or have a stateful option. For purposes of this feature I am going to ignore the stateful patterns and focus on the stateless ones. This is because we don’t want to introduce state management into Envoy if there is another option which is just as secure.
A common pattern to mitigate CSRF attacks is utilizing tokens that help discern requests made by the user versus requests made by a malicious third-party. This approach is the most popular and is the recommended approach by OWASP. There are three approaches here, the synchronizer token pattern, encryption based token pattern, or HMAC based token pattern. All three of these work by generating a cryptographically secure token that is associated with the user’s current session. This token is embedded into the HTML and/or added to request headers/parameters and submitted to the server which is responsible for verifying the existence and validity of this token. The main difference between the three approaches is the data that is used in generating the secure token and how the token is verified. The synchronizer pattern generates a token per session or request and therefore validates the submitted token using the stored value. The encryption pattern generates a token using the user’s ID, timestamp, and nonce and validates the submitted token by validating it and comparing any potentially stored user ID to the submitted one and checking that the timestamp is still valid. The HMAC pattern is similar to the encryption pattern with the exception that it uses a strong HMAC function and includes an additional field for the operation a request is performing.
Another stateless pattern to mitigate CSRF attacks is origin verification. This mechanism works by determining the origin of a request submitted to the server and comparing it against the origin of the request’s destination. If they both match the server accepts the request as valid and if they do not the server throws the request away. The server determines the origin of a request by first using the Origin header, if it is present. The reason for it’s priority is that it will be present in HTTP requests that originate from a HTTPS URL; unlike the Referer header. However, if the Origin header is not present the Referer header is used as a fallback and if neither are present the request will be blocked. The request’s destination can be determined in a number of ways including adding target origin knowledge to your application, using the Host header, or using the X-Forwarded-Host header. The addition of target origin logic into the application directly is the most secure approach as it lives on the server and therefore is a trusted value. Reliance on headers can seem like a potential pitfall but this pattern works because the relied on headers can only be set by browsers as they are on the forbidden headers list. This means that they cannot be altered programmatically by a malicious third-party. This pattern has drawbacks including its reliance on the behavior of external technology and the potential for the Origin header not being included or being set to null.
One more promising mitigation pattern is utilizing the Samesite cookie attribute. This attribute on a cookie can be set to either Strict or Lax. If set to Strict browsers will not attach the cookie to any cross-site requests. If set to Lax the cookie would be attached to any top-level navigation cross-site request that uses a “safe” HTTP method. However, this approach has some known exploits such as malicious third-parties triggering top-level navigations or opening new windows and prerendering. Also, this attribute is relatively new and therefore is not widely supported by all browsers.
Chosen Mitigation Pattern
When assessing both potential mitigation patterns you can see some obvious pros for token based patterns. It is the recommended OWASP approach, it is the most secure, it has the least number of dependencies on assumptions from external technologies. However, it’s main drawback is that it relies on developers remembering to incorporate generated tokens in forms when submitted. This additional overhead in large scale operations is likely to result in engineers forgetting to submit this token. Moving concern from services and into the Envoy layer entirely adds the advantage that CSRF can be dropped into existing architectures that utilize Envoy for their networking layer. Additionally, this eliminates the need to manage handling of key rotation when the secret key is swapped out. While it’s not ideal to rely on behavior of external technology (namely the Origin header) since this header is relied on for other functionality it seems like a safe assumption this value won’t change in the near future.
Implementation
An HTTP filter will be added to Envoy that will parse incoming requests to determine their origin. This will be done by first checking for the presence of an Origin header and grabbing it’s value if present. In the absence of this header the filter will check for the Referer header and, if available, grab it’s value. In the scenario where both are absent the request will be rejected. Upon rejection a 403 will be returned to the client. If one or both headers are present we will determine the destination origin using the
The filter assumes that consumers aren’t using GET requests for state changing operations, which would violate RFC2616, section 9.1.1.