Missing output encoding in `delete_json_doc`: `id` is echoed raw in the confirmation message
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 70/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
Research direction
The relevant code is the delete_json_doc case in src/index.ts, around lines 120-132. Read how id is taken from request.params.arguments and why the !id guard fails after String(...). Then check the load_json_doc and query_json_docs cases, which the issue says follow the same pattern. Done means a missing or malformed id is rejected before db.del, and the confirmation text encodes the ID instead of echoing it raw.
Written by the indexing model from the issue text.
Description
Tool: delete_json_doc · Tested commit: 605dbb7
Weakness: CWE-79 Cross-site Scripting / unescaped output
Summary
delete_json_doc deletes a document from the Fireproof json_docs database and replies Deleted document with ID: <id>, with the caller's id inserted verbatim. The ID is not validated or escaped, so markup or control characters in it come back unchanged. This only matters if a client renders tool output as HTML or Markdown, but the fix is small.
Details
src/index.ts:120-132:
case "delete_json_doc": {
const id = String(request.params.arguments?.id);
if (!id) {
throw new Error("ID is required");
}
await db.del(id);
return {
content: [{
type: "text",
text: `Deleted document with ID: ${id}`
}]
};
}
There is no check on the ID's format and no encoding of the echoed value. Two related details: String(undefined) is the string "undefined", so the !id guard never fires when id is missing; and the reply says "Deleted" whether or not a document with that ID existed.
Impact
The id argument is chosen by the model and can be steered by prompt injection, and the echoed text goes back to the client. In clients that show tool results as plain text nothing happens. A client or UI that renders tool output as HTML or Markdown without escaping would render the caller's markup. Severity is low; this is a hardening issue in a demo server.
Suggested fix
Validate the ID before use (for example typeof id === "string" && /^[A-Za-z0-9_-]{1,128}$/.test(id), matching the IDs Fireproof generates), fix the missing-argument check by testing the raw argument before String(...), and return the ID JSON-encoded, for example Deleted document with ID: ${JSON.stringify(id)}. The same pattern applies to load_json_doc and query_json_docs.
- Dominant language
- JavaScript
- Stars
- 31
- Forks
- 10
- PR merge metrics
- No merged PRs in 30d
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from fireproof-storage/mcp-database-server
-
problem with cloud buildMay be free again @necrodome claimed this 664 days ago, and no pull request is open. Open
fireproof-storage/mcp-database-server#1 · 8 comments · 1 assignee ·
All issues in fireproof-storage/mcp-database-server
Similar issues
-
area:install bug needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
yetone/magpie#2406 · 1 comment ·
Maintainers usually reply within 1 day
-
[BUG]: Prompt compressor crashes with TypeError when a past chat has a non-string response.textPossibly taken @ManojDevarajulu claimed this today. Openpossible bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Mintplex-Labs/anything-llm#6737 ·
Maintainers usually reply within 1 day
-
check:passed feeds:add
Difficulty 2/5 Under an hour Newbie friendliness 62/100
-
Remove the dead tree 'loadfail' handler in browser.js, which calls a non-existent tree.isSelected()OpenHousekeeping
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
pgadmin-org/pgadmin4#10601 ·
Maintainers usually reply within 1 day