mirror of
https://github.com/mat-1/metasearch2.git
synced 2025-08-02 15:26:04 +00:00
csrf and xss fix
thanks @JorianWoltjer <3
This commit is contained in:
parent
7a3e5f04bc
commit
ad1fb8a9af
2 changed files with 35 additions and 11 deletions
|
@ -6,6 +6,7 @@ use axum::{
|
|||
response::{IntoResponse, Response},
|
||||
Extension,
|
||||
};
|
||||
use reqwest::header;
|
||||
use tracing::error;
|
||||
|
||||
use crate::{config::Config, engines};
|
||||
|
@ -42,6 +43,9 @@ pub async fn route(
|
|||
if res.content_length().unwrap_or_default() > max_size {
|
||||
return (StatusCode::PAYLOAD_TOO_LARGE, "Image too large").into_response();
|
||||
}
|
||||
|
||||
const ALLOWED_IMAGE_TYPES: &[&str] = &["apng", "avif", "gif", "jpeg", "png", "webp"];
|
||||
|
||||
// validate content-type
|
||||
let content_type = res
|
||||
.headers()
|
||||
|
@ -49,8 +53,15 @@ pub async fn route(
|
|||
.and_then(|v| v.to_str().ok())
|
||||
.unwrap_or_default()
|
||||
.to_string();
|
||||
if !content_type.starts_with("image/") {
|
||||
return (StatusCode::BAD_REQUEST, "Not an image").into_response();
|
||||
|
||||
let Some((base_type, subtype)) = content_type.split_once("/") else {
|
||||
return (StatusCode::UNSUPPORTED_MEDIA_TYPE, "Invalid Content-Type").into_response();
|
||||
};
|
||||
if base_type != "image" {
|
||||
return (StatusCode::UNSUPPORTED_MEDIA_TYPE, "Not an image").into_response();
|
||||
}
|
||||
if !ALLOWED_IMAGE_TYPES.contains(&subtype) {
|
||||
return (StatusCode::UNSUPPORTED_MEDIA_TYPE, "Image type not allowed").into_response();
|
||||
}
|
||||
|
||||
let mut image_bytes = Vec::new();
|
||||
|
@ -63,11 +74,10 @@ pub async fn route(
|
|||
|
||||
(
|
||||
[
|
||||
(axum::http::header::CONTENT_TYPE, content_type),
|
||||
(
|
||||
axum::http::header::CACHE_CONTROL,
|
||||
"public, max-age=31536000".to_owned(),
|
||||
),
|
||||
(header::CONTENT_TYPE, content_type),
|
||||
(header::CACHE_CONTROL, "public, max-age=31536000".to_owned()),
|
||||
(header::X_CONTENT_TYPE_OPTIONS, "nosniff".to_owned()),
|
||||
(header::CONTENT_DISPOSITION, "attachment".to_owned()),
|
||||
],
|
||||
image_bytes,
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use axum::{
|
||||
http::{header, StatusCode},
|
||||
response::IntoResponse,
|
||||
http::{header, HeaderMap, StatusCode},
|
||||
response::{IntoResponse, Response},
|
||||
Extension, Form,
|
||||
};
|
||||
use axum_extra::extract::{cookie::Cookie, CookieJar};
|
||||
|
@ -69,10 +69,24 @@ pub struct Settings {
|
|||
pub stylesheet_str: String,
|
||||
}
|
||||
|
||||
pub async fn post(mut jar: CookieJar, Form(settings): Form<Settings>) -> impl IntoResponse {
|
||||
pub async fn post(
|
||||
headers: HeaderMap,
|
||||
mut jar: CookieJar,
|
||||
Form(settings): Form<Settings>,
|
||||
) -> Response {
|
||||
let Some(origin) = headers.get("origin").and_then(|h| h.to_str().ok()) else {
|
||||
return (StatusCode::BAD_REQUEST, "Missing or invalid Origin header").into_response();
|
||||
};
|
||||
let Some(host) = headers.get("host").and_then(|h| h.to_str().ok()) else {
|
||||
return (StatusCode::BAD_REQUEST, "Missing or invalid Host header").into_response();
|
||||
};
|
||||
if origin != format!("http://{host}") && origin != format!("https://{host}") {
|
||||
return (StatusCode::BAD_REQUEST, "Origin does not match Host").into_response();
|
||||
}
|
||||
|
||||
let mut settings_cookie = Cookie::new("settings", serde_json::to_string(&settings).unwrap());
|
||||
settings_cookie.make_permanent();
|
||||
jar = jar.add(settings_cookie);
|
||||
|
||||
(StatusCode::FOUND, [(header::LOCATION, "/settings")], jar)
|
||||
(StatusCode::FOUND, [(header::LOCATION, "/settings")], jar).into_response()
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue