Status (2026-10-13): Items 1 to 3 below were fixed shortly after this critique; items 4 and 5 remain open. The critique text and the audit table are left as written.
- Item 1 (page names): since 2026-05-03
WikiPageNameValidator(wikantik-util) is called bywrite_pages,update_page,rename_pageanddelete_pages. It rejects blank names, names over 128 characters, control characters including the null byte,/and\, and... It is a deny-list, not the strict CamelCase allow-list the critique proposed.- Item 2 (resource exhaustion): the same change hardened the frontmatter YAML loader (
FrontmatterParser): alias fan-out capped at 50, nesting depth 50, 1 MB per frontmatter block, duplicate keys refused. No overall request-size limit onwrite_pagesorupdate_pagecontent was found in the MCP tools.- Item 3 (stale hash): since 2026-05-03 a
hash mismatchfromupdate_pagecarriescurrentHash,currentVersionandlatestContent, so the agent can rebase without another read.- Item 4 (broken-link suggestions):
get_broken_linksstill returns only the referenced and referencing pages, with no similarity-based fix suggestions.- Item 5 (silos): the two endpoints remain separate. The admin server gained admin-bypass copies of
query_nodesandsearch_knowledgefor curators, but there is no merged tool. See MCP Integration for the current surface.
This report outlines an engineering and security critique of the wikantik-admin and wikantik-knowledge MCP servers, derived from a session involving large-scale refactoring and aggressive robustness testing ("face-punching").
Observation: The server allowed renaming a page to ../../../../etc/passwd. While it performed a "normalization" (resulting in ........EtcPasswd), it did not block the path traversal attempt outright.
Critique: The normalization logic appears to be a naive replacement of forbidden characters rather than a strict allow-list for CamelCase names. Furthermore, the server accepted a 5,000-character page name and a name containing a null byte (\u0000).
Recommendation:
^[A-Z][a-zA-Z0-9]+$).Observation: The server successfully processed a 5,000-character page name and a complex YAML structure with recursive anchors (YAML Bomb). Critique: While the server didn't crash, the lack of resource limits on string lengths and object depth makes it vulnerable to memory exhaustion attacks. Recommendation:
write_pages or update_page request (e.g., 2MB).metadata and content blocks.Observation: A rename_page call with updateLinks=true mutates other pages, changing their hashes.
Critique: If an agent attempts an edit based on a stale hash, the server returns a generic "hash mismatch" error, forcing an extra round-trip to re-read the content.
Recommendation: Return the latestContent and newVersion directly in the 409-equivalent error response to allow the agent to rebase immediately.
Observation: Identifying high-leverage broken links is turn-intensive.
Critique: The Admin server knows a link is broken but lacks "semantic awareness" of why.
Recommendation: Integrate get_broken_links with the Knowledge server's embedding space to provide "Fix Suggestions" (e.g., "Page SystemsThinking is missing, but SystemsTheory exists with 92% similarity").
Observation: Conceptual split between Admin and Knowledge servers leads to redundant context gathering. Critique: An agent often needs "is it a page?" (Admin) and "what is it about?" (Knowledge) simultaneously. Recommendation: Consolidate into a single "Agentic API" surface where a single tool call can return both metadata and semantic context.
| Vector | Input | Result | Status |
|---|---|---|---|
| Path Traversal | ../../etc/passwd | Sanitized to ........EtcPasswd | FAIL (Should block) |
| SQL Injection | ' OR 1=1 -- | Handled gracefully (no matches) | PASS |
| Shell Injection | test; ls -la | Handled gracefully (no matches) | PASS |
| Billion Laughs | YAML anchors/aliases | Processed and re-emitted | WARN (Potential DoS) |
| Buffer Overflow | 5,000 char name | Created successfully | FAIL (Should limit length) |
| Null Byte | Test\u0000Page | Created successfully | FAIL (Should block) |
| System Protect | delete_pages(["Main"]) | Refused | PASS |
See Also:
Cluster Hub: Wikantik Platform Development Hub: Architecture, MCP Protocols, and Agent Briefings (wikantik-development)