Merge pull request #211 from BillionClaw/clawoss/fix/csp-session-loop
fix(auth): resolve CSP blocking inline styles and fix session refresh loop
This commit is contained in:
@@ -30,8 +30,10 @@ pub const CSRF_HEADER: &str = "x-csrf-token";
|
|||||||
/// Resolution order:
|
/// Resolution order:
|
||||||
/// 1. `OXICLOUD_COOKIE_SECURE=true|false` — explicit override.
|
/// 1. `OXICLOUD_COOKIE_SECURE=true|false` — explicit override.
|
||||||
/// 2. `OXICLOUD_BASE_URL` starts with `https` → `true`.
|
/// 2. `OXICLOUD_BASE_URL` starts with `https` → `true`.
|
||||||
/// 3. **Default: `true`** (safe-by-default). Set `OXICLOUD_COOKIE_SECURE=false`
|
/// 3. `OXICLOUD_BASE_URL` starts with `http` → `false`.
|
||||||
/// explicitly for plain-HTTP development environments.
|
/// 4. **Default: `false`** for compatibility with HTTP deployments
|
||||||
|
/// (Docker, local development). Set `OXICLOUD_COOKIE_SECURE=true`
|
||||||
|
/// explicitly for production HTTPS environments.
|
||||||
fn cookie_secure() -> bool {
|
fn cookie_secure() -> bool {
|
||||||
if let Ok(v) = std::env::var("OXICLOUD_COOKIE_SECURE") {
|
if let Ok(v) = std::env::var("OXICLOUD_COOKIE_SECURE") {
|
||||||
let secure = v == "true" || v == "1";
|
let secure = v == "true" || v == "1";
|
||||||
@@ -44,18 +46,25 @@ fn cookie_secure() -> bool {
|
|||||||
}
|
}
|
||||||
return secure;
|
return secure;
|
||||||
}
|
}
|
||||||
// Auto-detect from base URL, defaulting to secure when unset
|
// Auto-detect from base URL, defaulting to insecure for compatibility
|
||||||
let secure = std::env::var("OXICLOUD_BASE_URL")
|
match std::env::var("OXICLOUD_BASE_URL") {
|
||||||
.map(|u| u.starts_with("https"))
|
Ok(url) if url.starts_with("https") => true,
|
||||||
.unwrap_or(true);
|
Ok(url) if url.starts_with("http://") => {
|
||||||
if !secure {
|
tracing::info!(
|
||||||
tracing::warn!(
|
"OXICLOUD_BASE_URL is HTTP — cookie Secure flag is OFF. \
|
||||||
"OXICLOUD_BASE_URL does not start with https — \
|
Set OXICLOUD_COOKIE_SECURE=true to override if your proxy terminates TLS."
|
||||||
cookie Secure flag is OFF. Set OXICLOUD_COOKIE_SECURE=true \
|
|
||||||
to override if your proxy terminates TLS."
|
|
||||||
);
|
);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// Default to false for compatibility with HTTP deployments
|
||||||
|
tracing::info!(
|
||||||
|
"OXICLOUD_BASE_URL not set — defaulting to non-secure cookies \
|
||||||
|
for HTTP compatibility. Set OXICLOUD_COOKIE_SECURE=true for HTTPS deployments."
|
||||||
|
);
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
secure
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build a `Set-Cookie` header value.
|
/// Build a `Set-Cookie` header value.
|
||||||
|
|||||||
+6
-3
@@ -416,15 +416,18 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
app = app
|
app = app
|
||||||
.layer(SetResponseHeaderLayer::overriding(
|
.layer(SetResponseHeaderLayer::overriding(
|
||||||
HeaderName::from_static("content-security-policy"),
|
HeaderName::from_static("content-security-policy"),
|
||||||
// All inline scripts and styles have been migrated to external
|
// Note: 'unsafe-inline' is required for style-src because the
|
||||||
// files, so 'unsafe-inline' is no longer needed.
|
// frontend JavaScript dynamically sets inline styles (e.g.,
|
||||||
|
// element.style.display = 'none'). This is a common pattern
|
||||||
|
// for UI state management and cannot be easily migrated to
|
||||||
|
// external CSS classes without significant refactoring.
|
||||||
// frame-src: '*' only matches network schemes, so 'blob:' must be
|
// frame-src: '*' only matches network schemes, so 'blob:' must be
|
||||||
// listed explicitly for inline PDF/document viewers.
|
// listed explicitly for inline PDF/document viewers.
|
||||||
// media-src: needed for blob: video/audio playback.
|
// media-src: needed for blob: video/audio playback.
|
||||||
HeaderValue::from_static(
|
HeaderValue::from_static(
|
||||||
"default-src 'self'; \
|
"default-src 'self'; \
|
||||||
script-src 'self'; \
|
script-src 'self'; \
|
||||||
style-src 'self'; \
|
style-src 'self' 'unsafe-inline'; \
|
||||||
img-src 'self' data: blob:; \
|
img-src 'self' data: blob:; \
|
||||||
media-src 'self' blob:; \
|
media-src 'self' blob:; \
|
||||||
connect-src 'self'; \
|
connect-src 'self'; \
|
||||||
|
|||||||
Reference in New Issue
Block a user