mirror of
https://github.com/nimbold/Firelink.git
synced 2026-07-26 12:08:27 +00:00
fix: pass capture cookies and headers securely to metadata fetcher
- Pass captured cookies and headers from UI state into the backend `fetch_metadata` command. - Implement secure domain-matching redirect policy in the backend to prevent leaking cookies, headers, and Basic Auth credentials to third-party domains upon redirect. - Ensure metadata fetches correctly identify authenticated files (e.g. from Gofile) without being redirected to login/error pages.
This commit is contained in:
+46
-6
@@ -876,8 +876,11 @@ async fn fetch_metadata(
|
||||
user_agent: Option<String>,
|
||||
username: Option<String>,
|
||||
password: Option<String>,
|
||||
headers: Option<String>,
|
||||
cookies: Option<String>,
|
||||
) -> Result<MetadataResponse, String> {
|
||||
let mut current_url = url.clone();
|
||||
let original_host = reqwest::Url::parse(&url).ok().and_then(|u| u.host_str().map(|s| s.to_string()));
|
||||
let mut redirects = 0;
|
||||
let res;
|
||||
|
||||
@@ -904,21 +907,58 @@ async fn fetch_metadata(
|
||||
builder = builder.resolve(&host, addr);
|
||||
}
|
||||
|
||||
let current_host = reqwest::Url::parse(¤t_url).ok().and_then(|u| u.host_str().map(|s| s.to_string()));
|
||||
let mut should_send_auth = redirects == 0;
|
||||
if !should_send_auth {
|
||||
if let (Some(orig), Some(curr)) = (&original_host, ¤t_host) {
|
||||
if curr == orig || curr.ends_with(&format!(".{}", orig)) {
|
||||
should_send_auth = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut header_map = reqwest::header::HeaderMap::new();
|
||||
if should_send_auth {
|
||||
if let Some(ref h_str) = headers {
|
||||
for line in h_str.lines() {
|
||||
if let Some((k, v)) = line.split_once(':') {
|
||||
if let Ok(name) = reqwest::header::HeaderName::from_bytes(k.trim().as_bytes()) {
|
||||
if let Ok(value) = reqwest::header::HeaderValue::from_str(v.trim()) {
|
||||
header_map.insert(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(ref c_str) = cookies {
|
||||
if !c_str.trim().is_empty() {
|
||||
if let Ok(value) = reqwest::header::HeaderValue::from_str(c_str.trim()) {
|
||||
header_map.insert(reqwest::header::COOKIE, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
builder = builder.default_headers(header_map);
|
||||
|
||||
let client = builder.build().map_err(|e| e.to_string())?;
|
||||
|
||||
let mut head_req = client.head(¤t_url);
|
||||
if let Some(ref user) = username {
|
||||
if !user.is_empty() {
|
||||
head_req = head_req.basic_auth(user, password.as_deref());
|
||||
if should_send_auth {
|
||||
if let Some(ref user) = username {
|
||||
if !user.is_empty() {
|
||||
head_req = head_req.basic_auth(user, password.as_deref());
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut current_res = head_req.send().await.map_err(|e| e.to_string())?;
|
||||
|
||||
if !current_res.status().is_success() && !current_res.status().is_redirection() {
|
||||
let mut get_req = client.get(¤t_url);
|
||||
if let Some(ref user) = username {
|
||||
if !user.is_empty() {
|
||||
get_req = get_req.basic_auth(user, password.as_deref());
|
||||
if should_send_auth {
|
||||
if let Some(ref user) = username {
|
||||
if !user.is_empty() {
|
||||
get_req = get_req.basic_auth(user, password.as_deref());
|
||||
}
|
||||
}
|
||||
}
|
||||
current_res = get_req.send().await.map_err(|e| e.to_string())?;
|
||||
|
||||
@@ -247,7 +247,9 @@ export const AddDownloadsModal = () => {
|
||||
url: row.sourceUrl,
|
||||
userAgent: settingsStore.customUserAgent || null,
|
||||
username: useAuth ? username.trim() || null : login?.username || null,
|
||||
password: useAuth ? password || null : keychainPassword
|
||||
password: useAuth ? password || null : keychainPassword,
|
||||
headers: headers?.trim() || null,
|
||||
cookies: cookies?.trim() || null
|
||||
});
|
||||
setParsedItems(current => updateRowIfCurrent(
|
||||
current,
|
||||
@@ -291,7 +293,7 @@ export const AddDownloadsModal = () => {
|
||||
}
|
||||
})();
|
||||
}
|
||||
}, [parsedItems, pendingAddFilename, password, useAuth, username]);
|
||||
}, [parsedItems, pendingAddFilename, password, useAuth, username, headers, cookies]);
|
||||
|
||||
useEffect(() => {
|
||||
if (parsedItems.length === 0) {
|
||||
|
||||
Reference in New Issue
Block a user