Repository navigation
Expand file tree
/
Copy pathindex.js
More file actions
71 lines (56 loc) · 2.26 KB
/
Copy pathindex.js
File metadata and controls
71 lines (56 loc) · 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
'use strict';
const ip6addr = require('ip6addr');
// Simple proxy trusting middleware
// TODO: make proxylist somewhat compatible with https://expressjs.com/ru/guide/behind-proxies.html
// convert comma-separated ip list to array
function listToArray(str) {
return str.split(',').map(x => x.trim());
}
// check if addr is enlisted
// TODO: add check against cidr ranges
function isAddrInList (addr, cidrs) {
return cidrs.some(item => {
return item.contains(addr);
});
}
const wellKnownNames = {
loopback: ['127.0.0.1/8', '::1/128'],
linklocal: ['169.254.0.0/16', 'fe80::/10'],
uniquelocal: ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7'],
}
const flattenArray = (arr) => arr.reduce((acc, val) => acc.concat(val), []);
function mapCidrs(addresses) {
const ipOrCidrs = flattenArray(addresses.map(addr => wellKnownNames[addr] || addr));
const cidrs = ipOrCidrs.map(ipOrCidr => ipOrCidr.includes('/') ? ip6addr.createCIDR(ipOrCidr): ip6addr.createAddrRange(ipOrCidr, ipOrCidr));
return cidrs
}
function koaTrustProxy (trustlist = 'loopback', trustheader = 'x-forwarded-for') {
// fold trusted header to lowercase
trustheader = trustheader.toLowerCase();
// check if proxylist is string, then split it
if (typeof trustlist === 'string') {
trustlist = listToArray(trustlist);
}
const cidrs = mapCidrs(trustlist);
// return middleware async function
return async function (ctx, next) {
let ip = ctx.socket.remoteAddress;
// check if our addr belongs to proxy or there is no ip at all (in case of unix socket)
if (!ctx.socket.remoteAddress || isAddrInList(ctx.socket.remoteAddress, cidrs)) {
// check for trustheader presence
let header = ctx.request.headers[trustheader];
if (header) {
let ips = listToArray(header);
// find first rightmost untrusted address, or leftmost if all trusted
for (let i = ips.length-1; i >= 0; i--) {
ip = ips[i];
if (!isAddrInList(ip, cidrs)) break;
}
}
}
ctx.request.ip = ip;
// call next middleware in chain
await next();
}
}
module.exports = koaTrustProxy;