Mostly safe โ a couple of notes worth reading.
Scanned 5/3/2026, 6:50:10 PMยทCached resultยทFast Scanยท45 rulesยทHow we decide โ
AIVSS Score
Low
Severity Breakdown
0
critical
0
high
51
medium
0
low
MCP Server Information
Findings
This package receives a B grade with a safety score of 70/100 and carries moderate risk due to 51 medium-severity findings, primarily centered on server configuration issues (45 findings) and ANSI escape injection vulnerabilities (6 findings). While no critical or high-severity flaws were identified, the configuration weaknesses could expose your system to misuse if the server is deployed without proper hardening. You should review and apply the recommended configuration mitigations before using this in production environments.
No known CVEs found for this package or its dependencies.
Scan Details
Want deeper analysis?
Fast scan found 51 findings using rule-based analysis. Upgrade for LLM consensus across 5 judges, AI-generated remediation, and cross-file taint analysis.
Building your own MCP server?
Same rules, same LLM judges, same grade. Private scans stay isolated to your account and never appear in the public registry. Required for code your team hasnโt shipped yet.
Showing 1โ30 of 51 findings
51 findings
Service binds to 0.0.0.0 โ all network interfaces. For MCP servers that only need to talk to a single parent process, bind to 127.0.0.1 (or a Unix domain socket) instead.
Evidence
| 191 | }) |
| 192 | |
| 193 | // ์๋ฒ ์์ (0.0.0.0์ผ๋ก ๋ฐ์ธ๋ฉํ์ฌ ์ธ๋ถ ์ ์ ํ์ฉ) |
| 194 | const expressServer = app.listen(port, "0.0.0.0", () => { |
| 195 | console.error(`โ Korean Law MCP server (HTTP stateless) listening on port ${port}`) |
| 196 | console.error(`โ MCP endpoint: http://0.0.0.0:${port}/mcp`) |
| 197 | console.error(`โ Health check: http://0.0.0.0:${port}/health`) |
Remediation
Bind to 127.0.0.1 for local-only access. If cross-host access is truly required, put the service behind an authenticated reverse proxy rather than exposing it on 0.0.0.0.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 225 | .description("์์ฐ์ด ์ง์์ ๋ผ์ฐํ ๊ฒฝ๋ก ํ์ธ (์คํํ์ง ์์)") |
| 226 | .action((words: string[]) => { |
| 227 | const query = words.join(" ") |
| 228 | console.log(explainRoute(query)) |
| 229 | }) |
| 230 | |
| 231 | // โโ list ๋ช ๋ น โโ |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 342 | try { |
| 343 | input = JSON.parse(cmdOpts.jsonInput) |
| 344 | } catch { |
| 345 | console.error(fmt.red("--json-input ํ์ฑ ์คํจ: ์ ํจํ JSON์ ์ ๋ ฅํ์ธ์.")) |
| 346 | process.exit(1) |
| 347 | } |
| 348 | } else { |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 170 | isError: result.isError || false, |
| 171 | }, null, 2)) |
| 172 | } catch (error) { |
| 173 | console.log(JSON.stringify({ |
| 174 | query, |
| 175 | route: { tool: route.tool, reason: route.reason }, |
| 176 | error: error instanceof Error ? error.message : String(error), |
| 177 | }, null, 2)) |
| 178 | process.exit(1) |
| 179 | } |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 72 | const route = routeQuery(query) |
| 73 | |
| 74 | if (verbose) { |
| 75 | console.log(fmt.dim(explainRoute(query))) |
| 76 | } else { |
| 77 | printRouteInfo(route.tool, route.reason) |
| 78 | } |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 257 | printBanner() |
| 258 | printToolList() |
| 259 | console.log(fmt.dim(" ์ฌ์ฉ๋ฒ: korean-law <๋๊ตฌ๋ช > [์ต์ ]")) |
| 260 | console.log(fmt.dim(" ์์ฐ์ด: korean-law query \"๋ฏผ๋ฒ ์ 1์กฐ\"")) |
| 261 | console.log(fmt.dim(" ๋ํํ: korean-law interactive")) |
| 262 | console.log() |
| 263 | }) |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 162 | } |
| 163 | } |
| 164 | |
| 165 | console.log(JSON.stringify({ |
| 166 | query, |
| 167 | route: { tool: route.tool, reason: route.reason, params: route.params }, |
| 168 | result: result.content.map(c => c.text).join("\n"), |
| 169 | pipelineResult, |
| 170 | isError: result.isError || false, |
| 171 | }, null, 2)) |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 271 | // ======================================== |
| 272 | |
| 273 | export const chainDisputePrepSchema = z.object({ |
| 274 | query: z.string().describe("๋ถ์ ํค์๋ (์: '๊ฑด์ถํ๊ฐ ์ทจ์ ํ์ ์ฌํ', '์ง๊ณ์ฒ๋ถ ๊ฐ๊ฒฝ')"), |
| 275 | domain: z.enum(["tax", "labor", "privacy", "competition", "general"]).optional() |
| 276 | .describe("์ ๋ฌธ ๋ถ์ผ (tax=์กฐ์ธ์ฌํ, labor=๋ ธ๋์, privacy=๊ฐ์ธ์ ๋ณด์, competition=๊ณต์ ์). ๋ฏธ์ง์ ์ ์ฟผ๋ฆฌ์์ ์๋ ๊ฐ์ง"), |
| 277 | apiKey: z.string().optional(), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 9 | // ======================================== |
| 10 | |
| 11 | const baseSearchSchema = { |
| 12 | query: z.string().optional().describe("๊ฒ์ ํค์๋"), |
| 13 | display: z.number().min(1).max(100).default(20).describe("ํ์ด์ง๋น ๊ฒฐ๊ณผ ๊ฐ์ (๊ธฐ๋ณธ๊ฐ: 20, ์ต๋: 100)"), |
| 14 | page: z.number().min(1).default(1).describe("ํ์ด์ง ๋ฒํธ (๊ธฐ๋ณธ๊ฐ: 1)"), |
| 15 | sort: z.enum(["lasc", "ldes", "dasc", "ddes", "nasc", "ndes"]).optional() |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 6 | // English law search tool - Search for English translations of Korean laws |
| 7 | export const searchEnglishLawSchema = z.object({ |
| 8 | query: z.string().optional().describe("๋ฒ๋ น๋ช ๊ฒ์์ด (์๋ฌธ ๋๋ ํ๊ธ, ์: 'Customs Act', '๊ด์ธ๋ฒ')"), |
| 9 | display: z.number().min(1).max(100).default(20).describe("ํ์ด์ง๋น ๊ฒฐ๊ณผ ๊ฐ์ (๊ธฐ๋ณธ๊ฐ: 20, ์ต๋: 100)"), |
| 10 | page: z.number().min(1).default(1).describe("ํ์ด์ง ๋ฒํธ (๊ธฐ๋ณธ๊ฐ: 1)"), |
| 11 | sort: z.enum(["lasc", "ldes", "dasc", "ddes"]).optional() |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 13 | // 1. ๋ฒ๋ น์ฉ์ด ์ง์๋ฒ ์ด์ค ์กฐํ (lstrmAI) |
| 14 | export const getLegalTermKBSchema = z.object({ |
| 15 | query: z.string().describe("๊ฒ์ํ ๋ฒ๋ น์ฉ์ด"), |
| 16 | display: z.number().min(1).max(100).default(20).describe("๊ฒฐ๊ณผ ์ (๊ธฐ๋ณธ:20)"), |
| 17 | page: z.number().min(1).default(1).describe("ํ์ด์ง (๊ธฐ๋ณธ:1)"), |
| 18 | apiKey: z.string().optional().describe("๋ฒ์ ์ฒ Open API ์ธ์ฆํค(OC). ์ฌ์ฉ์๊ฐ ์ ๊ณตํ ๊ฒฝ์ฐ ์ ๋ฌ"), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 146 | export const searchAcrSpecialAppealsSchema = z.object({ |
| 147 | ...baseSearchSchema, |
| 148 | query: z.string().optional().describe("๊ฒ์ ํค์๋ (์: '๊ตญ๋ฏผ๊ถ์ต', 'ํ์ ์ฌํ', '๊ณ ์ถฉ')"), |
| 149 | }); |
| 150 | export type SearchAcrSpecialAppealsInput = z.infer<typeof searchAcrSpecialAppealsSchema>; |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 6 | // Legal terms search tool - Search for legal terminology definitions |
| 7 | export const searchLegalTermsSchema = z.object({ |
| 8 | query: z.string().describe("๊ฒ์ํ ๋ฒ๋ น์ฉ์ด (์: '์ ์', '์ ์', 'ํ์', '์ฑ๊ถ')"), |
| 9 | display: z.number().min(1).max(100).default(20).describe("ํ์ด์ง๋น ๊ฒฐ๊ณผ ๊ฐ์ (๊ธฐ๋ณธ๊ฐ: 20, ์ต๋: 100)"), |
| 10 | page: z.number().min(1).default(1).describe("ํ์ด์ง ๋ฒํธ (๊ธฐ๋ณธ๊ฐ: 1)"), |
| 11 | apiKey: z.string().optional().describe("๋ฒ์ ์ฒ Open API ์ธ์ฆํค(OC). ์ฌ์ฉ์๊ฐ ์ ๊ณตํ ๊ฒฝ์ฐ ์ ๋ฌ"), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 331 | // ======================================== |
| 332 | |
| 333 | export const chainAmendmentTrackSchema = z.object({ |
| 334 | query: z.string().describe("๋ฒ๋ น๋ช (์: '๊ด์ธ๋ฒ', '์ง๋ฐฉ์ธํน๋ก์ ํ๋ฒ')"), |
| 335 | mst: z.string().optional().describe("๋ฒ๋ น์ผ๋ จ๋ฒํธ (์๊ณ ์์ผ๋ฉด)"), |
| 336 | lawId: z.string().optional().describe("๋ฒ๋ นID (์๊ณ ์์ผ๋ฉด)"), |
| 337 | scenario: z.enum(["timeline"]).optional() |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 31 | query: z.string().describe("๋ถ์ฒ๋ช (์: '๋ณด๊ฑด๋ณต์ง๋ถ')") |
| 32 | }) |
| 33 | export const LinkedLawsFromOrdinanceSchema = baseLinkageSchema.extend({ |
| 34 | query: z.string().describe("์์น๋ฒ๊ท๋ช (์: '์์ธํน๋ณ์ ์ฃผ์ฐจ์ฅ ์ค์น ๋ฐ ๊ด๋ฆฌ ์กฐ๋ก')") |
| 35 | }) |
| 36 | |
| 37 | // === ๋ฒ์ฉ XML ํ์ (์๋ต ๊ตฌ์กฐ ๋ฏธํ์ ๋์) === |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 118 | export const searchAcrDecisionsSchema = z.object({ |
| 119 | ...baseSearchSchemaOptionalQuery, |
| 120 | query: z.string().optional().describe("๊ฒ์ ํค์๋ (์: 'ํ์ ์ฌํ', '๊ณ ์ถฉ๋ฏผ์', '๋ถํจํ์')"), |
| 121 | }); |
| 122 | |
| 123 | export type SearchAcrDecisionsInput = z.infer<typeof searchAcrDecisionsSchema>; |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 9 | // ======================================== |
| 10 | |
| 11 | const searchSchema = { |
| 12 | query: z.string().describe("๊ฒ์ ํค์๋"), |
| 13 | display: z.number().min(1).max(100).default(20).describe("ํ์ด์ง๋น ๊ฒฐ๊ณผ ๊ฐ์ (๊ธฐ๋ณธ๊ฐ: 20, ์ต๋: 100)"), |
| 14 | page: z.number().min(1).default(1).describe("ํ์ด์ง ๋ฒํธ (๊ธฐ๋ณธ๊ฐ: 1)"), |
| 15 | sort: z.enum(["lasc", "ldes", "dasc", "ddes"]).optional() |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 28 | query: z.string().describe("๋ฒ๋ น๋ช (์: '๊ตญ๋ฏผ๊ฑด๊ฐ๋ณดํ๋ฒ')") |
| 29 | }) |
| 30 | export const DelegatedLawsSchema = baseLinkageSchema.extend({ |
| 31 | query: z.string().describe("๋ถ์ฒ๋ช (์: '๋ณด๊ฑด๋ณต์ง๋ถ')") |
| 32 | }) |
| 33 | export const LinkedLawsFromOrdinanceSchema = baseLinkageSchema.extend({ |
| 34 | query: z.string().describe("์์น๋ฒ๊ท๋ช (์: '์์ธํน๋ณ์ ์ฃผ์ฐจ์ฅ ์ค์น ๋ฐ ๊ด๋ฆฌ ์กฐ๋ก')") |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 6 | // Customs legal interpretation search tool - Search for customs law interpretations |
| 7 | export const searchCustomsInterpretationsSchema = z.object({ |
| 8 | query: z.string().optional().describe("Search keyword (e.g., '๊ฑฐ๋๋ช ์ธ์', '์ธ๊ธ')"), |
| 9 | display: z.number().min(1).max(100).default(20).describe("Results per page (default: 20, max: 100)"), |
| 10 | page: z.number().min(1).default(1).describe("Page number (default: 1)"), |
| 11 | inq: z.number().optional().describe("Inquiry organization code (์ง์๊ธฐ๊ด์ฝ๋)"), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 529 | // ======================================== |
| 530 | |
| 531 | export const chainProcedureDetailSchema = z.object({ |
| 532 | query: z.string().describe("์ ์ฐจ/๋น์ฉ ๊ด๋ จ ์ง๋ฌธ (์: '์ฌ๊ถ๋ฐ๊ธ ์ ์ฐจ ์์๋ฃ', '๊ฑด์ถํ๊ฐ ์ ์ฒญ ๋ฐฉ๋ฒ')"), |
| 533 | scenario: z.enum(["manual"]).optional() |
| 534 | .describe("ํ์ฅ ์๋๋ฆฌ์ค. manual=๊ณต๋ฌด์ ์ฒ๋ฆฌ ๋งค๋ด์ผ (ํ์ ๊ท์น + ์์น๋ฒ๊ท ํน์น + ํด์๋ก ์ถ๊ฐ). ๋ฏธ์ง์ ์ ์ฟผ๋ฆฌ์์ ์๋ ๊ฐ์ง."), |
| 535 | apiKey: z.string().optional(), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 7 | // Administrative appeal decision search tool - Search for administrative tribunal rulings |
| 8 | export const searchAdminAppealsSchema = z.object({ |
| 9 | query: z.string().optional().describe("๊ฒ์ ํค์๋ (์: '์ทจ์์ฒ๋ถ', '์์ ์ ์ง', '๊ณผํ๋ฃ')"), |
| 10 | display: z.number().min(1).max(100).default(20).describe("ํ์ด์ง๋น ๊ฒฐ๊ณผ ๊ฐ์ (๊ธฐ๋ณธ๊ฐ: 20, ์ต๋: 100)"), |
| 11 | page: z.number().min(1).default(1).describe("ํ์ด์ง ๋ฒํธ (๊ธฐ๋ณธ๊ฐ: 1)"), |
| 12 | sort: z.enum(["lasc", "ldes", "dasc", "ddes", "nasc", "ndes"]).optional() |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 125 | export const searchAppealReviewDecisionsSchema = z.object({ |
| 126 | ...baseSearchSchema, |
| 127 | query: z.string().optional().describe("๊ฒ์ ํค์๋ (์: 'ํ๋ฉด', 'ํด์', '์ง๊ณ', '๊ฐ๋ด')"), |
| 128 | }); |
| 129 | export type SearchAppealReviewDecisionsInput = z.infer<typeof searchAppealReviewDecisionsSchema>; |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 461 | // ======================================== |
| 462 | |
| 463 | export const chainFullResearchSchema = z.object({ |
| 464 | query: z.string().describe("์์ฐ์ด ์ง๋ฌธ (์: '๊ธฐ๊ฐ์ ๊ทผ๋ก์ 2๋ ์ด๊ณผ ์ฌ์ฉ', '์์ฃผ์ด์ ์ฒ๋ฒ ๊ธฐ์ค')"), |
| 465 | scenario: z.enum(["customs"]).optional() |
| 466 | .describe("ํ์ฅ ์๋๋ฆฌ์ค. customs=๊ด์ธยทํต๊ด ์ข ํฉ (๊ด์ธ3๋ฒ + ํด์๋ก + FTA์กฐ์ฝ + ์ธ์จํ + ์กฐ์ธ์ฌํ). ๋ฏธ์ง์ ์ ์ฟผ๋ฆฌ์์ ์๋ ๊ฐ์ง."), |
| 467 | apiKey: z.string().optional(), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 25 | query: z.string().describe("๋ฒ๋ น๋ช (์: '๊ตญ๋ฏผ๊ฑด๊ฐ๋ณดํ๋ฒ')") |
| 26 | }) |
| 27 | export const LinkedOrdinanceArticlesSchema = baseLinkageSchema.extend({ |
| 28 | query: z.string().describe("๋ฒ๋ น๋ช (์: '๊ตญ๋ฏผ๊ฑด๊ฐ๋ณดํ๋ฒ')") |
| 29 | }) |
| 30 | export const DelegatedLawsSchema = baseLinkageSchema.extend({ |
| 31 | query: z.string().describe("๋ถ์ฒ๋ช (์: '๋ณด๊ฑด๋ณต์ง๋ถ')") |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 62 | export const searchPipcDecisionsSchema = z.object({ |
| 63 | ...baseSearchSchemaRequiredQuery, |
| 64 | query: z.string().describe("๊ฒ์ ํค์๋ (ํ์, ์: '๊ฐ์ธ์ ๋ณด', '์ ์ถ', '๊ณผ์ง๊ธ')"), |
| 65 | }); |
| 66 | |
| 67 | export type SearchPipcDecisionsInput = z.infer<typeof searchPipcDecisionsSchema>; |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 221 | // compare_admin_rule_old_new ์คํค๋ง |
| 222 | export const CompareAdminRuleOldNewSchema = z.object({ |
| 223 | query: z.string().optional().describe("ํ์ ๊ท์น๋ช ํค์๋ (๊ฒ์์ฉ)"), |
| 224 | id: z.string().optional().describe("ํ์ ๊ท์นID (๋ณธ๋ฌธ ์กฐํ์ฉ, search_admin_rule์์ ํ๋)"), |
| 225 | apiKey: z.string().optional().describe("๋ฒ์ ์ฒ Open API ์ธ์ฆํค(OC). ์ฌ์ฉ์๊ฐ ์ ๊ณตํ ๊ฒฝ์ฐ ์ ๋ฌ") |
| 226 | }).refine(data => data.query || data.id, { |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 10 | import { formatToolError } from "../lib/errors.js" |
| 11 | |
| 12 | export const SearchOrdinanceSchema = z.object({ |
| 13 | query: z.string().describe("๊ฒ์ํ ์์น๋ฒ๊ท๋ช (์: '์์ธ', 'ํ๊ฒฝ')"), |
| 14 | display: z.number().min(1).max(100).default(20).describe("ํ์ด์ง๋น ๊ฒฐ๊ณผ ๊ฐ์ (๊ธฐ๋ณธ๊ฐ: 20, ์ต๋: 100)"), |
| 15 | apiKey: z.string().optional().describe("๋ฒ์ ์ฒ Open API ์ธ์ฆํค(OC). ์ฌ์ฉ์๊ฐ ์ ๊ณตํ ๊ฒฝ์ฐ ์ ๋ฌ") |
| 16 | }) |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 11 | import { expandLawQuery } from "../lib/search-normalizer.js" |
| 12 | |
| 13 | export const SearchLawSchema = z.object({ |
| 14 | query: z.string().describe("๊ฒ์ํ ๋ฒ๋ น๋ช (์: '๊ด์ธ๋ฒ', 'ftaํน๋ก๋ฒ', 'ํ๊ด๋ฒ')"), |
| 15 | display: z.number().optional().default(20).describe("์ต๋ ๊ฒฐ๊ณผ ๊ฐ์"), |
| 16 | apiKey: z.string().optional().describe("๋ฒ์ ์ฒ Open API ์ธ์ฆํค(OC). ์ฌ์ฉ์๊ฐ ์ ๊ณตํ ๊ฒฝ์ฐ ์ ๋ฌ") |
| 17 | }) |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 10 | import { formatToolError } from "../lib/errors.js" |
| 11 | |
| 12 | export const FindSimilarPrecedentsSchema = z.object({ |
| 13 | query: z.string().describe("๊ฒ์ ํค์๋ ๋๋ ํ๋ก ๋ด์ฉ"), |
| 14 | display: z.number().optional().default(5).describe("์ต๋ ๊ฒฐ๊ณผ ๊ฐ์ (๊ธฐ๋ณธ๊ฐ: 5)"), |
| 15 | apiKey: z.string().optional().describe("๋ฒ์ ์ฒ Open API ์ธ์ฆํค(OC). ์ฌ์ฉ์๊ฐ ์ ๊ณตํ ๊ฒฝ์ฐ ์ ๋ฌ") |
| 16 | }) |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 5 | import { formatToolError } from "../lib/errors.js" |
| 6 | |
| 7 | export const searchTreatiesSchema = z.object({ |
| 8 | query: z.string().optional().describe("๊ฒ์ ํค์๋ (์: 'ํฌ์๋ณด์ฅ', '๋ฒ์ฃ์ธ์ธ๋')"), |
| 9 | cls: z.enum(["1", "2"]).optional().describe("์กฐ์ฝ๊ตฌ๋ถ (1=์์์กฐ์ฝ, 2=๋ค์์กฐ์ฝ)"), |
| 10 | natCd: z.string().optional().describe("๊ตญ๊ฐ์ฝ๋ (์: 'US', 'JP')"), |
| 11 | eftYd: z.string().optional().describe("๋ฐํจ์ผ (YYYYMMDD)"), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 122 | // 3. ์ผ์์ฉ์ด ์กฐํ |
| 123 | export const getDailyTermSchema = z.object({ |
| 124 | query: z.string().describe("๊ฒ์ํ ์ผ์์ฉ์ด (์: '์์ธ', '์ ์ธ', '๋บ์๋')"), |
| 125 | display: z.number().min(1).max(100).default(20).describe("๊ฒฐ๊ณผ ์ (๊ธฐ๋ณธ:20)"), |
| 126 | page: z.number().min(1).default(1).describe("ํ์ด์ง (๊ธฐ๋ณธ:1)"), |
| 127 | apiKey: z.string().optional().describe("๋ฒ์ ์ฒ Open API ์ธ์ฆํค(OC). ์ฌ์ฉ์๊ฐ ์ ๊ณตํ ๊ฒฝ์ฐ ์ ๋ฌ"), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 34 | export const searchFtcDecisionsSchema = z.object({ |
| 35 | ...baseSearchSchemaRequiredQuery, |
| 36 | query: z.string().describe("๊ฒ์ ํค์๋ (ํ์, ์: '๋ดํฉ', '๋ถ๊ณต์ ๊ฑฐ๋', '์์ ๋ช ๋ น')"), |
| 37 | }); |
| 38 | |
| 39 | export type SearchFtcDecisionsInput = z.infer<typeof searchFtcDecisionsSchema>; |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 6 | // Tax tribunal decision search tool - Search for special administrative appeals decisions |
| 7 | export const searchTaxTribunalDecisionsSchema = z.object({ |
| 8 | query: z.string().optional().describe("Search keyword (e.g., '์๋์ฐจ', '๋ถ๊ฐ๊ฐ์น์ธ')"), |
| 9 | display: z.number().min(1).max(100).default(20).describe("Results per page (default: 20, max: 100)"), |
| 10 | page: z.number().min(1).default(1).describe("Page number (default: 1)"), |
| 11 | cls: z.string().optional().describe("Decision type code (์ฌ๊ฒฐ๊ตฌ๋ถ์ฝ๋)"), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 7 | // AI-powered intelligent law search tool |
| 8 | // ์ด๋ฆ์ searchAiLaw๊ฐ ๋ ์ ํํ์ง๋ง, ํธํ์ฑ์ ์ํด searchLifeLaw alias ์ ์ง |
| 9 | export const searchAiLawSchema = z.object({ |
| 10 | query: z.string().describe("์์ฐ์ด ์ง๋ฌธ ๋๋ ์ผ์ ์ํฉ (์: '์์ฃผ์ด์ ์ฒ๋ฒ', '์๋์ฐจ ๋ณด์ฆ๊ธ ๋ฐํ', 'ํด์ง๊ธ ๊ณ์ฐ')"), |
| 11 | search: z.enum(["0", "1", "2", "3"]).default("0").describe( |
| 12 | "๊ฒ์๋ฒ์: 0=๋ฒ๋ น์กฐ๋ฌธ(๊ธฐ๋ณธ), 1=๋ฒ๋ น ๋ณํยท์์, 2=ํ์ ๊ท์น ์กฐ๋ฌธ, 3=ํ์ ๊ท์น ๋ณํยท์์" |
| 13 | ), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 123 | domain: z.enum(DOMAINS).describe( |
| 124 | "๋๋ฉ์ธ ์ ํ (enum ๊ฐ ์ฐธ์กฐ)" |
| 125 | ), |
| 126 | query: z.string().optional().describe("๊ฒ์ ํค์๋"), |
| 127 | display: z.number().min(1).max(100).default(20).optional().describe("๊ฒฐ๊ณผ ์ (๊ธฐ๋ณธ20)"), |
| 128 | page: z.number().min(1).default(1).optional().describe("ํ์ด์ง (๊ธฐ๋ณธ1)"), |
| 129 | sort: z.string().optional().describe("์ ๋ ฌ: lasc/ldes/dasc/ddes/nasc/ndes"), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 15 | // === ์คํค๋ง === |
| 16 | |
| 17 | const baseLinkageSchema = z.object({ |
| 18 | query: z.string().describe("๊ฒ์ ํค์๋"), |
| 19 | display: z.number().min(1).max(100).default(20).describe("๊ฒฐ๊ณผ ๊ฐ์ (๊ธฐ๋ณธ:20, ์ต๋:100)"), |
| 20 | page: z.number().min(1).default(1).describe("ํ์ด์ง ๋ฒํธ (๊ธฐ๋ณธ:1)"), |
| 21 | apiKey: z.string().optional().describe("๋ฒ์ ์ฒ Open API ์ธ์ฆํค(OC)") |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 9 | import { formatToolError } from "../lib/errors.js" |
| 10 | |
| 11 | export const AdvancedSearchSchema = z.object({ |
| 12 | query: z.string().describe("๊ฒ์ ํค์๋"), |
| 13 | searchType: z.enum(["law", "admin_rule", "ordinance", "all"]).optional().default("law").describe( |
| 14 | "๊ฒ์ ๋์: law (๋ฒ๋ น), admin_rule (ํ์ ๊ท์น), ordinance (์์น๋ฒ๊ท), all (์ ์ฒด)" |
| 15 | ), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 22 | }) |
| 23 | |
| 24 | export const LinkedOrdinancesSchema = baseLinkageSchema.extend({ |
| 25 | query: z.string().describe("๋ฒ๋ น๋ช (์: '๊ตญ๋ฏผ๊ฑด๊ฐ๋ณดํ๋ฒ')") |
| 26 | }) |
| 27 | export const LinkedOrdinanceArticlesSchema = baseLinkageSchema.extend({ |
| 28 | query: z.string().describe("๋ฒ๋ น๋ช (์: '๊ตญ๋ฏผ๊ฑด๊ฐ๋ณดํ๋ฒ')") |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 5 | import { formatToolError, noResultHint } from "../lib/errors.js" |
| 6 | |
| 7 | export const searchInterpretationsSchema = z.object({ |
| 8 | query: z.string().describe("Search keyword (e.g., '์๋์ฐจ', '๊ทผ๋ก๊ธฐ์ค๋ฒ')"), |
| 9 | display: z.number().min(1).max(100).default(20).describe("Results per page (default: 20, max: 100)"), |
| 10 | page: z.number().min(1).default(1).describe("Page number (default: 1)"), |
| 11 | sort: z.enum(["lasc", "ldes", "dasc", "ddes", "nasc", "ndes"]).optional() |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 6 | // Common schema for committee decision search (query optional) |
| 7 | const baseSearchSchemaOptionalQuery = { |
| 8 | query: z.string().optional().describe("๊ฒ์ ํค์๋"), |
| 9 | display: z.number().min(1).max(100).default(20).describe("ํ์ด์ง๋น ๊ฒฐ๊ณผ ๊ฐ์ (๊ธฐ๋ณธ๊ฐ: 20, ์ต๋: 100)"), |
| 10 | page: z.number().min(1).default(1).describe("ํ์ด์ง ๋ฒํธ (๊ธฐ๋ณธ๊ฐ: 1)"), |
| 11 | sort: z.enum(["lasc", "ldes", "dasc", "ddes"]).optional() |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 67 | // 2. ๋ฒ๋ น์ฉ์ด ์์ธ ์กฐํ (lstrm ๋ณธ๋ฌธ) |
| 68 | export const getLegalTermDetailSchema = z.object({ |
| 69 | query: z.string().describe("์กฐํํ ๋ฒ๋ น์ฉ์ด๋ช "), |
| 70 | apiKey: z.string().optional().describe("๋ฒ์ ์ฒ Open API ์ธ์ฆํค(OC). ์ฌ์ฉ์๊ฐ ์ ๊ณตํ ๊ฒฝ์ฐ ์ ๋ฌ"), |
| 71 | }); |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 90 | export const searchNlrcDecisionsSchema = z.object({ |
| 91 | ...baseSearchSchemaOptionalQuery, |
| 92 | query: z.string().optional().describe("๊ฒ์ ํค์๋ (์: '๋ถ๋นํด๊ณ ', '๋ ธ๋์์', '์กฐ์ ')"), |
| 93 | }); |
| 94 | |
| 95 | export type SearchNlrcDecisionsInput = z.infer<typeof searchNlrcDecisionsSchema>; |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 391 | // ======================================== |
| 392 | |
| 393 | export const chainOrdinanceCompareSchema = z.object({ |
| 394 | query: z.string().describe("์กฐ๋ก ๊ด๋ จ ํค์๋ (์: '์ฃผ๋ฏผ์์นํ', '๊ฐ๋ฐํ์ ํ๊ฐ ๊ธฐ์ค')"), |
| 395 | parentLaw: z.string().optional().describe("์์ ๋ฒ๋ น๋ช (์: '์ง๋ฐฉ์์น๋ฒ'). ๋ฏธ์ง์ ์ ์๋ ๊ฒ์."), |
| 396 | scenario: z.enum(["compliance"]).optional() |
| 397 | .describe("ํ์ฅ ์๋๋ฆฌ์ค. compliance=์กฐ๋ก ์์๋ฒ ์ ํฉ์ฑ ๊ฒ์ฆ (ํ์ฌยทํ์ฌ ์๋ฒ ํ๊ฒฐ + ์์๋ฒ ๊ทผ๊ฑฐ ๋ถ์). ๋ฏธ์ง์ ์ ์ฟผ๋ฆฌ์์ ์๋ ๊ฐ์ง."), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 10 | // search_admin_rule ์คํค๋ง |
| 11 | export const SearchAdminRuleSchema = z.object({ |
| 12 | query: z.string().describe("๊ฒ์ํ ํ์ ๊ท์น๋ช "), |
| 13 | knd: z.string().optional().describe("ํ์ ๊ท์น ์ข ๋ฅ (1=ํ๋ น, 2=์๊ท, 3=๊ณ ์, 4=๊ณต๊ณ , 5=์ผ๋ฐ)"), |
| 14 | display: z.number().optional().default(20).describe("์ต๋ ๊ฒฐ๊ณผ ๊ฐ์"), |
| 15 | apiKey: z.string().optional().describe("๋ฒ์ ์ฒ Open API ์ธ์ฆํค(OC). ์ฌ์ฉ์๊ฐ ์ ๊ณตํ ๊ฒฝ์ฐ ์ ๋ฌ") |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 210 | // ======================================== |
| 211 | |
| 212 | export const chainActionBasisSchema = z.object({ |
| 213 | query: z.string().describe("์ฒ๋ถ ์ ํ + ํค์๋ (์: '๊ฑด์ถํ๊ฐ ๊ฑฐ๋ถ ๊ทผ๊ฑฐ', '๋ณด์กฐ๊ธ ํ์')"), |
| 214 | scenario: z.enum(["penalty"]).optional() |
| 215 | .describe("ํ์ฅ ์๋๋ฆฌ์ค. penalty=์ฒ๋ถยท๋ฒ์น ๊ธฐ์ค ์ข ํฉ (๋ณํ ์ฒ๋ถ๊ธฐ์คํ + ๊ฐ๊ฒฝ ํ๋ก + ๊ฐ์ ์ด๋ ฅ). ๋ฏธ์ง์ ์ ์ฟผ๋ฆฌ์์ ์๋ ๊ฐ์ง."), |
| 216 | apiKey: z.string().optional(), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 11 | } from "../lib/decision-compact.js" |
| 12 | |
| 13 | export const searchPrecedentsSchema = z.object({ |
| 14 | query: z.string().optional().describe("๊ฒ์ ํค์๋ (์: '์๋์ฐจ', '๋ด๋ณด๊ถ')"), |
| 15 | court: z.string().optional().describe("๋ฒ์๋ช ํํฐ (์: '๋๋ฒ์', '์์ธ๊ณ ๋ฑ๋ฒ์')"), |
| 16 | caseNumber: z.string().optional().describe("์ฌ๊ฑด๋ฒํธ (์: '2009๋ํฉ133')"), |
| 17 | display: z.number().min(1).max(100).default(20).describe("๊ฒฐ๊ณผ ์ (๊ธฐ๋ณธ:20, ์ต๋:100)"), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 148 | // ======================================== |
| 149 | |
| 150 | export const chainLawSystemSchema = z.object({ |
| 151 | query: z.string().describe("๋ฒ๋ น๋ช ๋๋ ํค์๋ (์: '๊ด์ธ๋ฒ', '๊ฑด์ถ๋ฒ ํ๊ฐ')"), |
| 152 | articles: z.array(z.string()).optional().describe("์กฐํํ ์กฐ๋ฌธ ๋ฒํธ (์: ['์ 38์กฐ', '์ 39์กฐ'])"), |
| 153 | scenario: z.enum(["delegation", "impact"]).optional() |
| 154 | .describe("ํ์ฅ ์๋๋ฆฌ์ค. delegation=์์์ ๋ฒ ๋ฏธ์ดํ ๊ฐ์, impact=๊ฐ์ ์ํฅ๋ ๋ถ์. ๋ฏธ์ง์ ์ ์ฟผ๋ฆฌ์์ ์๋ ๊ฐ์ง."), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 12 | import { searchOrdinance } from "./ordinance-search.js" |
| 13 | |
| 14 | export const SearchAllSchema = z.object({ |
| 15 | query: z.string().describe("๊ฒ์ํ ํค์๋"), |
| 16 | display: z.number().min(1).max(50).default(10).describe("๊ฐ ์ ํ๋ณ ์ต๋ ๊ฒฐ๊ณผ ๊ฐ์ (๊ธฐ๋ณธ๊ฐ: 10)"), |
| 17 | apiKey: z.string().optional().describe("๋ฒ์ ์ฒ Open API ์ธ์ฆํค(OC). ์ฌ์ฉ์๊ฐ ์ ๊ณตํ ๊ฒฝ์ฐ ์ ๋ฌ") |
| 18 | }) |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 12 | // Constitutional Court decision search tool - Search for Constitutional Court rulings |
| 13 | export const searchConstitutionalDecisionsSchema = z.object({ |
| 14 | query: z.string().optional().describe("๊ฒ์ ํค์๋ (์: '์ํ', '๊ธฐ๋ณธ๊ถ', '์ฌ์ฐ๊ถ')"), |
| 15 | caseNumber: z.string().optional().describe("์ฌ๊ฑด๋ฒํธ (์: '2020ํ๋ฐ123')"), |
| 16 | display: z.number().min(1).max(100).default(20).describe("ํ์ด์ง๋น ๊ฒฐ๊ณผ ๊ฐ์ (๊ธฐ๋ณธ๊ฐ: 20, ์ต๋: 100)"), |
| 17 | page: z.number().min(1).default(1).describe("ํ์ด์ง ๋ฒํธ (๊ธฐ๋ณธ๊ฐ: 1)"), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 18 | - uses: actions/checkout@v4 |
| 19 | |
| 20 | - name: Use Node.js ${{ matrix.node-version }} |
| 21 | uses: actions/setup-node@v4 |
| 22 | with: |
| 23 | node-version: ${{ matrix.node-version }} |
| 24 | cache: npm |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 15 | node-version: [20] |
| 16 | |
| 17 | steps: |
| 18 | - uses: actions/checkout@v4 |
| 19 | |
| 20 | - name: Use Node.js ${{ matrix.node-version }} |
| 21 | uses: actions/setup-node@v4 |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc