# Uptime Kuma CSRF Protection and Origin Security: How It Works

> Discover how Uptime Kuma secures your monitoring with JWT authentication CSRF protection and origin security checks. Learn about its robust defense against web vulnerabilities.

- Repository: [Louis Lam/uptime-kuma](https://github.com/louislam/uptime-kuma)
- Tags: security
- Published: 2026-02-28

---

**Uptime Kuma eliminates traditional CSRF vulnerabilities by using JWT-based authentication instead of cookie-based sessions, while enforcing strict WebSocket origin validation and iframe protection through configurable security headers.**

Uptime Kuma, an open-source monitoring tool maintained by Louis Lam, implements a unique security model that abandons cookie-based authentication entirely. By leveraging **JSON Web Tokens (JWT)** transmitted explicitly in headers and socket.io events, the application removes the attack surface that traditional CSRF protections target. This article examines the specific origin-checking mechanisms and security headers implemented in the `louislam/uptime-kuma` repository.

## How Uptime Kuma Eliminates CSRF Without Tokens

Unlike conventional web applications that rely on session cookies and require **synchronizer tokens** to prevent cross-site request forgery, Uptime Kuma uses a token-based authentication system that inherently mitigates CSRF attacks.

In [`server/util-server.js`](https://github.com/louislam/uptime-kuma/blob/main/server/util-server.js), the authentication utilities including `checkLogin` validate JWTs passed explicitly in request bodies or socket.io events rather than extracting credentials from cookies. Because browsers do not automatically attach custom headers or request body parameters to cross-origin requests, an attacker cannot forge authenticated requests even without a CSRF token. This design choice eliminates the need for the `csurf` middleware or similar server-side CSRF protection mechanisms.

## WebSocket Origin Validation

While JWT-based auth removes cookie-CSRF risks, the WebSocket connections require explicit origin verification to prevent unauthorized cross-origin socket connections.

### The allowRequest Hook Implementation

In [`server/uptime-kuma-server.js`](https://github.com/louislam/uptime-kuma/blob/main/server/uptime-kuma-server.js), the Socket.io server constructor implements an `allowRequest` hook that validates every incoming WebSocket connection:

```javascript
// Conceptual representation of the implementation
allowRequest: (req, callback) => {
    const origin = req.headers.origin;
    // Validation checks origin against Host or x-forwarded-for
    if (originMatchesTrustedHost(origin, req)) {
        callback(null, true);
    } else {
        callback(null, false);
    }
}

```

The hook extracts `req.headers.origin` and compares it against the request's `Host` header or the trusted proxy header `x-forwarded-for`. If the origin does not match these trusted sources, the connection is rejected with `callback(null, false)` and an error is logged. This ensures that WebSocket connections originate only from the expected domain.

### Bypassing the Origin Check for Reverse Proxies

For deployments behind complex reverse proxy configurations, you can disable this check:

```bash
export UPTIME_KUMA_WS_ORIGIN_CHECK=bypass
node server/server.js

```

Setting `UPTIME_KUMA_WS_ORIGIN_CHECK` to `"bypass"` instructs the server in [`server/uptime-kuma-server.js`](https://github.com/louislam/uptime-kuma/blob/main/server/uptime-kuma-server.js) to skip origin validation entirely, allowing connections from any origin.

## HTTP Security Headers and Frame Protection

Uptime Kuma implements additional security layers through HTTP headers to prevent click-jacking and control cross-origin resource sharing.

### X-Frame-Options Configuration

In [`server/server.js`](https://github.com/louislam/uptime-kuma/blob/main/server/server.js), the Express server adds the `X-Frame-Options: SAMEORIGIN` header to every HTTP response by default. This prevents the Uptime Kuma dashboard from being embedded in malicious iframes, thwarting click-jacking attacks.

To disable this protection (rarely needed):

```bash

# Via CLI flag

node server/server.js --disable-frame-sameorigin

# Or via environment variable

export UPTIME_KUMA_DISABLE_FRAME_SAMEORIGIN=1
node server/server.js

```

### CORS Policies for Development vs Production

The [`server/util-server.js`](https://github.com/louislam/uptime-kuma/blob/main/server/util-server.js) file contains helper functions `allowDevAllOrigin` and `allowAllOrigin` that configure Cross-Origin Resource Sharing headers based on the environment:

- **Development mode** (`NODE_ENV=development`): Sends `Access-Control-Allow-Origin: *` headers, allowing the UI to be served from a different port during local development.
- **Production mode**: No CORS headers are added, forcing the UI and API to be served from the same origin and preventing cross-origin API requests.

## JWT Extraction in the Client

The client-side application stores and transmits JWTs explicitly rather than relying on cookies. In [`src/mixins/socket.js`](https://github.com/louislam/uptime-kuma/blob/main/src/mixins/socket.js), the Vue mixin extracts the stored token:

```javascript
const jwtToken = this.$root.storage().token;
if (jwtToken && jwtToken !== 'autoLogin') {
    const payload = jwtDecode(jwtToken);
    // Token used for socket.io authentication
}

```

This explicit token handling ensures that authentication credentials are never automatically included in cross-site requests.

## Summary

- **JWT-based authentication** in [`server/util-server.js`](https://github.com/louislam/uptime-kuma/blob/main/server/util-server.js) eliminates CSRF attack vectors by avoiding cookie-based sessions entirely.
- **WebSocket origin validation** in [`server/uptime-kuma-server.js`](https://github.com/louislam/uptime-kuma/blob/main/server/uptime-kuma-server.js) rejects connections from untrusted origins unless bypassed via `UPTIME_KUMA_WS_ORIGIN_CHECK`.
- **X-Frame-Options: SAMEORIGIN** headers in [`server/server.js`](https://github.com/louislam/uptime-kuma/blob/main/server/server.js) prevent click-jacking attacks by default.
- **Environment-specific CORS** controls allow development flexibility while enforcing same-origin policies in production.
- **No CSRF tokens** are required or implemented, as the authentication architecture inherently prevents cross-site request forgery.

## Frequently Asked Questions

### Does Uptime Kuma use CSRF tokens for security?

No, Uptime Kuma does not implement traditional CSRF tokens or the `csurf` middleware. Because the application uses JWT-based authentication stored in browser memory (not cookies), browsers cannot automatically include credentials in cross-site requests. This architectural choice inherently prevents CSRF attacks without requiring synchronizer tokens.

### How do I configure Uptime Kuma behind a reverse proxy with WebSocket support?

When running behind a reverse proxy like Nginx or Traefik, set the `UPTIME_KUMA_WS_ORIGIN_CHECK` environment variable to `"bypass"` to disable the strict origin check. This allows the WebSocket connections to function correctly when the proxy modifies headers or when the origin appears different due to forwarding. Ensure your proxy correctly sets `X-Forwarded-For` headers if you choose to keep origin checking enabled.

### What is the purpose of the X-Frame-Options header in Uptime Kuma?

The `X-Frame-Options: SAMEORIGIN` header prevents click-jacking attacks by ensuring the Uptime Kuma dashboard can only be embedded in iframes on the same origin. This stops attackers from loading your monitoring interface within a malicious site using invisible frames to trick users into unintended actions. You can disable this with the `--disable-frame-sameorigin` flag if you need to embed the dashboard in legitimate cross-origin frames.

### Is CORS enabled in production Uptime Kuma deployments?

No, Uptime Kuma does not send CORS headers in production environments (`NODE_ENV=production`). The `allowAllOrigin` and `allowDevAllOrigin` functions in [`server/util-server.js`](https://github.com/louislam/uptime-kuma/blob/main/server/util-server.js) only add `Access-Control-Allow-Origin: *` during development mode. In production, the API and UI must be served from the same origin, which provides additional CSRF protection by preventing cross-origin API requests from browser-based JavaScript.