mirror of
https://github.com/zyycn/codex-proxy-rs.git
synced 2026-11-06 08:06:19 +00:00
fix(update): allow GitHub release asset redirects
Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -39,6 +39,8 @@ use self::state::{
|
||||
};
|
||||
use self::swap::{replace_release_files, rollback_release};
|
||||
|
||||
pub use self::release::validate_download_url;
|
||||
|
||||
const APP_BINARY_NAME: &str = "codex-proxy-rs";
|
||||
const DEFAULT_WEB_DIST_DIR: &str = "/app/web/dist";
|
||||
const DEFAULT_GITHUB_API_BASE: &str = "https://api.github.com/repos";
|
||||
|
||||
@@ -177,7 +177,8 @@ pub(crate) fn select_archive<'a>(
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn validate_download_url(raw: &str, api_base: &str) -> Result<(), OperationError> {
|
||||
/// 校验 GitHub Release 资产 URL 及其重定向目标是否位于受信任边界内。
|
||||
pub fn validate_download_url(raw: &str, api_base: &str) -> Result<(), OperationError> {
|
||||
let url = reqwest::Url::parse(raw)
|
||||
.map_err(|error| invalid(format!("invalid download URL: {error}")))?;
|
||||
if local_download_allowed(&url, api_base) {
|
||||
@@ -294,6 +295,7 @@ fn github_download_host_allowed(host: &str) -> bool {
|
||||
|| host.ends_with(".github.com")
|
||||
|| host == "objects.githubusercontent.com"
|
||||
|| host.ends_with(".objects.githubusercontent.com")
|
||||
|| host == "release-assets.githubusercontent.com"
|
||||
}
|
||||
|
||||
fn local_download_allowed(url: &reqwest::Url, api_base: &str) -> bool {
|
||||
|
||||
@@ -10,7 +10,9 @@ use gateway_admin::model::system::{
|
||||
};
|
||||
use gateway_admin::ports::system::{SystemOperationErrorKind, SystemOperations};
|
||||
use gateway_core::engine::CancellationToken;
|
||||
use gateway_host::system_update::{ProcessSystemOperations, SystemUpdateConfig};
|
||||
use gateway_host::system_update::{
|
||||
ProcessSystemOperations, SystemUpdateConfig, validate_download_url,
|
||||
};
|
||||
use sha2::{Digest as _, Sha256};
|
||||
use tar::{Builder, EntryType, Header};
|
||||
use wiremock::matchers::{method, path};
|
||||
@@ -280,6 +282,17 @@ async fn update_should_reject_release_archive_from_untrusted_host() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_should_trust_github_release_asset_redirect_host() {
|
||||
assert!(
|
||||
validate_download_url(
|
||||
"https://release-assets.githubusercontent.com/github-production-release-asset/archive",
|
||||
"https://api.github.com/repos",
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn update_should_reject_release_archive_with_unsafe_path() {
|
||||
let server = MockServer::start().await;
|
||||
|
||||
Reference in New Issue
Block a user