-
Notifications
You must be signed in to change notification settings - Fork 10
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
Block based on response status or headers #171
base: master
Are you sure you want to change the base?
Conversation
elif http_version == 3: | ||
version_arg = "--http3-only" | ||
else: | ||
raise Exception(f"Unknown HTTP version: {http_version}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⚪ Code Quality Violation
Exception is too generic (...read more)
Do not raise Exception
and BaseException
. These are too generic. Having generic exceptions makes it difficult to differentiate errors in a program. Use a specific exception, for example, ValueError
, or create your own instead of using generic ones.
Learn More
@@ -1,9 +1,10 @@ | |||
from alpine:3.19 | |||
FROM alpine/curl-http3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟠 Code Quality Violation
always pin version to an image spec (...read more)
This rule dictates that Docker images should always be tagged with a specific version number. In Docker, an image tag represents a particular version of an image. The use of tags allows developers to have better control over which versions of an image are being used in their projects.
This is crucial because it ensures the consistency and reliability of the Docker environment. If an image is not tagged, Docker defaults to using the 'latest' version of the image. However, the 'latest' tag does not guarantee that the same version of an image will be used every time, which can lead to unexpected behavior or compatibility issues.
To comply with this rule, always specify a version number when pulling a Docker image. Instead of FROM debian
, write FROM debian:unstable
or FROM debian:10.3
. This ensures that you are using a specific version of the image, providing a more predictable and stable environment for your project.
Looks unnecessary once the full header filter chain is run.
c0cbf4c
to
2820009
Compare
@cataphract We're not part of the same team or even the same organization. Given that, providing some context upfront can help set the stage for those reviewing your PR. A bit of background on what it does and why it’s needed would go a long way in ensuring a smoother review process. Could you, please, share more details? |
Fixes refcount management and use-after-frees. Prefers to call ngx_http_finalize_request() with NGX_OK rather than NGX_DONE so that filter finalization, subrequest post actions, lingering close, and keepalive logic are respected.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #171 +/- ##
==========================================
- Coverage 71.87% 71.25% -0.62%
==========================================
Files 44 44
Lines 6190 6683 +493
Branches 899 948 +49
==========================================
+ Hits 4449 4762 +313
- Misses 1305 1466 +161
- Partials 436 455 +19
|
@dmehala I've added a description now. It was meant to be a draft PR; I opened it to run the pipelines. |
try { | ||
const urlObj = new URL(request.url, `http://${request.headers.host}`); | ||
const card = parseInt(urlObj.searchParams.get("card")); | ||
const numBouts = parseInt(urlObj.searchParams.get("num_bouts")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⚪ Code Quality Violation
Missing radix parameter. (...read more)
When utilizing the parseInt()
function, many often skip the second parameter (the radix), allowing the function to deduce the number type based on the initial argument. By default, parseInt()
can recognize both decimal and hexadecimal numbers, the latter through the 0x
prefix. However, before ECMAScript 5, the function also mistakenly recognized octal numbers, leading to issues as many developers presumed a starting 0
would be disregarded.
const urlObj = new URL(request.url, `http://${request.headers.host}`); | ||
const card = parseInt(urlObj.searchParams.get("card")); | ||
const numBouts = parseInt(urlObj.searchParams.get("num_bouts")); | ||
const delay = parseInt(urlObj.searchParams.get("delay")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⚪ Code Quality Violation
Missing radix parameter. (...read more)
When utilizing the parseInt()
function, many often skip the second parameter (the radix), allowing the function to deduce the number type based on the initial argument. By default, parseInt()
can recognize both decimal and hexadecimal numbers, the latter through the 0x
prefix. However, before ECMAScript 5, the function also mistakenly recognized octal numbers, leading to issues as many developers presumed a starting 0
would be disregarded.
const sendRepeatResponse = (request, response) => { | ||
try { | ||
const urlObj = new URL(request.url, `http://${request.headers.host}`); | ||
const card = parseInt(urlObj.searchParams.get("card")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⚪ Code Quality Violation
Missing radix parameter. (...read more)
When utilizing the parseInt()
function, many often skip the second parameter (the radix), allowing the function to deduce the number type based on the initial argument. By default, parseInt()
can recognize both decimal and hexadecimal numbers, the latter through the 0x
prefix. However, before ECMAScript 5, the function also mistakenly recognized octal numbers, leading to issues as many developers presumed a starting 0
would be disregarded.
bf9ab76
to
e9066a7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From reading the PR it's quite hard to ascertain if this will work as intended, at least not without spending a similar amount of time it took to write it reviewing it... However aside from a few comments, I don't see any critical issues although some mistakes have been highlighted and should be fixed.
src/security/context.cpp
Outdated
assert(req != nullptr); | ||
|
||
auto *ctx = instance.current_ctx_; | ||
assert(ctx != nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How certain are we about these assertions...? An explicit check may be more prudent otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's not clear is that c->data is the request in http3.
Seeing as this function is very difficult to exercise and the tests don't reach it (the data for the headers is small enough that it isn't sent just yet), I'm changing this to not rely on c->data.
0b6544e
to
7cfce28
Compare
Significantly changes how the hooking mechanism for executing the final WAF run. The purpose is to allow blocking based on the response headers and status that would otherwise be sent.
Previously, we would install only an output filter. By the time it was invoked, the headers would already have been committed. It would not be possible to fully replace the response with another one.
So this PR installs also a header filter. When invoked, this header filter prevents the final filter from committing the response by changing the
send_chain
function pointer, continuing the filter chain and saving the buffers instead (because the filter may not invoke send_chain, it needs also to look at where this data may be buffered: this needs different code for http 1/3 and http/2).Afterwards, it launches the WAF task. While this task is running, any data send to the output buffer is consumed as saved (copied), up to a certain limit. Once this limit is reached, the buffers are not consumed anymore, therefore stalling the output chain with busy buffers.
Once the final WAF task finishes, either a blocking response is committed, fully replacing the headers and body, or, if we're not to block, the buffered headers and body are sent forward (with special logic wrt the headers in http/2, as ngx_http_write_filter() can't send header frames in http/2).
Other changes: