ElementsProject / ElementsProject/cln-application

Opening RTL causes CLN Application CSRF failure and misleading password prompt

Open
#165 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
52
Forks
15
PR merge metrics
No merged PRs in 30d

Description

## Summary

When CLN Application and Ride The Lightning (RTL) are served from the same hostname on different ports, opening RTL can cause CLN Application to fail its next authentication-status request with `403 Invalid CSRF token. Form tempered.` CLN Application then displays its password dialog even when `APP_SINGLE_SIGN_ON=true` and the Umbrel session remains valid.

Browser cookies are scoped by hostname and path, not port. RTL writes a generic `XSRF-TOKEN` cookie at `Path=/` on the shared hostname. Axios in CLN Application can consume that cookie for its XSRF header instead of the token CLN Application fetched from `/v1/shared/csrf/`.

## Environment

- Umbrel / umbrelOS
- CLN Application image: `ghcr.io/elementsproject/cln-application:26.04`
- CLN Application URL: `http://:2103/cln`
- `APP_SINGLE_SIGN_ON=true`
- RTL URL: `http://:3100/rtl`
- Reproduced with RTL v0.15.8
- Reviewed RTL v0.15.12 source: it still uses the generic `XSRF-TOKEN` cookie at `Path=/`
- Both apps use the same hostname and different ports

## Steps to reproduce

1. Log in to Umbrel normally.
2. Open CLN Application and confirm it authenticates through SSO and displays node data without a password prompt.
3. Open RTL on the same hostname in the same browser profile.
4. Return to or reload CLN Application.

## Actual behavior

CLN Application sends `POST /v1/auth/isauthenticated/`, receives HTTP 403, zeroes the displayed node data, and opens the password dialog.

Browser console:

```text
Failed to load resource: the server responded with a status of 403 (Forbidden)
HTTP Request failed for post /auth/isauthenticated ... Invalid CSRF token. Form tempered.
Auth Status failed: Invalid CSRF token. Form tempered.
```

CLN Application server log at the same timestamps:

```text
Invalid CSRF token. Form tempered.
```

This is misleading because the password is not wrong and SSO is still valid. `lightningd` remains healthy.

## Confirmed recovery

Expiring only the `XSRF-TOKEN` cookie for the shared hostname at `Path=/`, then reloading CLN Application, immediately removes the password dialog and restores authenticated node data. Neither CLN Application nor `lightningd` needs to be restarted.

A direct HTTP test that shared only the `_csrf` cookie did not reproduce the failure. The real browser flow did reproduce it, which points specifically to Axios automatically reading RTL's visible `XSRF-TOKEN` cookie.

## Relevant CLN Application behavior

CLN Application explicitly fetches a CSRF token from `/v1/shared/csrf/` and assigns it to Axios's `X-XSRF-TOKEN` default header. However, Axios also has conventional `XSRF-TOKEN` cookie handling.

Separately, `RootService.getAuthStatus()` catches any request error and returns a state equivalent to unauthenticated with a valid password. Startup then opens the password modal, masking the underlying CSRF error.

## Expected behavior

- Cookies created by another same-host application must not invalidate CLN Application requests.
- A CSRF/network error from `/auth/isauthenticated` must not be presented as a password failure.
- With `APP_SINGLE_SIGN_ON=true`, this failure should provide a recoverable error state rather than a password prompt.

## Suggested fixes

1. Give CLN Application unique XSRF cookie/header names, or disable Axios automatic `XSRF-TOKEN` cookie consumption because CLN Application already fetches and sets its CSRF token explicitly.
2. Consider scoping the CLN CSRF cookie to an application-specific path where deployment routing permits it.
3. Preserve the actual authentication-status error in `getAuthStatus()` and do not convert every exception into the password-login state.

I can provide additional sanitized network traces if needed.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start at the Axios CSRF configuration and the RootService.getAuthStatus() entry point, then reproduce the shared-hostname, different-port browser flow with RTL. Trace how the XSRF-TOKEN cookie reaches /v1/auth/isauthenticated/ and how its error is converted into the password state. Done means RTL no longer invalidates CLN Application authentication and CSRF or network errors are not shown as password failures.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
authentication, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.