Fix code scanning and dependabot security alerts (#756)

* Fix code scanning and dependabot security alerts

Code scanning fixes (14 alerts):
- Fix XSS in OG image route by validating request origin against allowlist
- Fix incomplete URL sanitization in blog layout using exact hostname matching
- Bind port-check socket to 127.0.0.1 instead of 0.0.0.0
- Add explicit permissions to 7 GitHub Actions workflows

Dependabot fixes:
- Update @isaacs/brace-expansion 5.0.0 -> 5.0.1 (CVE-2026-25547)
- Update bytes 1.10.1 -> 1.11.1 (CVE-2026-25541)
- Update time 0.3.41 -> 0.3.47 (CVE-2026-25727)
- Update cryptography 45.0.7 -> 46.0.5 (CVE-2026-26007)
- Update python-multipart 0.0.20 -> 0.0.22 (CVE-2026-24486)
- Update urllib3 2.6.2 -> 2.6.3 in test lockfiles (CVE-2026-21441)
- Update Werkzeug 3.1.4 -> 3.1.5 (CVE-2026-21860)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Address PR review feedback

- Replace plano.katanemo.com with planoai.dev in allowed hosts
- Add planoai.dev to OG route and blog layout allowlists
- Revert socket bind to 0.0.0.0 (intentional for port-in-use check)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Adil Hafeez 2026-02-14 12:27:07 -08:00 committed by GitHub
parent 38646fdac2
commit 1df43872a6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 6293 additions and 1979 deletions

View file

@ -4,6 +4,28 @@ import { client, urlFor } from "@/lib/sanity";
export const runtime = "edge";
const ALLOWED_HOSTS = new Set([
"archgw-tau.vercel.app",
"planoai.dev",
"localhost",
]);
function getSafeBaseUrl(requestOrigin: string): string {
if (process.env.NEXT_PUBLIC_APP_URL) {
return process.env.NEXT_PUBLIC_APP_URL;
}
if (process.env.VERCEL_URL) {
return `https://${process.env.VERCEL_URL}`;
}
try {
const parsed = new URL(requestOrigin);
if (ALLOWED_HOSTS.has(parsed.hostname)) {
return parsed.origin;
}
} catch {}
return "http://localhost:3000";
}
// Font loading function that uses the request origin
function loadFont(fileName: string, baseUrl: string) {
return fetch(new URL(`/fonts/${fileName}`, baseUrl)).then((res) => {
@ -55,12 +77,8 @@ export async function GET(
{ params }: { params: Promise<{ slug: string }> },
) {
try {
// Get base URL for font loading - use request origin in production
const fontBaseUrl =
process.env.NEXT_PUBLIC_APP_URL ||
(process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`
: request.nextUrl.origin);
// Get base URL for font loading - use validated origin
const fontBaseUrl = getSafeBaseUrl(request.nextUrl.origin);
// Load fonts with error handling
let fontData;
@ -116,11 +134,7 @@ export async function GET(
}
// Use logo PNG
const baseUrl =
process.env.NEXT_PUBLIC_APP_URL ||
(process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`
: request.nextUrl.origin);
const baseUrl = getSafeBaseUrl(request.nextUrl.origin);
const logoUrl = `${baseUrl}/Logomark.png`;
return new ImageResponse(

View file

@ -47,24 +47,29 @@ export async function generateMetadata({
}
// Get baseUrl - use NEXT_PUBLIC_APP_URL if set, otherwise construct from VERCEL_URL
// Restrict to allowed hosts: localhost:3000, archgw-tau.vercel.app, or plano.katanemo.com
// Restrict to allowed hosts: localhost:3000, archgw-tau.vercel.app, or planoai.dev
let baseUrl = "http://localhost:3000";
if (process.env.NEXT_PUBLIC_APP_URL) {
const url = process.env.NEXT_PUBLIC_APP_URL;
if (
url.includes("archgw-tau.vercel.app") ||
url.includes("plano.katanemo.com") ||
url.includes("localhost:3000")
) {
baseUrl = url;
try {
const parsed = new URL(process.env.NEXT_PUBLIC_APP_URL);
const allowedHosts = new Set([
"archgw-tau.vercel.app",
"planoai.dev",
"localhost",
]);
if (allowedHosts.has(parsed.hostname)) {
baseUrl = parsed.origin;
}
} catch {
// Invalid URL, keep default
}
} else if (process.env.VERCEL_URL) {
const hostname = process.env.VERCEL_URL;
// VERCEL_URL is just the hostname, not the full URL
if (hostname === "archgw-tau.vercel.app") {
baseUrl = `https://${hostname}`;
} else if (hostname === "plano.katanemo.com") {
if (
hostname === "archgw-tau.vercel.app" ||
hostname === "planoai.dev"
) {
baseUrl = `https://${hostname}`;
}
}