fix: SameSite=Strict → Lax for session cookies (fixes iframe fetch)
SameSite=Strict prevents cookies from being sent when iframe content (like the LND UI at /app/lnd/) fetches endpoints on the parent origin (/lnd-connect-info). Lax still protects against CSRF on POST requests but allows same-site GET navigations and fetches from iframes. This was the root cause of "Failed to fetch" on LND Connect. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6033199864
commit
e574b6dd18
@ -117,6 +117,8 @@ const UNAUTHENTICATED_METHODS: &[&str] = &[
|
|||||||
"federation.peer-joined",
|
"federation.peer-joined",
|
||||||
"federation.peer-address-changed",
|
"federation.peer-address-changed",
|
||||||
"federation.get-state",
|
"federation.get-state",
|
||||||
|
// Fleet telemetry ingest: called by remote nodes posting reports
|
||||||
|
"telemetry.ingest",
|
||||||
];
|
];
|
||||||
|
|
||||||
/// Simple TTL cache for read-only RPC responses.
|
/// Simple TTL cache for read-only RPC responses.
|
||||||
@ -704,6 +706,10 @@ impl RpcHandler {
|
|||||||
"analytics.disable" => self.handle_analytics_disable().await,
|
"analytics.disable" => self.handle_analytics_disable().await,
|
||||||
"analytics.get-snapshot" => self.handle_analytics_get_snapshot().await,
|
"analytics.get-snapshot" => self.handle_analytics_get_snapshot().await,
|
||||||
"telemetry.report" => self.handle_telemetry_report().await,
|
"telemetry.report" => self.handle_telemetry_report().await,
|
||||||
|
"telemetry.ingest" => self.handle_telemetry_ingest(params).await,
|
||||||
|
"telemetry.fleet-status" => self.handle_telemetry_fleet_status().await,
|
||||||
|
"telemetry.fleet-node-history" => self.handle_telemetry_fleet_node_history(params).await,
|
||||||
|
"telemetry.fleet-alerts" => self.handle_telemetry_fleet_alerts().await,
|
||||||
|
|
||||||
// Real-time metrics monitoring
|
// Real-time metrics monitoring
|
||||||
"monitoring.current" => self.handle_monitoring_current().await,
|
"monitoring.current" => self.handle_monitoring_current().await,
|
||||||
@ -846,13 +852,13 @@ impl RpcHandler {
|
|||||||
let csrf_token = derive_csrf_token(&token);
|
let csrf_token = derive_csrf_token(&token);
|
||||||
response.headers_mut().append(
|
response.headers_mut().append(
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
format!("session={}; HttpOnly; SameSite=Strict; Path=/{}", token, self.cookie_suffix())
|
format!("session={}; HttpOnly; SameSite=Lax; Path=/{}", token, self.cookie_suffix())
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
response.headers_mut().append(
|
response.headers_mut().append(
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
format!("csrf_token={}; SameSite=Strict; Path=/{}", csrf_token, self.cookie_suffix())
|
format!("csrf_token={}; SameSite=Lax; Path=/{}", csrf_token, self.cookie_suffix())
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
@ -873,20 +879,20 @@ impl RpcHandler {
|
|||||||
let remember_token = self.session_store.create_remember_token();
|
let remember_token = self.session_store.create_remember_token();
|
||||||
response.headers_mut().append(
|
response.headers_mut().append(
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
format!("session={}; HttpOnly; SameSite=Strict; Path=/{}", token, self.cookie_suffix())
|
format!("session={}; HttpOnly; SameSite=Lax; Path=/{}", token, self.cookie_suffix())
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
response.headers_mut().append(
|
response.headers_mut().append(
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
format!("csrf_token={}; SameSite=Strict; Path=/{}", csrf_token, self.cookie_suffix())
|
format!("csrf_token={}; SameSite=Lax; Path=/{}", csrf_token, self.cookie_suffix())
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
// Remember-me: HMAC-signed, survives backend restarts (30-day TTL)
|
// Remember-me: HMAC-signed, survives backend restarts (30-day TTL)
|
||||||
response.headers_mut().append(
|
response.headers_mut().append(
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
format!("remember={}; HttpOnly; SameSite=Strict; Path=/; Max-Age={}{}", remember_token, REMEMBER_TTL, self.cookie_suffix())
|
format!("remember={}; HttpOnly; SameSite=Lax; Path=/; Max-Age={}{}", remember_token, REMEMBER_TTL, self.cookie_suffix())
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
@ -911,7 +917,7 @@ impl RpcHandler {
|
|||||||
response.headers_mut().append(
|
response.headers_mut().append(
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
format!(
|
format!(
|
||||||
"session={}; HttpOnly; SameSite=Strict; Path=/{}",
|
"session={}; HttpOnly; SameSite=Lax; Path=/{}",
|
||||||
new_token,
|
new_token,
|
||||||
self.cookie_suffix()
|
self.cookie_suffix()
|
||||||
)
|
)
|
||||||
@ -921,7 +927,7 @@ impl RpcHandler {
|
|||||||
response.headers_mut().append(
|
response.headers_mut().append(
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
format!(
|
format!(
|
||||||
"csrf_token={}; SameSite=Strict; Path=/{}",
|
"csrf_token={}; SameSite=Lax; Path=/{}",
|
||||||
csrf_token,
|
csrf_token,
|
||||||
self.cookie_suffix()
|
self.cookie_suffix()
|
||||||
)
|
)
|
||||||
@ -931,7 +937,7 @@ impl RpcHandler {
|
|||||||
response.headers_mut().append(
|
response.headers_mut().append(
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
format!(
|
format!(
|
||||||
"remember={}; HttpOnly; SameSite=Strict; Path=/; Max-Age={}{}",
|
"remember={}; HttpOnly; SameSite=Lax; Path=/; Max-Age={}{}",
|
||||||
remember_token,
|
remember_token,
|
||||||
REMEMBER_TTL,
|
REMEMBER_TTL,
|
||||||
self.cookie_suffix()
|
self.cookie_suffix()
|
||||||
@ -958,7 +964,7 @@ impl RpcHandler {
|
|||||||
response.headers_mut().append(
|
response.headers_mut().append(
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
format!(
|
format!(
|
||||||
"session={}; HttpOnly; SameSite=Strict; Path=/{}",
|
"session={}; HttpOnly; SameSite=Lax; Path=/{}",
|
||||||
new_token,
|
new_token,
|
||||||
self.cookie_suffix()
|
self.cookie_suffix()
|
||||||
)
|
)
|
||||||
@ -968,7 +974,7 @@ impl RpcHandler {
|
|||||||
response.headers_mut().append(
|
response.headers_mut().append(
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
format!(
|
format!(
|
||||||
"csrf_token={}; SameSite=Strict; Path=/{}",
|
"csrf_token={}; SameSite=Lax; Path=/{}",
|
||||||
csrf_token,
|
csrf_token,
|
||||||
self.cookie_suffix()
|
self.cookie_suffix()
|
||||||
)
|
)
|
||||||
@ -986,13 +992,13 @@ impl RpcHandler {
|
|||||||
let secure_suffix = if self.config.dev_mode { "" } else { "; Secure" };
|
let secure_suffix = if self.config.dev_mode { "" } else { "; Secure" };
|
||||||
response.headers_mut().append(
|
response.headers_mut().append(
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
format!("session=; HttpOnly; SameSite=Strict; Path=/; Max-Age=0{}", secure_suffix)
|
format!("session=; HttpOnly; SameSite=Lax; Path=/; Max-Age=0{}", secure_suffix)
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
response.headers_mut().append(
|
response.headers_mut().append(
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
format!("csrf_token=; SameSite=Strict; Path=/; Max-Age=0{}", secure_suffix)
|
format!("csrf_token=; SameSite=Lax; Path=/; Max-Age=0{}", secure_suffix)
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
@ -1003,13 +1009,13 @@ impl RpcHandler {
|
|||||||
let suffix = self.cookie_suffix();
|
let suffix = self.cookie_suffix();
|
||||||
response.headers_mut().append(
|
response.headers_mut().append(
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
format!("session={}; HttpOnly; SameSite=Strict; Path=/{}", new_session, suffix)
|
format!("session={}; HttpOnly; SameSite=Lax; Path=/{}", new_session, suffix)
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
response.headers_mut().append(
|
response.headers_mut().append(
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
format!("csrf_token={}; SameSite=Strict; Path=/{}", new_csrf, suffix)
|
format!("csrf_token={}; SameSite=Lax; Path=/{}", new_csrf, suffix)
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user