← back to AbramsOS
Harden auth cookies for public HTTPS surface + record claims subdomain deploy
d08f146dfc0edd88db81f07e31f7879010a51427 · 2026-07-31 15:20:29 -0700 · Steve Abrams
- trust proxy=1 (behind Kamatera nginx) so req.secure reflects X-Forwarded-Proto.
- Session + CSRF cookies now secure:req.secure — Secure over HTTPS subdomain,
plain over direct tailnet http (no lockout). Closes cookie-in-transit leak on
the now-public claims.abramsos.agentabrams.com PII surface.
- Records the deployed nginx vhost (45.61.58.125:80/443 -> 100.82.17.107:9774).
Found by /yoloforever cycle-1 contrarian gate; verified Secure-on-https / plain-on-http.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M deploy/claims.abramsos.agentabrams.com.nginx.confM middleware/csrf.jsM routes/auth-app.jsM server.js
Diff
commit d08f146dfc0edd88db81f07e31f7879010a51427
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Fri Jul 31 15:20:29 2026 -0700
Harden auth cookies for public HTTPS surface + record claims subdomain deploy
- trust proxy=1 (behind Kamatera nginx) so req.secure reflects X-Forwarded-Proto.
- Session + CSRF cookies now secure:req.secure — Secure over HTTPS subdomain,
plain over direct tailnet http (no lockout). Closes cookie-in-transit leak on
the now-public claims.abramsos.agentabrams.com PII surface.
- Records the deployed nginx vhost (45.61.58.125:80/443 -> 100.82.17.107:9774).
Found by /yoloforever cycle-1 contrarian gate; verified Secure-on-https / plain-on-http.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
deploy/claims.abramsos.agentabrams.com.nginx.conf | 2 +-
middleware/csrf.js | 2 +-
routes/auth-app.js | 4 ++--
server.js | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/deploy/claims.abramsos.agentabrams.com.nginx.conf b/deploy/claims.abramsos.agentabrams.com.nginx.conf
index bf5c78e..0af8c8d 100644
--- a/deploy/claims.abramsos.agentabrams.com.nginx.conf
+++ b/deploy/claims.abramsos.agentabrams.com.nginx.conf
@@ -2,7 +2,7 @@
# Cloned from animals.agentabrams.com (plain proxy; AbramsOS has its own requireAuth).
# certbot --nginx injects its own acme-challenge handler + adds the 443 block.
server {
- listen 80;
+ listen 45.61.58.125:80;
server_name claims.abramsos.agentabrams.com;
location / {
proxy_pass http://100.82.17.107:9774; # this Mac (tailnet), AbramsOS :9774
diff --git a/middleware/csrf.js b/middleware/csrf.js
index acad605..f798081 100644
--- a/middleware/csrf.js
+++ b/middleware/csrf.js
@@ -19,7 +19,7 @@ function ensureToken(req, res, next) {
httpOnly: false, // body must read it
sameSite: 'lax',
maxAge: TTL_MS,
- secure: false, // dev http
+ secure: req.secure, // Secure over HTTPS (subdomain); plain over direct http — no lockout
});
}
res.locals.csrfToken = token;
diff --git a/routes/auth-app.js b/routes/auth-app.js
index 4cd881f..cbfa943 100644
--- a/routes/auth-app.js
+++ b/routes/auth-app.js
@@ -45,7 +45,7 @@ router.post('/signup', async (req, res) => {
// Sign them into a temporary session so they can complete TOTP enrollment
const { sid } = await auth.createSession(DEV_USER_ID, meta);
- res.cookie(auth.SESSION_COOKIE, sid, { httpOnly: true, sameSite: 'lax', maxAge: auth.SESSION_TTL_MS });
+ res.cookie(auth.SESSION_COOKIE, sid, { httpOnly: true, sameSite: 'lax', maxAge: auth.SESSION_TTL_MS, secure: req.secure });
res.redirect('/enroll-totp');
} catch (err) {
console.error('[signup]', err);
@@ -117,7 +117,7 @@ router.post('/signin', async (req, res) => {
// Begin a session marked as NOT step-upped yet
const { sid } = await auth.createSession(userId, meta);
- res.cookie(auth.SESSION_COOKIE, sid, { httpOnly: true, sameSite: 'lax', maxAge: auth.SESSION_TTL_MS });
+ res.cookie(auth.SESSION_COOKIE, sid, { httpOnly: true, sameSite: 'lax', maxAge: auth.SESSION_TTL_MS, secure: req.secure });
return res.render('signin', { stage: 'totp', error: null, next });
}
diff --git a/server.js b/server.js
index 1b0e16c..ba33c86 100644
--- a/server.js
+++ b/server.js
@@ -40,7 +40,7 @@ const PORT = parseInt(process.env.PORT || '9931', 10);
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
-app.set('trust proxy', 'loopback');
+app.set('trust proxy', 1); // behind Kamatera nginx (sets X-Forwarded-Proto) — makes req.secure accurate over HTTPS
app.use(helmet({ contentSecurityPolicy: false, crossOriginEmbedderPolicy: false }));
app.use(morgan('tiny'));
← 69b613c auto-save: 2026-07-31T14:58:42 (1 files) — deploy/claims.abr
·
back to AbramsOS
·
Stop unauth info-disclosure on public surface (/healthz + er 8c7f239 →