T09 · Insecure Skill Coding Practices
- Location
scripts/gemini-image-runtime.mjs:127- Finding
Unrestricted Local File Read and Transmission to a Remote Service
- Content
View full analysis
1 && mimeTypes.length !== inputPaths.length) { throw new Error("Pass either one --mime-type for all inputs or one --mime-type per --input"); } return Promise.all( inputPaths.map(async (inputPath, index) => { const imageBuffer = await fs.readFile(inputPath); const mimeType = mimeTypes[index] || mimeTypes[0] || mimeTypeForPath(inputPath); return { mimeType, data: imageBuffer.toString("base64"), }; }), ); } ``` The corresponding call site accepts the input path directly from command-line arguments: ```js const args = parseArgs(process.argv.slice(2)); const prompt = requireSingleArg(args.prompt, "prompt"); const inputs = normalizeArgList(requireSingleArg(args.input, "input")); const output = requireSingleArg(args.output, "output"); const mimeTypes = normalizeArgList(args["mime-type"]); const imageConfig = readImageConfigArgs(args); const inlineDataParts = await createInlineDataParts(inputs, mimeTypes); const { ai, model } = createGeminiImageClientFromEnv(); const response = await ai.models.generateContent( createImageGenerationRequest({ model, prompt, inlineDataParts, imageConfig, }), ); ``` ### Technical Analysis The `--input` argument is treated as a filesystem path and passed directly to `fs.readFile`. The implementation does not: - Restrict the path to an approved workspace or input directory. - Reject absolute paths or `..` traversal. - Resolve and validate the canonical path. - Detect symlinks that resolve outs ...[truncated 1590 chars]- Remediation
View remediation
