mirror of https://github.com/rwf2/Rocket.git
Prevent bypassing safe guard in pathbuf segments
This commit is contained in:
parent
41aecc3e7f
commit
432a6a1832
|
@ -290,11 +290,13 @@ impl<'a> FromSegments<'a> for PathBuf {
|
|||
fn from_segments(segments: Segments<'a>) -> Result<PathBuf, Utf8Error> {
|
||||
let mut buf = PathBuf::new();
|
||||
for segment in segments {
|
||||
let decoded = URI::percent_decode(segment.as_bytes())?;
|
||||
if decoded == ".." {
|
||||
buf.pop();
|
||||
} else if !(decoded.starts_with('.') || decoded.starts_with('*')) {
|
||||
buf.push(&*decoded)
|
||||
let decoded_seg = URI::percent_decode(segment.as_bytes())?;
|
||||
for decoded in Segments(&decoded_seg) {
|
||||
if decoded == ".." {
|
||||
buf.pop();
|
||||
} else if !(decoded.starts_with('.') || decoded.starts_with('*')) {
|
||||
buf.push(&*decoded)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
#![feature(plugin)]
|
||||
#![plugin(rocket_codegen)]
|
||||
|
||||
extern crate rocket;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[get("/<path..>")]
|
||||
fn none(path: PathBuf) -> String {
|
||||
path.to_string_lossy().into()
|
||||
}
|
||||
|
||||
#[cfg(feature = "testing")]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use rocket::testing::MockRequest;
|
||||
use rocket::http::Method::*;
|
||||
|
||||
#[test]
|
||||
fn secure_segments() {
|
||||
let rocket = rocket::ignite()
|
||||
.mount("/", routes![none]);
|
||||
|
||||
let mut req = MockRequest::new(Get, "hello%2f..%2f..%2f..%2fetc%2fpasswd");
|
||||
let mut response = req.dispatch_with(&rocket);
|
||||
let body_str = response.body().and_then(|b| b.into_string());
|
||||
assert_eq!(body_str, Some("etc/passwd".into()));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue