fix(media): reject extension cookie headers for media

Keep explicit media requests on yt-dlp's configured browser-cookie path and preserve cookies for normal captures.
This commit is contained in:
NimBold
2026-07-10 00:46:00 +03:30
parent c5025fd5a0
commit 3fbd0742be
3 changed files with 34 additions and 4 deletions
+27 -3
View File
@@ -315,7 +315,13 @@ fn normalize_download(payload: ExtensionRequest) -> Option<ExtensionDownload> {
silent: payload.silent,
filename,
headers: payload.headers.filter(|value| !value.trim().is_empty()),
cookies: payload.cookies.filter(|value| !value.trim().is_empty()),
// A full browser Cookie header can exceed upstream request-header
// limits. Media uses yt-dlp's configured browser-cookie source
// instead; regular captured downloads retain their exact cookies.
cookies: (!payload.media)
.then_some(payload.cookies)
.flatten()
.filter(|value| !value.trim().is_empty()),
media: payload.media,
})
}
@@ -449,8 +455,8 @@ fn is_allowed_origin(origin: &str) -> bool {
#[cfg(test)]
mod tests {
use super::{
add_server_identity, is_valid_client_nonce, sign_server_proof, PROTOCOL_VERSION_HEADER,
SERVER_HEADER,
add_server_identity, is_valid_client_nonce, normalize_download, sign_server_proof,
ExtensionRequest, PROTOCOL_VERSION_HEADER, SERVER_HEADER,
};
use axum::{http::StatusCode, middleware, routing::get, Router};
use hmac::{Hmac, KeyInit, Mac};
@@ -492,6 +498,24 @@ mod tests {
assert!(!is_valid_client_nonce("0123456789abcdef0123456789abcdeg"));
}
#[test]
fn explicit_media_drops_the_extension_cookie_header() {
let download = normalize_download(ExtensionRequest {
urls: vec!["https://www.youtube.com/watch?v=example".to_string()],
referer: None,
silent: false,
filename: None,
headers: Some("User-Agent: Firefox".to_string()),
cookies: Some("large=browser-cookie-header".to_string()),
media: true,
})
.expect("valid media handoff");
assert!(download.media);
assert!(download.cookies.is_none());
assert_eq!(download.headers.as_deref(), Some("User-Agent: Firefox"));
}
#[test]
fn signs_server_proof_with_timestamp_nonce_and_bound_port() {
let token = Arc::new(RwLock::new("pairing-token".to_string()));
+1
View File
@@ -818,6 +818,7 @@ describe('useDownloadStore', () => {
expect(state.isAddModalOpen).toBe(true);
expect(state.pendingAddUrls).toBe('https://adult.example/watch/123');
expect(state.pendingAddMediaUrls).toEqual(['https://adult.example/watch/123']);
expect(state.pendingAddCookies).toBe('');
});
it('deduplicates forced media URLs and drops stale media intent when opening fresh', async () => {
+6 -1
View File
@@ -552,12 +552,17 @@ export const useDownloadStore = create<DownloadState>((set, get) => ({
const urls = [...new Set(request.urls.map(url => url.trim()).filter(Boolean))];
if (urls.length === 0) return;
// Explicit media uses yt-dlp and its configured browser-cookie source.
// Passing Firefox's complete page Cookie header can exceed YouTube's
// request-header limit; ordinary captured file downloads keep it.
const cookies = request.media === true ? null : request.cookies;
get().openAddModalWithUrls(
urls.join('\n'),
request.referer,
urls.length === 1 ? request.filename : null,
request.headers,
request.cookies,
cookies,
request.media === true
);
},