From 047792227df0a7e8f4c08f57d8812abebec38341 Mon Sep 17 00:00:00 2001 From: tomaioo Date: Fri, 17 Apr 2026 17:11:49 -0700 Subject: [PATCH 1/2] fix(security): 2 improvements across 2 files - Security: Build script allows path traversal via AI_COOKBOOK_OUTPUT_DIR - Security: Unvalidated href prop may enable javascript: URL injection Signed-off-by: tomaioo <203048277+tomaioo@users.noreply.github.com> --- bin/ensure-ai-cookbook.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bin/ensure-ai-cookbook.js b/bin/ensure-ai-cookbook.js index 6599e04381..9c4dd654e9 100644 --- a/bin/ensure-ai-cookbook.js +++ b/bin/ensure-ai-cookbook.js @@ -4,7 +4,13 @@ const { existsSync, mkdirSync, writeFileSync } = require('fs'); const path = require('path'); const WORKSPACE_ROOT = path.resolve(__dirname, '..'); -const OUTPUT_DIR = path.join(WORKSPACE_ROOT, process.env.AI_COOKBOOK_OUTPUT_DIR ?? 'ai-cookbook'); +const outputDirFromEnv = process.env.AI_COOKBOOK_OUTPUT_DIR ?? 'ai-cookbook'; +const OUTPUT_DIR = path.resolve(WORKSPACE_ROOT, outputDirFromEnv); + +if (OUTPUT_DIR !== WORKSPACE_ROOT && !OUTPUT_DIR.startsWith(`${WORKSPACE_ROOT}${path.sep}`)) { + throw new Error('[ensure-ai-cookbook] AI_COOKBOOK_OUTPUT_DIR must resolve within the repository root'); +} + const PLACEHOLDER_PATH = path.join(OUTPUT_DIR, 'recipes-not-synced.mdx'); // Ensure ai-cookbook directory exists with a placeholder file. From 7aea0e660dfa039dd5b94c15e8689bc03c42983f Mon Sep 17 00:00:00 2001 From: tomaioo Date: Fri, 17 Apr 2026 17:11:49 -0700 Subject: [PATCH 2/2] fix(security): 2 improvements across 2 files - Security: Build script allows path traversal via AI_COOKBOOK_OUTPUT_DIR - Security: Unvalidated href prop may enable javascript: URL injection Signed-off-by: tomaioo <203048277+tomaioo@users.noreply.github.com> --- src/components/elements/CallToAction.js | 26 ++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/components/elements/CallToAction.js b/src/components/elements/CallToAction.js index 7be158145a..7ff006b384 100644 --- a/src/components/elements/CallToAction.js +++ b/src/components/elements/CallToAction.js @@ -1,9 +1,33 @@ import React from 'react'; import styles from './call-to-action.module.css'; + const getSafeHref = (href) => { + if (typeof href !== 'string') { + return '#'; + } + + const value = href.trim(); + + if (!value || value.startsWith('/') || value.startsWith('#') || value.startsWith('?')) { + return value || '#'; + } + + const lowerValue = value.toLowerCase(); + + if ( + lowerValue.startsWith('http://') || + lowerValue.startsWith('https://') || + lowerValue.startsWith('mailto:') + ) { + return value; + } + + return '#'; + }; + export const CallToAction = ({ href, children }) => { return ( - +
{children}