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

fix(#8868): don't forward all headers for get requests #8924

Merged
merged 9 commits into from
Mar 14, 2024

Conversation

dianabarsan
Copy link
Member

@dianabarsan dianabarsan commented Mar 12, 2024

Description

Node 19 adds keep-alive header to requests by default. This makes the content-length header very significant and important because it enables the server to know when one request has been fully received and another one is sent through the same connection.
When authenticating a user, we take all headers from the original user's request and pass them to a GET /_session request, presumably so we don't have to filter out all the ways through which the user can authenticate (cookie, authorization etc). This meant that if the original request was a POST, and it had a content-length header, this header was also forwarded. This meant that when the connection would later be reused, the server (haproxy in this case) would truncate the previous's request content-length number of characters from the next request, believing the previous request was not finished. Obviously, this new truncated request was invalid and generated a 400 status code.

This only seems to happen when accessing API directly or through the AWS load balancer, and never when running requests through nginx.

To avoid next request truncation, I am no longer forwarding content-length headers in the session request.

#8868

Code review checklist

  • Readable: Concise, well named, follows the style guide, documented if necessary.
  • Documented: Configuration and user documentation on cht-docs
  • Tested: Unit and/or e2e where appropriate
  • Internationalised: All user facing text
  • Backwards compatible: Works with existing data and configuration or includes a migration. Any breaking changes documented in the release notes.

Compose URLs

If Build CI hasn't passed, these may 404:

License

The software is provided under AGPL-3.0. Contributions to this project are accepted under the same license.

@dianabarsan
Copy link
Member Author

Added an e2e test to demonstrate fixed behavior, and an opposite e2e test here: https://github.com/medic/cht-core/compare/test-login?expand=1 that shows the 400 request: https://github.com/medic/cht-core/actions/runs/8274351579/job/22639815092#step:17:286

@dianabarsan dianabarsan requested a review from latin-panda March 14, 2024 02:30
@dianabarsan
Copy link
Member Author

Hi @latin-panda

Would you mind reviewing this? Thanks a lot!

Copy link
Contributor

@latin-panda latin-panda left a comment

Choose a reason for hiding this comment

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

LGTM!

Thanks for explaining in the PR's description box, I learned from it!

api/tests/mocha/auth.spec.js Show resolved Hide resolved
@dianabarsan dianabarsan merged commit 831bd6e into master Mar 14, 2024
30 checks passed
@dianabarsan dianabarsan deleted the 8868-dont-forward-all-headers-for-get branch March 14, 2024 17:48
dianabarsan added a commit that referenced this pull request Mar 14, 2024
Node 19 adds keep-alive header to requests by default. This makes the content-length header very significant and important because it enables the server to know when one request has been fully received and another one is sent through the same connection.
When authenticating a user, we take all headers from the original user's request and pass them to a GET /_session request, presumably so we don't have to filter out all the ways through which the user can authenticate (cookie, authorization etc). This meant that if the original request was a POST, and it had a content-length header, this header was also forwarded. This meant that when the connection would later be reused, the server (haproxy in this case) would truncate the previous's request content-length number of characters from the next request, believing the previous request was not finished. Obviously, this new truncated request was invalid and generated a 400 status code.

This only seems to happen when accessing API directly or through the AWS load balancer, and never when running requests through nginx.

To avoid next request truncation, I am no longer forwarding content-length headers in the session request.

#8868

(cherry picked from commit 831bd6e)
dianabarsan added a commit that referenced this pull request Mar 15, 2024
Node 19 adds keep-alive header to requests by default. This makes the content-length header very significant and important because it enables the server to know when one request has been fully received and another one is sent through the same connection.
When authenticating a user, we take all headers from the original user's request and pass them to a GET /_session request, presumably so we don't have to filter out all the ways through which the user can authenticate (cookie, authorization etc). This meant that if the original request was a POST, and it had a content-length header, this header was also forwarded. This meant that when the connection would later be reused, the server (haproxy in this case) would truncate the previous's request content-length number of characters from the next request, believing the previous request was not finished. Obviously, this new truncated request was invalid and generated a 400 status code.

This only seems to happen when accessing API directly or through the AWS load balancer, and never when running requests through nginx.

To avoid next request truncation, I am no longer forwarding content-length headers in the session request.

#8868

(cherry picked from commit 831bd6e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants