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},
|
response::{IntoResponse, Response},
|
||||||
Extension,
|
Extension,
|
||||||
};
|
};
|
||||||
|
use reqwest::header;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
use crate::{config::Config, engines};
|
use crate::{config::Config, engines};
|
||||||
|
@ -42,6 +43,9 @@ pub async fn route(
|
||||||
if res.content_length().unwrap_or_default() > max_size {
|
if res.content_length().unwrap_or_default() > max_size {
|
||||||
return (StatusCode::PAYLOAD_TOO_LARGE, "Image too large").into_response();
|
return (StatusCode::PAYLOAD_TOO_LARGE, "Image too large").into_response();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ALLOWED_IMAGE_TYPES: &[&str] = &["apng", "avif", "gif", "jpeg", "png", "webp"];
|
||||||
|
|
||||||
// validate content-type
|
// validate content-type
|
||||||
let content_type = res
|
let content_type = res
|
||||||
.headers()
|
.headers()
|
||||||
|
@ -49,8 +53,15 @@ pub async fn route(
|
||||||
.and_then(|v| v.to_str().ok())
|
.and_then(|v| v.to_str().ok())
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.to_string();
|
.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();
|
let mut image_bytes = Vec::new();
|
||||||
|
@ -63,11 +74,10 @@ pub async fn route(
|
||||||
|
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
(axum::http::header::CONTENT_TYPE, content_type),
|
(header::CONTENT_TYPE, content_type),
|
||||||
(
|
(header::CACHE_CONTROL, "public, max-age=31536000".to_owned()),
|
||||||
axum::http::header::CACHE_CONTROL,
|
(header::X_CONTENT_TYPE_OPTIONS, "nosniff".to_owned()),
|
||||||
"public, max-age=31536000".to_owned(),
|
(header::CONTENT_DISPOSITION, "attachment".to_owned()),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
image_bytes,
|
image_bytes,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use axum::{
|
use axum::{
|
||||||
http::{header, StatusCode},
|
http::{header, HeaderMap, StatusCode},
|
||||||
response::IntoResponse,
|
response::{IntoResponse, Response},
|
||||||
Extension, Form,
|
Extension, Form,
|
||||||
};
|
};
|
||||||
use axum_extra::extract::{cookie::Cookie, CookieJar};
|
use axum_extra::extract::{cookie::Cookie, CookieJar};
|
||||||
|
@ -69,10 +69,24 @@ pub struct Settings {
|
||||||
pub stylesheet_str: String,
|
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());
|
let mut settings_cookie = Cookie::new("settings", serde_json::to_string(&settings).unwrap());
|
||||||
settings_cookie.make_permanent();
|
settings_cookie.make_permanent();
|
||||||
jar = jar.add(settings_cookie);
|
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