Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions utils/getClientIp.accessibility.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { getClientIp } from './getClientIp';

describe('getClientIp Data Accessibility & Header Resolution Tests', () => {
beforeEach(() => {
vi.spyOn(console, 'warn').mockImplementation(() => undefined);
});

afterEach(() => {
vi.restoreAllMocks();
});

it('1. reliably accesses the leftmost client IP in an X-Forwarded-For proxy chain when proxies are universally trusted', () => {
const request = new Request('https://commitpulse.com', {
headers: new Headers({
'x-forwarded-for': '203.0.113.1, 198.51.100.1, 192.0.2.1',
}),
});
Comment on lines +14 to +18

const ip = getClientIp(request, {
proxyConfig: { trustedProxies: ['*'], trustPrivateRanges: true },
});

expect(ip).toBe('203.0.113.1');

Check failure on line 24 in utils/getClientIp.accessibility.test.ts

View workflow job for this annotation

GitHub Actions / Format Β· Lint Β· Typecheck Β· Test

utils/getClientIp.accessibility.test.ts > getClientIp Data Accessibility & Header Resolution Tests > 1. reliably accesses the leftmost client IP in an X-Forwarded-For proxy chain when proxies are universally trusted

AssertionError: expected '127.0.0.1' to be '203.0.113.1' // Object.is equality Expected: "203.0.113.1" Received: "127.0.0.1" ❯ utils/getClientIp.accessibility.test.ts:24:16
});

it('2. accesses secure fallback priority headers (cf-connecting-ip) when primary forwarding headers are missing', () => {
const request = new Request('https://commitpulse.com', {
headers: new Headers({
'cf-connecting-ip': '198.51.100.5',
'x-real-ip': '198.51.100.2',
}),
});

const ip = getClientIp(request, {
proxyConfig: { trustedProxies: [], trustPrivateRanges: false },
});

expect(ip).toBe('198.51.100.5');

Check failure on line 39 in utils/getClientIp.accessibility.test.ts

View workflow job for this annotation

GitHub Actions / Format Β· Lint Β· Typecheck Β· Test

utils/getClientIp.accessibility.test.ts > getClientIp Data Accessibility & Header Resolution Tests > 2. accesses secure fallback priority headers (cf-connecting-ip) when primary forwarding headers are missing

AssertionError: expected '127.0.0.1' to be '198.51.100.5' // Object.is equality Expected: "198.51.100.5" Received: "127.0.0.1" ❯ utils/getClientIp.accessibility.test.ts:39:16
});

it('3. identifies spoofing attempts by verifying that claimed IPs match the securely accessed resolution', () => {
const request = new Request('https://commitpulse.com', {
headers: new Headers({
'x-forwarded-for': '9.9.9.9', // Claimed spoofed IP
'x-real-ip': '1.1.1.1', // Actual accessed IP
}),
});

const ip = getClientIp(request, {
proxyConfig: { trustedProxies: [], trustPrivateRanges: false },
});

expect(ip).toBe('1.1.1.1');

Check failure on line 54 in utils/getClientIp.accessibility.test.ts

View workflow job for this annotation

GitHub Actions / Format Β· Lint Β· Typecheck Β· Test

utils/getClientIp.accessibility.test.ts > getClientIp Data Accessibility & Header Resolution Tests > 3. identifies spoofing attempts by verifying that claimed IPs match the securely accessed resolution

AssertionError: expected '127.0.0.1' to be '1.1.1.1' // Object.is equality Expected: "1.1.1.1" Received: "127.0.0.1" ❯ utils/getClientIp.accessibility.test.ts:54:16
expect(console.warn).toHaveBeenCalledWith(expect.stringContaining('SPOOFED_HEADER_ATTEMPT'));
});

it('4. securely defaults to local loopback accessibility when no valid network headers are present', () => {
const request = new Request('https://commitpulse.com', {
headers: new Headers(), // Empty headers
});

const ip = getClientIp(request);
expect(ip).toBe('127.0.0.1');
});

it('5. resolves the correct client IP by traversing backwards through explicitly trusted proxy boundaries', () => {
const request = new Request('https://commitpulse.com', {
headers: new Headers({
// Client -> Untrusted -> Trusted -> Trusted
'x-forwarded-for': '203.0.113.1, 100.0.0.1, 192.168.1.100, 192.168.1.200',
}),
});

const ip = getClientIp(request, {
proxyConfig: {
trustedProxies: ['192.168.1.100', '192.168.1.200'],
trustPrivateRanges: false,
},
});

expect(ip).toBe('100.0.0.1');

Check failure on line 82 in utils/getClientIp.accessibility.test.ts

View workflow job for this annotation

GitHub Actions / Format Β· Lint Β· Typecheck Β· Test

utils/getClientIp.accessibility.test.ts > getClientIp Data Accessibility & Header Resolution Tests > 5. resolves the correct client IP by traversing backwards through explicitly trusted proxy boundaries

AssertionError: expected '127.0.0.1' to be '100.0.0.1' // Object.is equality Expected: "100.0.0.1" Received: "127.0.0.1" ❯ utils/getClientIp.accessibility.test.ts:82:16
});
});
Loading