From f62ff40403ffa1781459d6be8d97b8035888c00c Mon Sep 17 00:00:00 2001 From: Nishant Jain Date: Thu, 11 Jul 2024 19:23:15 -0700 Subject: [PATCH] block list --- .env.sample | 3 +++ src/app.ts | 11 +++++++++-- src/lib/utils.ts | 2 +- src/middlewares/allow_list.ts | 4 +++- src/middlewares/block_list.ts | 22 ++++++++++++++++++++++ 5 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 src/middlewares/block_list.ts diff --git a/.env.sample b/.env.sample index 879fca7..1ac6790 100644 --- a/.env.sample +++ b/.env.sample @@ -10,6 +10,9 @@ NODE_ENV=development # Comma-separated list of allowed domains for screenshots (optional) #ALLOW_LIST=jasonraimondi.com,github.com +# Comma-separated list of allowed domains for screenshots (optional) +# BLOCK_LIST=example.com + # Cache-Control header value for the responses (optional) #CACHE_CONTROL="public, max-age=86400, immutable" diff --git a/src/app.ts b/src/app.ts index babc3b6..2ac5c6b 100644 --- a/src/app.ts +++ b/src/app.ts @@ -8,8 +8,9 @@ import { ImageRenderInterface } from "./lib/image_render.js"; import { logger } from "./lib/logger.js"; import { PlainConfigSchema } from "./lib/schema.js"; import { ImageStorage } from "./lib/storage/_base.js"; -import { formatAllowList } from "./lib/utils.js"; +import { formatUrlList } from "./lib/utils.js"; import { handleAllowListMiddleware } from "./middlewares/allow_list.js"; +import { handleBlockListMiddleware } from "./middlewares/block_list.js"; import { handleExtractQueryParamsMiddleware } from "./middlewares/extract_query_params.js"; import { getIndex } from "./routes/index.js"; @@ -57,8 +58,14 @@ export function createApplication( app.use("/", handleExtractQueryParamsMiddleware(stringEncrypter)); + if (process.env.BLOCK_LIST && process.env.BLOCK_LIST.trim() !== "") { + const allowList = formatUrlList(process.env.BLOCK_LIST); + logger.info(`Blocked Domains: ${allowList.join(", ")}`); + app.use("/", handleBlockListMiddleware(allowList)); + } + if (process.env.ALLOW_LIST && process.env.ALLOW_LIST.trim() !== "") { - const allowList = formatAllowList(process.env.ALLOW_LIST); + const allowList = formatUrlList(process.env.ALLOW_LIST); logger.info(`Allowed Domains: ${allowList.join(", ")}`); app.use("/", handleAllowListMiddleware(allowList)); } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 86b38a9..c4062f0 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,4 +1,4 @@ -export function formatAllowList(allowList: string): string[] { +export function formatUrlList(allowList: string): string[] { return allowList.split(",").map(url => { url = url.trim().replace(/https?:\/\//g, ""); return new URL(`http://${url}`).host; diff --git a/src/middlewares/allow_list.ts b/src/middlewares/allow_list.ts index 04891b7..45021c0 100644 --- a/src/middlewares/allow_list.ts +++ b/src/middlewares/allow_list.ts @@ -7,7 +7,9 @@ import { logger } from "../lib/logger.js"; export function handleAllowListMiddleware(allowList: string[]) { return async (c: Context, next: () => Promise) => { const input = c.get("input"); - const isValidDomain = allowList.includes(new URL(input.url).host); + const newurl = new URL(input.url).host; + logger.info(`URL new: ${newurl}`); + const isValidDomain = allowList.includes(newurl); if (!isValidDomain) { logger.warn(`Blocked request to ${input.url} - not in allowlist`); diff --git a/src/middlewares/block_list.ts b/src/middlewares/block_list.ts new file mode 100644 index 0000000..30888e1 --- /dev/null +++ b/src/middlewares/block_list.ts @@ -0,0 +1,22 @@ +// blockedHostsMiddleware.ts +import { Context } from "hono"; +import { HTTPException } from "hono/http-exception"; + +import { AppEnv } from "../app.js"; +import { logger } from "../lib/logger.js"; + +export function handleBlockListMiddleware(blockList: string[]) { + return async (c: Context, next: () => Promise) => { + const input = c.get("input"); + const urlHost = new URL(input.url).host; + logger.info(`Request URL host: ${urlHost}`); + + // Check if the host is in the block list + if (blockList.includes(urlHost)) { + logger.warn(`Blocked request to ${input.url} - host is in block list`); + throw new HTTPException(403, { message: "Access to this URL is forbidden" }); + } + + await next(); + }; +}