mirror of
https://github.com/katanemo/plano.git
synced 2026-04-26 09:16:24 +02:00
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:
parent
38646fdac2
commit
1df43872a6
16 changed files with 6293 additions and 1979 deletions
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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}`;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue