-
Notifications
You must be signed in to change notification settings - Fork 2
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: Frame Injection (azul-private#12) #5035
Fix: Frame Injection (azul-private#12) #5035
Conversation
Codecov Report
@@ Coverage Diff @@
## develop #5035 +/- ##
===========================================
+ Coverage 84.60% 84.71% +0.11%
===========================================
Files 148 149 +1
Lines 18060 18197 +137
===========================================
+ Hits 15280 15416 +136
- Misses 2780 2781 +1
|
3b279b1
to
9521984
Compare
src/azul/chalice.py
Outdated
@@ -116,6 +121,21 @@ def patched_event_source_handler(self_, event, context): | |||
if old_handler.__code__ != patched_event_source_handler.__code__: | |||
chalice.app.EventSourceHandler.__call__ = patched_event_source_handler | |||
|
|||
def _wrapping_middleware(self, event, get_response): |
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.
More descriptive name
def _wrapping_middleware(self, event, get_response): | |
def _error_wrapping_middleware(self, event, get_response): |
src/azul/chalice.py
Outdated
parsed = parse_accept_header(event.headers.get('accept')) | ||
text_html = parsed.find('text/html') | ||
star_star = parsed.find('*/*') | ||
if -1 < text_html and (star_star == -1 or text_html < star_star): |
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.
I think it's more conventional to write the operands in this order. I certainly find it easier to read this way.
if -1 < text_html and (star_star == -1 or text_html < star_star): | |
if text_html > -1 and (star_star == -1 or text_html < star_star): |
9521984
to
01c25a7
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.
Looks good 👍
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.
I'd like to see the tests prove that the original body is HTML-escaped. That's what's ultimately behind all this.
src/azul/chalice.py
Outdated
@@ -116,6 +121,21 @@ def patched_event_source_handler(self_, event, context): | |||
if old_handler.__code__ != patched_event_source_handler.__code__: | |||
chalice.app.EventSourceHandler.__call__ = patched_event_source_handler | |||
|
|||
def _error_wrapping_middleware(self, event, get_response): | |||
response = get_response(event) | |||
if response.status_code >= 400: |
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.
I specified a different condition in the ticket. Please fix or explain the deviation.
src/azul/chalice.py
Outdated
parsed = parse_accept_header(event.headers.get('accept')) | ||
text_html = parsed.find('text/html') | ||
star_star = parsed.find('*/*') | ||
if text_html > -1 and (star_star == -1 or text_html < star_star): |
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.
if text_html > -1 and (star_star == -1 or text_html < star_star): | |
if 0 <= text_html and (star_star < 0 or text_html < star_star): |
src/azul/chalice.py
Outdated
response.body = ( | ||
'<html>' | ||
f'<head>Status {response.status_code}</head>' | ||
f'<body><pre>{html.escape(str(response.body), quote=False)}</pre></body>' |
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.
Explain use of {
and str
. What's the type of response.body
?
test/service/test_response.py
Outdated
unescaped = json.dumps({ | ||
'Code': 'NotFoundError', | ||
'Message': "Unable to find file 'foo', version None in catalog 'test'" | ||
}, separators=(',', ':')) | ||
escaped = ( | ||
"<html><head>Status 404</head><body><pre>{" | ||
"'Code': 'NotFoundError', " | ||
"'Message': \"Unable to find file 'foo', version None in catalog 'test'\"" | ||
"}</pre></body></html>" | ||
) |
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.
This is all very hard to parse and understand. Consider triple-quoted string and textwrap.dedent.
Also don't mix serialized and deserialized literals. Makes it even harder to examine for correctness.
test/service/test_response.py
Outdated
('text/html,*/*', True), | ||
]: | ||
headers = {'accept': accept} | ||
with self.subTest(headers=headers): |
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.
with self.subTest(headers=headers): | |
with self.subTest(accept=accept): |
and swap lines
9a68982
to
a935cdd
Compare
4a68f38
to
bb0e83e
Compare
test/test_content_type.py
Outdated
def route(): | ||
return '<script />' | ||
|
||
# noinspection PyUnusedLocal |
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.
Index: test/test_content_type.py
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/test/test_content_type.py b/test/test_content_type.py
--- a/test/test_content_type.py (revision 145cc0157017310efbc5cbc6dbbfc973970962a5)
+++ b/test/test_content_type.py (date 1681774413142)
@@ -106,8 +106,7 @@
def route():
return '<script />'
- # noinspection PyUnusedLocal
- def expected(debug: bool, wrapped: bool) -> Tuple[str, str]:
+ def expected(_debug: bool, _wrapped: bool) -> tuple[str, str]:
text = '<script />'
content_type = 'application/json'
return text, content_type
https://stackoverflow.com/a/49447358/4171119 is what we usually do in this case.
tuple
is now generic.
d575b28
to
77544d6
Compare
test/test_content_type.py
Outdated
raise ChaliceUnhandledError('<script />') | ||
|
||
def expected(_debug: bool, _wrapped: bool) -> tuple[str, str]: | ||
if _debug: |
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.
Only use _ for unused parameters.
77544d6
to
81b4367
Compare
src/azul/chalice.py
Outdated
those do prefer `text/html`. | ||
""" | ||
response = get_response(event) | ||
ct_key = only(key for key in response.headers |
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.
Wrap all or None.
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.
We typically use k
for key
and then you won't need to wrap.
81b4367
to
cf2a871
Compare
cf2a871
to
d658544
Compare
Connected issues: DataBiosphere/azul-private#12
Checklist
Author
develop
issues/<GitHub handle of author>/<issue#>-<slug>
partial
label to PR or this PR completely resolves all connected issues1 when the issue title describes a problem, the corresponding PR
title is
Fix:
followed by the issue titleAuthor (reindex, API changes)
r
tag to commit title or this PR does not require reindexingreindex
label to PR or this PR does not require reindexinga
(compatible changes) orA
(incompatible ones) tag to commit title or this PR does not modify the Azul service APIAPI
label to connected issues or this PR does not modify the Azul service APIAuthor (chains)
base
label to the blocking PR or this PR is not chained to another PRchained
label to this PR or this PR is not chained to another PRAuthor (upgrading)
u
tag to commit title or this PR does not require upgradingupgrade
label to PR or this PR does not require upgradingAuthor (operator tasks)
Author (hotfixes)
F
tag to main commit title or this PR does not include permanent fix for a temporary hotfixprod
branch has no temporary hotfixes for any connected issuesAuthor (before every review)
develop
, squashed old fixupsmake requirements_update
or this PR does not touch requirements*.txt, common.mk, Makefile and DockerfileR
tag to commit title or this PR does not touch requirements*.txtreqs
label to PR or this PR does not touch requirements*.txtmake integration_test
passes in personal deployment or this PR does not touch functionality that could break the ITPeer reviewer (after requesting changes)
Uncheck the Author (before every review) checklists.
Peer reviewer (after approval)
Primary reviewer (after requesting changes)
Uncheck the before every review checklists. Update the
N reviews
label.Primary reviewer (after approval)
demo
orno demo
no demo
no sandbox
N reviews
label is accurateOperator (before pushing merge the commit)
reindex
label andr
commit title tagno demo
develop
dev
and addedsandbox
label or PR is labeledno sandbox
anvildev
or PR is labeledno sandbox
sandbox
deployment or PR is labeledno sandbox
anvilbox
deployment or PR is labeledno sandbox
sandbox
deployment or PR is labeledno sandbox
anvilbox
deployment or PR is labeledno sandbox
sandbox
or this PR does not remove catalogs or otherwise causes unreferenced indicesanvilbox
or this PR does not remove catalogs or otherwise causes unreferenced indicessandbox
or this PR does not require reindexingsandbox
anvilbox
or this PR does not require reindexingsandbox
sandbox
or this PR does not require reindexingsandbox
anvilbox
or this PR does not require reindexingsandbox
Operator (after pushing the merge commit)
base
dev
or PR is labeledno sandbox
anvildev
or PR is labeledno sandbox
dev
1dev
1anvildev
1anvildev
1dev
anvildev
1 When pushing the merge commit is skipped due to the PR being
labelled
no sandbox
, the next build triggered by a PR whose merge commit ispushed determines this checklist item.
Operator (reindex)
dev
or this PR does not remove catalogs or otherwise causes unreferenced indicesanvildev
or this PR does not remove catalogs or otherwise causes unreferenced indicesdev
or this PR does not require reindexinganvildev
or this PR does not require reindexingdev
or this PR does not require reindexinganvildev
or this PR does not require reindexingdev
deployment or this PR does not require reindexinganvildev
deployment or this PR does not require reindexingOperator
Shorthand for review comments
L
line is too longW
line wrapping is wrongQ
bad quotesF
other formatting problem