From a5e0486da0cda068f39daee2592d51e691fa904b Mon Sep 17 00:00:00 2001 From: Baptiste Gelez Date: Wed, 6 Mar 2019 14:09:43 +0100 Subject: [PATCH] Make media extension parsing safer (#459) Only keep it if contains letters and numbers only, otherwise remove it. To be merged before #452 --- src/routes/medias.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/routes/medias.rs b/src/routes/medias.rs index 5f287ddf..7276e1a8 100644 --- a/src/routes/medias.rs +++ b/src/routes/medias.rs @@ -35,9 +35,19 @@ pub fn upload(user: User, data: Data, ct: &ContentType, conn: DbConn) -> Result< let filename = fields.get("file").and_then(|v| v.into_iter().next()) .ok_or_else(|| status::BadRequest(Some("No file uploaded")))?.headers .filename.clone(); - let ext = filename.and_then(|f| f.rsplit('.').next().map(|ext| ext.to_owned())) - .unwrap_or_else(|| "png".to_owned()); - let dest = format!("static/media/{}.{}", GUID::rand().to_string(), ext); + // Remove extension if it contains something else than just letters and numbers + let ext = filename + .and_then(|f| f + .rsplit('.') + .next() + .and_then(|ext| if ext.chars().any(|c| !c.is_alphanumeric()) { + None + } else { + Some(ext.to_lowercase()) + }) + .map(|ext| format!(".{}", ext)) + ).unwrap_or_default(); + let dest = format!("static/media/{}{}", GUID::rand().to_string(), ext); match fields["file"][0].data { SavedData::Bytes(ref bytes) => fs::write(&dest, bytes).map_err(|_| status::BadRequest(Some("Couldn't save upload")))?,