An upload asks the policy, like every other way in
/upload asked nothing. It took a file, capped it at 20 MB, and wrote it to the bucket for whoever sent it - no session, no page, no policy. It was the one server entry point that did not ask the question every other one asks, and on a site whose forms are public that makes the route public too: a free disk for anyone who finds the host. Harmless while no instance had storage configured, which is why it sat there. kasse now has a garage wired to klingenberg's portal, so it is not harmless any more. An upload now carries the question and the alternative the file is being attached to. The page has to exist, the alternative has to be open and to actually declare a `type: file` field, and the policy has to allow Submit on that page for whoever is asking - checked after the bytes are read and before any of them are written. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9891c462c6
commit
8d6f29011c
+11
-2
@@ -1042,7 +1042,7 @@ fn AlternativeCard(
|
||||
};
|
||||
let Some(files) = input.files() else { continue };
|
||||
let Some(file) = files.get(0) else { continue };
|
||||
match upload_file(&file).await {
|
||||
match upload_file(&file, &question_id_for_submit, &alt_name_for_submit).await {
|
||||
Ok(key) => {
|
||||
map.insert(name.clone(), serde_json::Value::String(key));
|
||||
}
|
||||
@@ -2541,12 +2541,21 @@ pub async fn submit_answer(
|
||||
/// server side is a raw Axum multipart handler (`src/upload.rs`) for
|
||||
/// the same reason.
|
||||
#[cfg(feature = "hydrate")]
|
||||
async fn upload_file(file: &web_sys::File) -> Result<String, wasm_bindgen::JsValue> {
|
||||
async fn upload_file(
|
||||
file: &web_sys::File,
|
||||
question_id: &str,
|
||||
alternative: &str,
|
||||
) -> Result<String, wasm_bindgen::JsValue> {
|
||||
use wasm_bindgen::{JsCast, JsValue};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{FormData, Request, RequestInit, Response};
|
||||
|
||||
let form = FormData::new()?;
|
||||
// Which page and which choice this file is being attached to. The
|
||||
// server refuses an upload that does not name a page it may
|
||||
// submit, so these travel with every file.
|
||||
form.append_with_str("question", question_id)?;
|
||||
form.append_with_str("alternative", alternative)?;
|
||||
form.append_with_blob("file", file)?;
|
||||
|
||||
let opts = RequestInit::new();
|
||||
|
||||
Reference in New Issue
Block a user