-
Notifications
You must be signed in to change notification settings - Fork 66
set content-security-policy, x-content-type-options, and x-frame-options headers for console assets
#5545
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
Conversation
this API is somewhat confusing, because i am not sure why one would need to _replace_ the list of allowed header names. it seems better to ensure that there is one place where every allowed response header is set.
|
|
||
| Ok(resp.body(file_contents.into())?) | ||
| let mut path = Utf8PathBuf::from("assets"); | ||
| path.extend(path_params.into_inner().path); |
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 can't find anywhere where we prevent the user from passing ".." in the path and walking back up the directory tree. How do we avoid that?
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 I had assumed find_file does that, but rereading it I don't think it does (it guards against following symlinks). I will add checks to that function and write a test.
I'm debating whether it makes more sense to bail on any path segment that contains .., or if we should std::path::Path::canonicalize every path as it comes in and bail if it isn't inside static_dir.
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 also thought it did, and I thought we had tests for it. I don't a huge problem with taking the easy route and telling any .. to go away.
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.
Good news, Dropshot already does this. https://github.com/oxidecomputer/dropshot/blob/28c63c7f9d3b81729c0b0343640fb815877cdfab/dropshot/src/router.rs#L636-L687 (since v0.6.0, oxidecomputer/dropshot#118)
I'm going to add a test on the Omicron side to ensure that remains the case.
| .header(http::header::CONTENT_TYPE, content_type) | ||
| .header(http::header::CACHE_CONTROL, "max-age=31536000, immutable"); // 1 year | ||
| let stream = FramedRead::new(file, BytesCodec::new()); | ||
| let body = Body::wrap_stream(stream); |
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.
Does this mean we don't have to read the entire file into memory at once?
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.
Yep. That may have been leading to some request latency with the larger bundles, although not sure if it actually was in practice.
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.
david-crespo
left a comment
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.
All good
|
#5065 pulls in the CSP changes on the console side, so moving out of draft. |

This is the Nexus side to oxidecomputer/console#2142, which needs to land before this lands. See also https://github.com/oxidecomputer/product-assurance/issues/50.
content-security-policytells a web browser what type of content, and from which origins, may be loaded on a page. The primary use is to help guard against cross-site scripting attacks and other kinds of novel attacks on web applications.x-content-type-options: nosnifftells the web browser to disallow content sniffing that can cause a browser to decide that responses with non-executable content types (e.g.image/png) can in fact be used as executable content types (e.g.text/javascript). This needs to be set for all console assets.x-frame-options: DENYdisallows embedding the console within another page, which helps to prevent click-jacking attacks. (This is obsoleted by theframe-ancestors 'none'CSP directive, but no harm in adding it.)content-security-policyonly needs to be set for the console index page, but there's no harm in setting it for the console assets as well.As part of this change I did some refactoring:
assetfunction and theserve_console_indexfunction are now in a single common function. This allows us to ship a gzip-compressed console index in the future.mime_guess; we only have a small list of file extensions we're willing to serve, so it doesn't make sense to compile a huge list of content types we'll never use into Nexus.There may be other headers from https://owasp.org/www-project-secure-headers/ (see the Best Practices tab) that we want but these are probably the most urgent.