mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-06-09 23:25:51 +08:00
fix(security): disable executable gray-matter frontmatter in commands
This commit is contained in:
@@ -3,8 +3,8 @@ import { promises as fs } from 'fs';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
import matter from 'gray-matter';
|
|
||||||
import { CLAUDE_MODELS, CURSOR_MODELS, CODEX_MODELS } from '../../shared/modelConstants.js';
|
import { CLAUDE_MODELS, CURSOR_MODELS, CODEX_MODELS } from '../../shared/modelConstants.js';
|
||||||
|
import { parseFrontmatter } from '../utils/frontmatter.js';
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = path.dirname(__filename);
|
const __dirname = path.dirname(__filename);
|
||||||
@@ -38,7 +38,7 @@ async function scanCommandsDirectory(dir, baseDir, namespace) {
|
|||||||
// Parse markdown file for metadata
|
// Parse markdown file for metadata
|
||||||
try {
|
try {
|
||||||
const content = await fs.readFile(fullPath, 'utf8');
|
const content = await fs.readFile(fullPath, 'utf8');
|
||||||
const { data: frontmatter, content: commandContent } = matter(content);
|
const { data: frontmatter, content: commandContent } = parseFrontmatter(content);
|
||||||
|
|
||||||
// Calculate relative path from baseDir for command name
|
// Calculate relative path from baseDir for command name
|
||||||
const relativePath = path.relative(baseDir, fullPath);
|
const relativePath = path.relative(baseDir, fullPath);
|
||||||
@@ -475,7 +475,7 @@ router.post('/load', async (req, res) => {
|
|||||||
|
|
||||||
// Read and parse the command file
|
// Read and parse the command file
|
||||||
const content = await fs.readFile(commandPath, 'utf8');
|
const content = await fs.readFile(commandPath, 'utf8');
|
||||||
const { data: metadata, content: commandContent } = matter(content);
|
const { data: metadata, content: commandContent } = parseFrontmatter(content);
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
path: commandPath,
|
path: commandPath,
|
||||||
@@ -560,7 +560,7 @@ router.post('/execute', async (req, res) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const content = await fs.readFile(commandPath, 'utf8');
|
const content = await fs.readFile(commandPath, 'utf8');
|
||||||
const { data: metadata, content: commandContent } = matter(content);
|
const { data: metadata, content: commandContent } = parseFrontmatter(content);
|
||||||
// Basic argument replacement (will be enhanced in command parser utility)
|
// Basic argument replacement (will be enhanced in command parser utility)
|
||||||
let processedContent = commandContent;
|
let processedContent = commandContent;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import matter from 'gray-matter';
|
|
||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { execFile } from 'child_process';
|
import { execFile } from 'child_process';
|
||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
import { parse as parseShellCommand } from 'shell-quote';
|
import { parse as parseShellCommand } from 'shell-quote';
|
||||||
|
import { parseFrontmatter } from './frontmatter.js';
|
||||||
|
|
||||||
const execFileAsync = promisify(execFile);
|
const execFileAsync = promisify(execFile);
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ const BASH_COMMAND_ALLOWLIST = [
|
|||||||
*/
|
*/
|
||||||
export function parseCommand(content) {
|
export function parseCommand(content) {
|
||||||
try {
|
try {
|
||||||
const parsed = matter(content);
|
const parsed = parseFrontmatter(content);
|
||||||
return {
|
return {
|
||||||
data: parsed.data || {},
|
data: parsed.data || {},
|
||||||
content: parsed.content || '',
|
content: parsed.content || '',
|
||||||
|
|||||||
18
server/utils/frontmatter.js
Normal file
18
server/utils/frontmatter.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import matter from 'gray-matter';
|
||||||
|
|
||||||
|
const disabledFrontmatterEngine = () => ({});
|
||||||
|
|
||||||
|
const frontmatterOptions = {
|
||||||
|
language: 'yaml',
|
||||||
|
// Disable JS/JSON frontmatter parsing to avoid executable project content.
|
||||||
|
// Mirrors Gatsby's mitigation for gray-matter.
|
||||||
|
engines: {
|
||||||
|
js: disabledFrontmatterEngine,
|
||||||
|
javascript: disabledFrontmatterEngine,
|
||||||
|
json: disabledFrontmatterEngine
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function parseFrontmatter(content) {
|
||||||
|
return matter(content, frontmatterOptions);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user