Skip to content

Commit 346cd98

Browse files
committed
Use x-forwarded-{host,proto} headers.
Also, emit useful error when sameorigin check fails.
1 parent 8788546 commit 346cd98

File tree

2 files changed

+20
-9
lines changed

2 files changed

+20
-9
lines changed

script/init-local-index.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ cd tmp/index-tmp
1919
cat > config.json <<-EOF
2020
{
2121
"dl": "http://localhost:8888/api/v1/crates",
22-
"api": "http://localhost:8888/"
22+
"api": "http://localhost:4200/"
2323
}
2424
EOF
2525
git add config.json

src/controllers/util.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,28 @@ impl AuthenticatedUser {
2828
impl<'a> UserAuthenticationExt for dyn RequestExt + 'a {
2929
/// Obtain `AuthenticatedUser` for the request or return an `Unauthorized` error
3030
fn authenticate(&self, conn: &PgConnection) -> AppResult<AuthenticatedUser> {
31-
let origin_headers = self.headers().get_all(header::ORIGIN);
32-
let expected_origin = match (self.scheme(), self.host()) {
33-
(conduit::Scheme::Http, conduit::Host::Name(host)) => format!("http://{}", host),
34-
(conduit::Scheme::Https, conduit::Host::Name(host)) => format!("https://{}", host),
31+
let forwarded_host = self.headers().get("x-forwarded-host");
32+
let forwarded_proto = self.headers().get("x-forwarded-proto");
33+
let expected_origin = match (forwarded_host, forwarded_proto) {
34+
(Some(host), Some(proto)) => format!(
35+
"{}://{}",
36+
proto.to_str().unwrap_or_default(),
37+
host.to_str().unwrap_or_default()
38+
),
3539
_ => "".to_string(),
3640
};
37-
if origin_headers
41+
42+
let bad_origin = self
43+
.headers()
44+
.get_all(header::ORIGIN)
3845
.iter()
39-
.any(|h| h.as_bytes() != expected_origin.as_bytes())
40-
{
41-
return Err(internal("only same-origin requests can be authenticated"))
46+
.find(|h| h.to_str().unwrap_or_default() != expected_origin);
47+
if let Some(bad_origin) = bad_origin {
48+
let error_message = format!(
49+
"only same-origin requests can be authenticated. expected {}, got {:?}",
50+
expected_origin, bad_origin
51+
);
52+
return Err(internal(&error_message))
4253
.chain_error(|| Box::new(Unauthorized) as Box<dyn AppError>);
4354
}
4455
if let Some(id) = self.extensions().find::<TrustedUserId>() {

0 commit comments

Comments
 (0)