extend noBrowser logic to other known clients

Massimo Melina committed Jan 27, 2026 at 10:28 UTC bce6333c7b7bb09849b6014a5563393679a3761b
1 file changed +4 -3
src/apiMiddleware.ts
+4 -3
@@ -28,10 +28,11 @@ export function apiMiddleware(apis: ApiHandlers) : Koa.Middleware {
28 const params = isPost ? ctx.state.params || {} : ctx.query
29 const apiName = ctx.path
30 console.debug('API', ctx.method, apiName, { ...params })
31 - const noBrowser = ctx.get('user-agent')?.startsWith('curl')
32 - const safe = noBrowser || isPost && ctx.get('x-hfs-anti-csrf') // POST is safe because browser will enforce SameSite cookie
31 + const csrfSafe = !isPost
32 + || ctx.get('x-hfs-anti-csrf') // automatic browser actions won't carry this header
33 || apiName.startsWith('get_') // "get_" apis are safe because they make no change
34 - if (!safe)
34 + || /^(curl|wget|python|go-|java|axios|postman|httpie|insomnia|bruno)/i.test(ctx.get('user-agent') || '') // only browser are subject to CSRF
35 + if (!csrfSafe)
36 return send(HTTP_FOOL, "missing header x-hfs-anti-csrf=1")
37 const customApiRest = apiName.startsWith(PLUGIN_CUSTOM_REST_PREFIX) && apiName.slice(PLUGIN_CUSTOM_REST_PREFIX.length)
38 const apiFun = customApiRest && firstPlugin(pl => pl.getData().customRest?.[customApiRest])