fix(mcp): reject control characters in FinDrive filenames - #561
fix(mcp): reject control characters in FinDrive filenames#561Deez-Automations wants to merge 2 commits into
Conversation
…rity-Project#360) upload_file passed filename straight through to storage and into a log line with zero validation. A filename containing a newline gets stored verbatim and, more importantly, injects a fake log line into the application log -- corrupting the audit trail and deceiving anyone monitoring logs for suspicious activity. Rejects \n, \r, \t, and \x00 in filenames before they reach storage or logging. Ordinary filenames are unaffected. Fixes GenAI-Security-Project#360
There was a problem hiding this comment.
Pull request overview
This PR addresses FinDrive MCP upload_file filename log-injection risk by validating filenames before they reach persistence or logging, aligning with Issue #360’s acceptance criteria.
Changes:
- Added filename validation in
upload_fileto reject control characters (\n,\r,\t,\x00). - Added unit tests covering rejection of newline, carriage return, and null byte filenames, plus a regression test for valid filenames.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| finbot/mcp/servers/findrive/server.py | Adds a control-character guard in upload_file before DB write and logging. |
| tests/unit/mcp/test_findrive.py | Introduces unit/regression coverage for the filename validation behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| async def test_fd_fname_003_newline_in_filename_enables_log_injection( | ||
| self, db, session_context | ||
| ): |
There was a problem hiding this comment.
Kept the name as-is on purpose — it matches issue #360's own acceptance-criteria test name verbatim so it's traceable back to the ticket, added a docstring note explaining that so it's not confusing on its own.
| @pytest.mark.unit | ||
| @pytest.mark.asyncio | ||
| async def test_fd_fname_003c_null_byte_in_filename_rejected(self, db, session_context): |
There was a problem hiding this comment.
Already added — test_fd_fname_003d_tab_in_filename_rejected covers it.
Clarified the naming convention on the test that verbatim-matches issue GenAI-Security-Project#360's own acceptance-criteria test name (name describes the vulnerability being guarded against, not the assertion direction -- kept as-is for traceability rather than renamed, per Copilot's flag). Added the missing tab-character coverage: the fix already rejects \t, but the original test suite only exercised newline/CR/null byte.
|
Addressed the Copilot review feedback:
5/5 tests passing after both changes. |
Summary
Fixes #360.
upload_file(FinDrive MCP server) passedfilenamestraight through to storage and into a log line with no validation at all. A filename containing a newline is stored verbatim in the DB and, more importantly, injects a fake log line into the application log — corrupting the audit trail and potentially deceiving anyone monitoring logs for suspicious activity.Fix
Rejects
\n,\r,\t, and\x00in filenames before they reach storage or logging, matching the fix proposed in the issue. Ordinary filenames are unaffected.Test plan
tests/unit/mcp/test_findrive.py— reproduces the vulnerability first (confirmed failing against the unfixed code), then confirms the fixpytest tests/unit/mcp/test_findrive.py— 4/4 passing