Implements origin/referrer block (khanon/oai-reverse-proxy!13)

This commit is contained in:
nai-degen
2023-05-22 21:08:20 +00:00
parent a3620db591
commit a61fa04fbf
4 changed files with 70 additions and 0 deletions
+3
View File
@@ -11,6 +11,9 @@
# CHECK_KEYS=true
# QUOTA_DISPLAY_MODE=full
# QUEUE_MODE=fair
# BLOCKED_ORIGINS=reddit.com,9gag.com
# BLOCK_MESSAGE="You must be over the age of majority in your country to use this service."
# BLOCK_REDIRECT="https://roblox.com/"
# Note: CHECK_KEYS is disabled by default in local development mode, but enabled
# by default in production mode.
+25
View File
@@ -95,6 +95,22 @@ type Config = {
* `none`: Requests are not queued and users have to retry manually
*/
queueMode: DequeueMode;
/**
* Comma-separated list of origins to block. Requests matching any of these
* origins or referers will be rejected.
* Partial matches are allowed, so `reddit` will match `www.reddit.com`.
* Include only the hostname, not the protocol or path, e.g:
* `reddit.com,9gag.com,gaiaonline.com`
*/
blockedOrigins?: string;
/**
* Message to return when rejecting requests from blocked origins.
*/
blockMessage?: string;
/**
* Desination URL to redirect blocked requests to, for non-JSON requests.
*/
blockRedirect?: string;
};
// To change configs, create a file called .env in the root directory.
@@ -127,6 +143,12 @@ export const config: Config = {
undefined
),
queueMode: getEnvWithDefault("QUEUE_MODE", "fair"),
blockedOrigins: getEnvWithDefault("BLOCKED_ORIGINS", undefined),
blockMessage: getEnvWithDefault(
"BLOCK_MESSAGE",
"You must be over the age of majority in your country to use this service."
),
blockRedirect: getEnvWithDefault("BLOCK_REDIRECT", "https://www.9gag.com"),
} as const;
/** Prevents the server from starting if config state is invalid. */
@@ -208,6 +230,9 @@ export const OMITTED_KEYS: (keyof Config)[] = [
"firebaseRtdbUrl",
"gatekeeperStore",
"maxIpsPerUser",
"blockedOrigins",
"blockMessage",
"blockRedirect",
];
const getKeys = Object.keys as <T extends object>(obj: T) => Array<keyof T>;
+40
View File
@@ -0,0 +1,40 @@
import { config } from "../config";
import { RequestHandler } from "express";
const BLOCKED_REFERERS = config.blockedOrigins?.split(",") || [];
/** Disallow requests from blocked origins and referers. */
export const checkOrigin: RequestHandler = (req, res, next) => {
const blocks = BLOCKED_REFERERS || [];
for (const block of blocks) {
if (
req.headers.origin?.includes(block) ||
req.headers.referer?.includes(block)
) {
req.log.warn(
{ origin: req.headers.origin, referer: req.headers.referer },
"Blocked request from origin or referer"
);
if (!req.accepts("html")) {
return res.status(403).json({
error: { type: "blocked_origin", message: config.blockMessage },
});
} else {
const destination = config.blockRedirect || "https://openai.com";
return res.status(403).send(
`<html>
<head>
<title>Redirecting</title>
<meta http-equiv="refresh" content="3; url=${destination}" />
</head>
<body style="font-family: sans-serif; height: 100vh; display: flex; flex-direction: column; justify-content: center; text-align: center;">
<h2>${config.blockMessage}</h3>
<p><strong>Please hold while you are redirected to a more suitable service.</strong></p>
</body>
</html>`
);
}
}
}
next();
};
+2
View File
@@ -12,6 +12,7 @@ import { handleInfoPage } from "./info-page";
import { logQueue } from "./prompt-logging";
import { start as startRequestQueue } from "./proxy/queue";
import { init as initUserStore } from "./proxy/auth/user-store";
import { checkOrigin } from "./proxy/check-origin";
const PORT = config.port;
@@ -61,6 +62,7 @@ app.use(
app.set("trust proxy", true);
// routes
app.use(checkOrigin);
app.get("/", handleInfoPage);
app.use("/admin", adminRouter);
app.use("/proxy", proxyRouter);