native-dialog-request.spec.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import type { IncomingHttpHeaders } from 'node:http'
  2. import { describe, expect, it } from 'vitest'
  3. import { isTrustedNativeDialogRequest } from '../src/native-dialog-request.ts'
  4. function request(
  5. remoteAddress: string | undefined,
  6. headers: IncomingHttpHeaders = {
  7. host: '127.0.0.1:3080',
  8. origin: 'http://127.0.0.1:3080',
  9. 'sec-fetch-site': 'same-origin',
  10. },
  11. ) {
  12. return { socket: { remoteAddress }, headers }
  13. }
  14. describe('native dialog request trust', () => {
  15. it('accepts loopback same-origin browser requests', () => {
  16. expect(isTrustedNativeDialogRequest(request('127.0.0.1'))).toBe(true)
  17. expect(isTrustedNativeDialogRequest(request('::1', {
  18. host: '[::1]:3080', origin: 'http://[::1]:3080', 'sec-fetch-site': 'same-origin',
  19. }))).toBe(true)
  20. expect(isTrustedNativeDialogRequest(request('::ffff:127.0.0.1'))).toBe(true)
  21. expect(isTrustedNativeDialogRequest(request('127.0.0.1', {
  22. host: 'localhost:3080', origin: 'http://localhost:3080', 'sec-fetch-site': 'same-origin',
  23. }))).toBe(true)
  24. expect(isTrustedNativeDialogRequest(request('127.0.0.2', {
  25. host: '127.0.0.2:3080', origin: 'https://127.0.0.2:3080', 'sec-fetch-site': 'same-origin',
  26. }))).toBe(true)
  27. })
  28. it('rejects remote sockets and requests without matching browser metadata', () => {
  29. expect(isTrustedNativeDialogRequest(request('192.168.1.5'))).toBe(false)
  30. expect(isTrustedNativeDialogRequest(request(undefined))).toBe(false)
  31. expect(isTrustedNativeDialogRequest(request('127.0.0.1', {
  32. host: '127.0.0.1:3080', origin: 'http://evil.example', 'sec-fetch-site': 'cross-site',
  33. }))).toBe(false)
  34. expect(isTrustedNativeDialogRequest(request('127.0.0.1', {
  35. host: '127.0.0.1:3080', origin: 'http://localhost:3080', 'sec-fetch-site': 'same-origin',
  36. }))).toBe(false)
  37. expect(isTrustedNativeDialogRequest(request('127.0.0.1', { host: '127.0.0.1:3080' }))).toBe(false)
  38. expect(isTrustedNativeDialogRequest(request('127.0.0.1', {
  39. origin: 'http://127.0.0.1:3080', 'sec-fetch-site': 'same-origin',
  40. }))).toBe(false)
  41. expect(isTrustedNativeDialogRequest(request('127.0.0.1', {
  42. host: 'attacker.example:3080', origin: 'http://attacker.example:3080', 'sec-fetch-site': 'same-origin',
  43. }))).toBe(false)
  44. expect(isTrustedNativeDialogRequest(request('127.0.0.1', {
  45. host: '127.0.0.1:3080', origin: 'ftp://127.0.0.1:3080', 'sec-fetch-site': 'same-origin',
  46. }))).toBe(false)
  47. expect(isTrustedNativeDialogRequest(request('127.0.0.1', {
  48. host: '127.999.0.1:3080', origin: 'http://127.999.0.1:3080', 'sec-fetch-site': 'same-origin',
  49. }))).toBe(false)
  50. expect(isTrustedNativeDialogRequest(request('127.0.0.1', {
  51. host: '[invalid', origin: 'http://[invalid', 'sec-fetch-site': 'same-origin',
  52. }))).toBe(false)
  53. })
  54. })