Files
hop.noname.company/apps/server/test/cloudflare-discovery.test.js

75 lines
2.9 KiB
JavaScript

import { test } from 'node:test';
import assert from 'node:assert/strict';
import { io } from 'socket.io-client';
import { fixture } from './helpers.js';
import { clientIp } from '../src/security.js';
test('Cloudflare 원본 IP는 신뢰한 인접 프록시의 단일 공인 IP만 허용한다', () => {
const resolve = (peer, headers) => clientIp(peer, headers, ['127.0.0.1'], 'cloudflare');
assert.equal(
resolve('127.0.0.1', { 'cf-connecting-ip': '8.8.8.8', 'x-forwarded-for': '1.1.1.1' }),
'8.8.8.8',
);
assert.equal(resolve('8.8.4.4', { 'cf-connecting-ip': '8.8.8.8' }), null);
for (const value of ['192.168.1.1', '127.0.0.1', 'bad', '8.8.8.8,1.1.1.1', ['8.8.8.8']])
assert.equal(resolve('127.0.0.1', { 'cf-connecting-ip': value }), null);
assert.equal(resolve('127.0.0.1', {}), null);
});
test('실제 소켓의 같은 원본 IP는 자동 발견하고 다른 네트워크·발견 꺼짐은 숨긴다', async () => {
const f = await fixture(true),
sockets = [];
f.cfg.clientIpSource = 'cloudflare';
try {
const clients = [];
for (const ip of ['8.8.8.8', '8.8.8.8', '1.1.1.1']) {
const client = await f.create(ip, false);
const socket = io(f.url, {
transports: ['websocket'],
auth: { csrfToken: client.csrf },
extraHeaders: {
Origin: f.cfg.appUrl,
Cookie: client.cookie,
'CF-Connecting-IP': ip,
'X-Forwarded-For': '9.9.9.9',
},
});
sockets.push(socket);
await new Promise((resolve, reject) => {
socket.once('connect', resolve);
socket.once('connect_error', reject);
});
clients.push(client);
}
const list = (await f.call(clients[0], '/discovery/devices')).json().devices;
assert.deepEqual(
list.map((device) => device.id),
[clients[1].deviceId],
);
await f.call(clients[1], '/device/me', 'PATCH', { discoverable: false });
assert.equal((await f.call(clients[0], '/discovery/devices')).json().devices.length, 0);
} finally {
sockets.forEach((socket) => socket.disconnect());
await f.close();
}
});
test('프록시 진단은 운영자 토큰 없이 원본 정보를 노출하지 않는다', async () => {
const f = await fixture();
f.cfg.proxyDiagnosticToken = 'p'.repeat(40);
try {
const denied = await f.call(null, '/ops/proxy-diagnostic');
assert.equal(denied.statusCode, 403);
assert.equal(denied.json().peerIp, undefined);
const allowed = await f.call(null, '/ops/proxy-diagnostic', 'GET', undefined, undefined, {
authorization: `Bearer ${f.cfg.proxyDiagnosticToken}`,
'cf-connecting-ip': '8.8.8.8',
});
assert.equal(allowed.statusCode, 200);
assert.equal(allowed.json().peerIp, '127.0.0.1');
assert.equal(allowed.json().cloudflareClientIpPresent, true);
f.cfg.proxyDiagnosticToken = undefined;
assert.equal((await f.call(null, '/ops/proxy-diagnostic')).statusCode, 404);
} finally {
await f.close();
}
});