mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-16 13:03:31 +08:00
Tighten H5 policy trusted routes
The classifier should not treat every /sdk path as trusted by pathname, because LAN-exposed servers already have a narrower local SDK trust boundary. Constraint: Desktop local chat, Tauri WebView, loopback adapters, and local SDK routes must remain tokenless. Rejected: Path-only /sdk trust | a non-local caller could reach the SDK route through a LAN-bound server. Confidence: high Scope-risk: narrow Directive: Keep remote /sdk and hostile-origin loopback requests in the H5/browser bucket unless a dedicated SDK auth layer is verified. Tested: bun test src/server/__tests__/h5-access-policy.test.ts
This commit is contained in:
parent
115e6f3b36
commit
a5cc7ff0c1
@ -25,18 +25,40 @@ describe('h5AccessPolicy', () => {
|
||||
expect(shouldRequireH5Token({ request, url: new URL(request.url), h5Enabled: true, explicitAuthRequired: false })).toBe(false)
|
||||
})
|
||||
|
||||
test('keeps internal SDK websocket routes tokenless', () => {
|
||||
const request = req('http://192.168.0.20:3456/sdk/session-1')
|
||||
test('keeps local internal SDK websocket routes tokenless', () => {
|
||||
const request = req('http://127.0.0.1:3456/sdk/session-1')
|
||||
expect(classifyH5Request(request, new URL(request.url))).toBe('internal-sdk')
|
||||
expect(shouldRequireH5Token({ request, url: new URL(request.url), h5Enabled: true, explicitAuthRequired: false })).toBe(false)
|
||||
})
|
||||
|
||||
test('does not trust remote SDK websocket routes by path alone', () => {
|
||||
const request = req('http://192.168.0.20:3456/sdk/session-1')
|
||||
expect(classifyH5Request(request, new URL(request.url))).toBe('h5-browser')
|
||||
expect(shouldRequireH5Token({ request, url: new URL(request.url), h5Enabled: true, explicitAuthRequired: false })).toBe(true)
|
||||
})
|
||||
|
||||
test('keeps adapter API routes tokenless for local integrations', () => {
|
||||
const request = req('http://127.0.0.1:3456/api/adapters')
|
||||
expect(classifyH5Request(request, new URL(request.url))).toBe('local-trusted')
|
||||
expect(shouldRequireH5Token({ request, url: new URL(request.url), h5Enabled: true, explicitAuthRequired: false })).toBe(false)
|
||||
})
|
||||
|
||||
test('does not trust loopback adapter requests from non-local browser origins', () => {
|
||||
const request = req('http://127.0.0.1:3456/api/adapters', {
|
||||
headers: { Origin: 'https://blocked.example.com' },
|
||||
})
|
||||
expect(classifyH5Request(request, new URL(request.url))).toBe('h5-browser')
|
||||
expect(shouldRequireH5Token({ request, url: new URL(request.url), h5Enabled: true, explicitAuthRequired: false })).toBe(true)
|
||||
})
|
||||
|
||||
test('keeps local desktop chat websocket routes tokenless', () => {
|
||||
for (const init of [{}, { headers: { Origin: 'http://tauri.localhost' } }]) {
|
||||
const request = req('http://127.0.0.1:3456/ws/session-1', init)
|
||||
expect(classifyH5Request(request, new URL(request.url))).toBe('local-trusted')
|
||||
expect(shouldRequireH5Token({ request, url: new URL(request.url), h5Enabled: true, explicitAuthRequired: false })).toBe(false)
|
||||
}
|
||||
})
|
||||
|
||||
test('requires H5 token for LAN browser API, proxy, and chat websocket routes when enabled', () => {
|
||||
for (const pathname of ['/api/status', '/proxy/openai/v1/chat/completions', '/ws/session-1']) {
|
||||
const request = req(`http://192.168.0.20:3456${pathname}`, {
|
||||
|
||||
@ -27,11 +27,13 @@ function isLocalOrigin(origin: string | null): boolean {
|
||||
}
|
||||
|
||||
export function classifyH5Request(request: Request, url: URL): H5RequestKind {
|
||||
if (url.pathname.startsWith('/sdk/')) {
|
||||
const localTrusted = isLoopbackHost(url.hostname) && isLocalOrigin(request.headers.get('Origin'))
|
||||
|
||||
if (url.pathname.startsWith('/sdk/') && localTrusted) {
|
||||
return 'internal-sdk'
|
||||
}
|
||||
|
||||
if (isLoopbackHost(url.hostname) && isLocalOrigin(request.headers.get('Origin'))) {
|
||||
if (localTrusted) {
|
||||
return 'local-trusted'
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user