admin/config: option to disable admin access for localhost

Massimo Melina committed Apr 2, 2022 at 11:27 UTC a92b0ada034b50aa43f78742c5d19517ffd76d91
3 files changed +8 -3
admin/src/ConfigPage.ts
+1
@@ -71,6 +71,7 @@ export default function ConfigPage() {
71 },
72 { k: 'accounts', label: "Accounts file" },
73 { k: 'open_browser_at_start', comp: BoolField },
74 + { k: 'localhost_admin', comp: BoolField, label: "Admin access for localhost connections", helperText: "To access Admin without entering credentials" },
75 { k: 'proxies', comp: NumberField, min: 0, max: 9, sm: 6, lg: 6, label: "How many proxies between this server and users?",
76 error: proxyWarning(values, status),
77 helperText: "Wrong number will prevent detection of users' IP address"
server/src/adminApis.ts
+6 -3
@@ -1,7 +1,7 @@
1 // This file is part of HFS - Copyright 2021-2022, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3 import { ApiError, ApiHandlers } from './apiMiddleware'
4 -import { getConfig, getWholeConfig, setConfig } from './config'
4 +import { defineConfig, getConfig, getWholeConfig, setConfig } from './config'
5 import { getStatus, getUrls } from './listen'
6 import { BUILD_TIMESTAMP, FORBIDDEN, HFS_STARTED, VERSION } from './const'
7 import vfsApis from './api.vfs'
@@ -67,7 +67,7 @@ export const adminApis: ApiHandlers = {
67 },
68
69 get_connections({}, ctx) {
70 - const ret = new Readable({ objectMode: true, read(){} }) // we don't care what you ask/read, we just push and hope for the best
70 + const ret = new Readable({ objectMode: true, read(){} }) // this stream pushes uncaring for when you read. Should we do better?
71 // start with existing connections
72 for (const conn of getConnections())
73 ret.push({ add: serializeConnection(conn) })
@@ -121,7 +121,10 @@ for (const k in adminApis) {
121 : new ApiError(401)
122 }
123
124 +defineConfig('localhost_admin', { defaultValue: true })
125 +
126 export function ctxAdminAccess(ctx: Koa.Context) {
125 - return isLocalHost(ctx) && !ctx.get('X-Forwarded-For') // this may detect an http-proxied request on localhost
127 + return isLocalHost(ctx) && getConfig('localhost_admin')
128 + && !ctx.state.proxiedFor // this may detect an http-proxied request on localhost
129 || getFromAccount(ctx.state.account, a => a.admin)
130 }
server/src/middlewares.ts
+1
@@ -103,6 +103,7 @@ export const someSecurity: Koa.Middleware = async (ctx, next) => {
103 if (applyBlock(ctx.socket))
104 return
105 proxyDetected ||= proxy > ''
106 + ctx.state.proxiedFor = proxy
107 }
108 catch {
109 return ctx.status = 418