mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Resolve hostnames from whitelist
This commit is contained in:
@@ -42,6 +42,7 @@ enableForwardedWhitelist: true
|
|||||||
whitelist:
|
whitelist:
|
||||||
- ::1
|
- ::1
|
||||||
- 127.0.0.1
|
- 127.0.0.1
|
||||||
|
- host.docker.internal
|
||||||
# Toggle basic authentication for endpoints
|
# Toggle basic authentication for endpoints
|
||||||
basicAuthMode: false
|
basicAuthMode: false
|
||||||
# Basic authentication credentials
|
# Basic authentication credentials
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
|
import dns from 'node:dns';
|
||||||
import Handlebars from 'handlebars';
|
import Handlebars from 'handlebars';
|
||||||
|
import ipRegex from 'ip-regex';
|
||||||
import ipMatching from 'ip-matching';
|
import ipMatching from 'ip-matching';
|
||||||
|
|
||||||
import { getIpFromRequest } from '../express-common.js';
|
import { getIpFromRequest } from '../express-common.js';
|
||||||
@@ -20,6 +22,8 @@ if (fs.existsSync(whitelistPath)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await resolveHostnames();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the client IP address from the request headers.
|
* Get the client IP address from the request headers.
|
||||||
* @param {import('express').Request} req Express request object
|
* @param {import('express').Request} req Express request object
|
||||||
@@ -45,6 +49,65 @@ function getForwardedIp(req) {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a string is a valid hostname according to RFC 1123
|
||||||
|
* @param {string} hostname The string to test
|
||||||
|
* @returns {boolean} True if the string is a valid hostname
|
||||||
|
*/
|
||||||
|
function isValidHostname(hostname) {
|
||||||
|
const hostnameRegex = /^(([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])\.)*([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])$/i;
|
||||||
|
return hostnameRegex.test(hostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a string is an IP address, CIDR notation, or IP wildcard
|
||||||
|
* @param {string} entry The string to test
|
||||||
|
* @returns {boolean} True if the string matches any IP format
|
||||||
|
*/
|
||||||
|
function isIpFormat(entry) {
|
||||||
|
// Match CIDR notation (e.g. 192.168.0.0/24)
|
||||||
|
if (entry.includes('/')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match exact IP address
|
||||||
|
if (ipRegex({ exact: true }).test(entry)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match IPv4 with wildcards (e.g. 192.168.*.* or 192.168.0.*)
|
||||||
|
const ipWildcardRegex = /^(\d{1,3}|\*)\.(\d{1,3}|\*)\.(\d{1,3}|\*)\.(\d{1,3}|\*)$/;
|
||||||
|
return ipWildcardRegex.test(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the IP addresses in the whitelist.
|
||||||
|
* Hostnames are resolved to IP addresses.
|
||||||
|
*/
|
||||||
|
async function resolveHostnames() {
|
||||||
|
for (let i = 0; i < whitelist.length; i++) {
|
||||||
|
try {
|
||||||
|
const entry = whitelist[i];
|
||||||
|
|
||||||
|
// Skip if entry appears to be an IP address, CIDR notation, or IP wildcard
|
||||||
|
if (isIpFormat(entry)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isValidHostname(entry)) {
|
||||||
|
const result = await dns.promises.lookup(entry);
|
||||||
|
|
||||||
|
if (result.address) {
|
||||||
|
console.info('Resolved whitelist hostname', entry, 'to IP address', result.address);
|
||||||
|
whitelist[i] = result.address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Ignore errors when resolving hostnames
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a middleware function that checks if the client IP is in the whitelist.
|
* Returns a middleware function that checks if the client IP is in the whitelist.
|
||||||
* @returns {import('express').RequestHandler} The middleware function
|
* @returns {import('express').RequestHandler} The middleware function
|
||||||
|
Reference in New Issue
Block a user