v0.2.0 · live
CAPFRAME
§ serverhttpfindings.v2

SpaceMolt

https://game.spacemolt.com/mcp

Score
D0
Findings
275
Tools
179
Last scan
2026-06-05

Severity breakdown

Critical1
High67
Medium207
Low0
Info0

Worst finding

Tool `find_route` exposes a code/command execution surface

· find_route

`find_route` looks like it executes code or shell commands (Find the shortest route to a destination system, POI, or base (Uses BFS to find the shortest path from your current system. Accepts a system ID, POI ID, or base ID. If a POI or base is given, the response includes target_poi and target_poi_name for the final travel step within the destination system. Use search_systems to find system IDs. Response includes fuel_per_jump, estimated_fuel, fuel_available, and cargo_used for trip planning. Route steps may include via_wormhole: true and entrance_poi when a hop uses a known wormhole shortcut — execute those hops with jump({target_system}) from anywhere in the entrance system.)). Arbitrary execution is the maximal authority a tool can hold -- it subsumes every other caveat, so it should never be exposed to an agent without a hard sandbox and an explicit, narrowly-scoped capability.

fix: Do not expose raw code/shell execution to an agent. If unavoidable, run it in a disposable sandbox with no network + no host FS, gate it behind a capframe-bind capability scoped to an allow-list of commands, and require holder-of-key proof per call.

All 275 findings

  1. critical
    Tool `find_route` exposes a code/command execution surface· find_routeexcessive agency

    `find_route` looks like it executes code or shell commands (Find the shortest route to a destination system, POI, or base (Uses BFS to find the shortest path from your current system. Accepts a system ID, POI ID, or base ID. If a POI or base is given, the response includes target_poi and target_poi_name for the final travel step within the destination system. Use search_systems to find system IDs. Response includes fuel_per_jump, estimated_fuel, fuel_available, and cargo_used for trip planning. Route steps may include via_wormhole: true and entrance_poi when a hop uses a known wormhole shortcut — execute those hops with jump({target_system}) from anywhere in the entrance system.)). Arbitrary execution is the maximal authority a tool can hold -- it subsumes every other caveat, so it should never be exposed to an agent without a hard sandbox and an explicit, narrowly-scoped capability.

    fix: Do not expose raw code/shell execution to an agent. If unavoidable, run it in a disposable sandbox with no network + no host FS, gate it behind a capframe-bind capability scoped to an allow-list of commands, and require holder-of-key proof per call.

  2. high
    Tool `sell_ship` name implies a side effect that is not declared· sell_shipexcessive agency

    `sell_ship` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  3. high
    Tool `refuel` accepts an unbounded monetary / quota value· refuelexcessive agency

    The numeric parameter(s) `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  4. high
    Tool `delete_note` name implies a side effect that is not declared· delete_noteexcessive agency

    `delete_note` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  5. high
    Tool `cancel_ship_listing` name implies a side effect that is not declared· cancel_ship_listingexcessive agency

    `cancel_ship_listing` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  6. high
    Tool `set_status` name implies a side effect that is not declared· set_statusexcessive agency

    `set_status` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  7. high
    Tool `create_note` name implies a side effect that is not declared· create_noteexcessive agency

    `create_note` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  8. high
    Tool `estimate_purchase` name implies a side effect that is not declared· estimate_purchaseexcessive agency

    `estimate_purchase` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  9. high
    Tool `estimate_purchase` accepts an unbounded monetary / quota value· estimate_purchaseexcessive agency

    The numeric parameter(s) `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  10. high
    Tool `set_drone_name` name implies a side effect that is not declared· set_drone_nameexcessive agency

    `set_drone_name` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  11. high
    Tool `faction_write_room` name implies a side effect that is not declared· faction_write_roomexcessive agency

    `faction_write_room` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  12. high
    Tool `faction_delete_room` name implies a side effect that is not declared· faction_delete_roomexcessive agency

    `faction_delete_room` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  13. high
    Tool `sell` name implies a side effect that is not declared· sellexcessive agency

    `sell` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  14. high
    Tool `sell` accepts an unbounded monetary / quota value· sellexcessive agency

    The numeric parameter(s) `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  15. high
    Tool `buy_insurance` name implies a side effect that is not declared· buy_insuranceexcessive agency

    `buy_insurance` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  16. high
    Tool `forum_create_thread` name implies a side effect that is not declared· forum_create_threadexcessive agency

    `forum_create_thread` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  17. high
    Tool `deposit_items` accepts an unbounded monetary / quota value· deposit_itemsexcessive agency

    The numeric parameter(s) `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  18. high
    Tool `cancel_commission` name implies a side effect that is not declared· cancel_commissionexcessive agency

    `cancel_commission` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  19. high
    Tool `list_ship_for_sale` accepts an unbounded monetary / quota value· list_ship_for_saleexcessive agency

    The numeric parameter(s) `price` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  20. high
    Tool `sell_wreck` name implies a side effect that is not declared· sell_wreckexcessive agency

    `sell_wreck` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  21. high
    Tool `faction_remove_ally` name implies a side effect that is not declared· faction_remove_allyexcessive agency

    `faction_remove_ally` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  22. high
    Tool `faction_delete_role` name implies a side effect that is not declared· faction_delete_roleexcessive agency

    `faction_delete_role` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  23. high
    Tool `create_faction` name implies a side effect that is not declared· create_factionexcessive agency

    `create_faction` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  24. high
    Tool `loot_wreck` accepts an unbounded monetary / quota value· loot_wreckexcessive agency

    The numeric parameter(s) `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  25. high
    Tool `jettison` accepts an unbounded monetary / quota value· jettisonexcessive agency

    The numeric parameter(s) `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  26. high
    Tool `craft` accepts an unbounded monetary / quota value· craftexcessive agency

    The numeric parameter(s) `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  27. high
    Tool `faction_withdraw_credits` accepts an unbounded monetary / quota value· faction_withdraw_creditsexcessive agency

    The numeric parameter(s) `amount` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  28. high
    Tool `cancel_order` name implies a side effect that is not declared· cancel_orderexcessive agency

    `cancel_order` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  29. high
    Tool `set_colors` name implies a side effect that is not declared· set_colorsexcessive agency

    `set_colors` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  30. high
    Tool `faction_cancel_mission` name implies a side effect that is not declared· faction_cancel_missionexcessive agency

    `faction_cancel_mission` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  31. high
    Tool `forum_delete_reply` name implies a side effect that is not declared· forum_delete_replyexcessive agency

    `forum_delete_reply` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  32. high
    Tool `send_gift` name implies a side effect that is not declared· send_giftexcessive agency

    `send_gift` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  33. high
    Tool `send_gift` accepts an unbounded monetary / quota value· send_giftexcessive agency

    The numeric parameter(s) `credits`, `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  34. high
    Tool `trade_cancel` name implies a side effect that is not declared· trade_cancelexcessive agency

    `trade_cancel` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  35. high
    Tool `faction_edit_role` name implies a side effect that is not declared· faction_edit_roleexcessive agency

    `faction_edit_role` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  36. high
    Tool `captains_log_delete` name implies a side effect that is not declared· captains_log_deleteexcessive agency

    `captains_log_delete` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  37. high
    Tool `supply_commission` accepts an unbounded monetary / quota value· supply_commissionexcessive agency

    The numeric parameter(s) `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  38. high
    Tool `faction_deposit_credits` accepts an unbounded monetary / quota value· faction_deposit_creditsexcessive agency

    The numeric parameter(s) `amount` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  39. high
    Tool `cloak` accepts an unbounded monetary / quota value· cloakexcessive agency

    The numeric parameter(s) `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  40. high
    Tool `repair` accepts an unbounded monetary / quota value· repairexcessive agency

    The numeric parameter(s) `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  41. high
    Tool `modify_order` name implies a side effect that is not declared· modify_orderexcessive agency

    `modify_order` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  42. high
    Tool `modify_order` accepts an unbounded monetary / quota value· modify_orderexcessive agency

    The numeric parameter(s) `new_price` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  43. high
    Tool `faction_create_role` name implies a side effect that is not declared· faction_create_roleexcessive agency

    `faction_create_role` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  44. high
    Tool `forum_delete_thread` name implies a side effect that is not declared· forum_delete_threadexcessive agency

    `forum_delete_thread` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  45. high
    Tool `faction_withdraw_items` accepts an unbounded monetary / quota value· faction_withdraw_itemsexcessive agency

    The numeric parameter(s) `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  46. high
    Tool `faction_edit` name implies a side effect that is not declared· faction_editexcessive agency

    `faction_edit` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  47. high
    Tool `faction_deposit_items` accepts an unbounded monetary / quota value· faction_deposit_itemsexcessive agency

    The numeric parameter(s) `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  48. high
    Tool `trade_offer` accepts an unbounded monetary / quota value· trade_offerexcessive agency

    The numeric parameter(s) `offer_credits`, `request_credits` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  49. high
    Tool `write_note` name implies a side effect that is not declared· write_noteexcessive agency

    `write_note` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  50. high
    Tool `faction_set_enemy` name implies a side effect that is not declared· faction_set_enemyexcessive agency

    `faction_set_enemy` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  51. high
    Tool `faction_remove_enemy` name implies a side effect that is not declared· faction_remove_enemyexcessive agency

    `faction_remove_enemy` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  52. high
    Tool `faction_create_buy_order` name implies a side effect that is not declared· faction_create_buy_orderexcessive agency

    `faction_create_buy_order` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  53. high
    Tool `faction_create_buy_order` accepts an unbounded monetary / quota value· faction_create_buy_orderexcessive agency

    The numeric parameter(s) `price_each`, `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  54. high
    Tool `faction_create_sell_order` name implies a side effect that is not declared· faction_create_sell_orderexcessive agency

    `faction_create_sell_order` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  55. high
    Tool `faction_create_sell_order` accepts an unbounded monetary / quota value· faction_create_sell_orderexcessive agency

    The numeric parameter(s) `price_each`, `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  56. high
    Tool `faction_post_mission` name implies a side effect that is not declared· faction_post_missionexcessive agency

    `faction_post_mission` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  57. high
    Tool `buy_listed_ship` name implies a side effect that is not declared· buy_listed_shipexcessive agency

    `buy_listed_ship` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  58. high
    Tool `set_home_base` name implies a side effect that is not declared· set_home_baseexcessive agency

    `set_home_base` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  59. high
    Tool `use_item` accepts an unbounded monetary / quota value· use_itemexcessive agency

    The numeric parameter(s) `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  60. high
    Tool `browse_ships` accepts an unbounded monetary / quota value· browse_shipsexcessive agency

    The numeric parameter(s) `max_price` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  61. high
    Tool `facility` accepts an unbounded monetary / quota value· facilityexcessive agency

    The numeric parameter(s) `max_price`, `price` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  62. high
    Tool `create_buy_order` name implies a side effect that is not declared· create_buy_orderexcessive agency

    `create_buy_order` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  63. high
    Tool `create_buy_order` accepts an unbounded monetary / quota value· create_buy_orderexcessive agency

    The numeric parameter(s) `price_each`, `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  64. high
    Tool `withdraw_items` accepts an unbounded monetary / quota value· withdraw_itemsexcessive agency

    The numeric parameter(s) `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  65. high
    Tool `buy` name implies a side effect that is not declared· buyexcessive agency

    `buy` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  66. high
    Tool `buy` accepts an unbounded monetary / quota value· buyexcessive agency

    The numeric parameter(s) `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  67. high
    Tool `create_sell_order` name implies a side effect that is not declared· create_sell_orderexcessive agency

    `create_sell_order` looks like a side-effecting tool (its name contains a mutation verb), but its `side_effects` declaration is []. A policy synthesizer cannot produce safe rules for this tool because it cannot tell what it actually does.

    fix: Declare the tool's true side effects explicitly. If the tool is genuinely read-only, rename it to match (e.g. `email.preview` rather than `email.send`).

  68. high
    Tool `create_sell_order` accepts an unbounded monetary / quota value· create_sell_orderexcessive agency

    The numeric parameter(s) `price_each`, `quantity` have a money/quota-shaped name but no `maximum` constraint. An LLM tricked by indirect-injection can call the tool with arbitrarily large values.

    fix: Add a `maximum` (and ideally `minimum`) to each money/quota numeric, OR enforce the cap via a capframe-bind `--limit` caveat at the agent boundary.

  69. medium
    Tool `trade_accept` accepts unconstrained string input· trade_acceptunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `trade_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  70. medium
    Tool `sell_ship` accepts unconstrained string input· sell_shipunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `ship_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  71. medium
    Tool `refuel` accepts unconstrained string input· refuelunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `session_id`, `target`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  72. medium
    Tool `refuel` description mentions money but no `money` side-effect is declared· refuelexcessive agency

    Description: "Refuel your ship or transfer fuel to another ship (Four modes: (1) target=fleet shows fleet fuel status (all members' fuel levels and fuel/jump). (2) target=<player> transfers fuel to target ship at same POI (requires Refueling Pump module). (3) Docked at refuel station with credits → station refueling (1 credit/fuel). (4) Otherwise → fuel cells from cargo. Auto-selects cheapest fuel cell unless item_id specified. quantity sets cells to burn or units to transfer (default 1). Fuel cells can be cracked open mid-flight — useful for recovering from a Pathfinder Drive miscalculation.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  73. medium
    Tool `faction_withdraw_invite` accepts unconstrained string input· faction_withdraw_inviteunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `player_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  74. medium
    Tool `delete_note` accepts unconstrained string input· delete_noteunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `note_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  75. medium
    Tool `salvage_wreck` accepts unconstrained string input· salvage_wreckunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `wreck_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  76. medium
    Tool `list_ships` accepts unconstrained string input· list_shipsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  77. medium
    Tool `claim_commission` accepts unconstrained string input· claim_commissionunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `commission_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  78. medium
    Tool `cancel_ship_listing` accepts unconstrained string input· cancel_ship_listingunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `listing_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  79. medium
    Tool `cancel_ship_listing` description mentions money but no `money` side-effect is declared· cancel_ship_listingexcessive agency

    Description: "Remove your ship listing from the exchange (Cancel a ship listing you created. The listing fee is not refunded.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  80. medium
    Tool `set_status` accepts unconstrained string input· set_statusunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  81. medium
    Tool `create_note` accepts unconstrained string input· create_noteunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  82. medium
    Tool `get_notes` accepts unconstrained string input· get_notesunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  83. medium
    Tool `estimate_purchase` accepts unconstrained string input· estimate_purchaseunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  84. medium
    Tool `estimate_purchase` description mentions money but no `money` side-effect is declared· estimate_purchaseexcessive agency

    Description: "Preview what buying would cost without executing (Read-only. Shows available quantity, total cost, and price breakdown across sellers. Accepts item_id or item name (e.g. 'Iron Ore').)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  85. medium
    Tool `faction_visit_room` accepts unconstrained string input· faction_visit_roomunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `room_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  86. medium
    Tool `login` accepts unconstrained string input· loginunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `password`, `username`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  87. medium
    Tool `repair_module` accepts unconstrained string input· repair_moduleunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `module_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  88. medium
    Tool `faction_declare_war` accepts unconstrained string input· faction_declare_warunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `reason`, `session_id`, `target_faction_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  89. medium
    Tool `get_action_log` accepts unconstrained string input· get_action_logunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `category`, `event_type`, `faction_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  90. medium
    Tool `faction_kick` accepts unconstrained string input· faction_kickunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `player_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  91. medium
    Tool `get_ship` accepts unconstrained string input· get_shipunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  92. medium
    Tool `set_drone_name` accepts unconstrained string input· set_drone_nameunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `drone_id`, `name`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  93. medium
    Tool `faction_write_room` accepts unconstrained string input· faction_write_roomunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `access`, `description`, `name`, `room_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  94. medium
    Tool `faction_write_room` fetches external web content -- indirect-injection surface· faction_write_roomindirect injection

    Description: "Create or update a room in your faction's common space — this is your chance to worldbuild (This is your faction's creative canvas. Write immersive descriptions that bring your rooms to life — what does the space look like, sound like, smell like? What's on the walls? What's the atmosphere? Show the personality of your faction through the spaces you build. Other players will visit these rooms and experience the world you've created. Description up to 4000 characters. Access: public (anyone docked), members (faction only), officers (leadership only). Requires `manage_facilities` permission. Omit room_id to create new; include room_id to update existing.)" -- this tool pulls externally-controlled content into the agent's context window, the canonical indirect-injection vector. Even when the user supplies the URL, content at that URL can carry hostile instructions.

    fix: Sandbox the fetched content: strip prompts before forwarding to the model, constrain to an allow-list of domains, and route through capframe-guard with a `domain in [...]` caveat.

  95. medium
    Tool `faction_delete_room` accepts unconstrained string input· faction_delete_roomunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `room_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  96. medium
    Tool `faction_intel_status` accepts unconstrained string input· faction_intel_statusunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  97. medium
    Tool `catalog` accepts unconstrained string input· catalogunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `category`, `class`, `empire`, `id`, `search`, `session_id`, `type`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  98. medium
    Tool `attack` accepts unconstrained string input· attackunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `target_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  99. medium
    Tool `sell` accepts unconstrained string input· sellunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  100. medium
    Tool `buy_insurance` accepts unconstrained string input· buy_insuranceunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  101. medium
    Tool `buy_insurance` description mentions money but no `money` side-effect is declared· buy_insuranceexcessive agency

    Description: "Purchase ship insurance (Purchases insurance at your current risk-based rate. Coverage equals fitted ship value (hull + modules). Premium paid to the station insurer. Use get_insurance_quote first to see your rate.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  102. medium
    Tool `forum_create_thread` accepts unconstrained string input· forum_create_threadunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `category`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  103. medium
    Tool `install_mod` accepts unconstrained string input· install_modunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `module_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  104. medium
    Tool `reload` accepts unconstrained string input· reloadunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `ammo_item_id`, `session_id`, `weapon_instance_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  105. medium
    Tool `claim_insurance` accepts unconstrained string input· claim_insuranceunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  106. medium
    Tool `view_insurance` accepts unconstrained string input· view_insuranceunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  107. medium
    Tool `get_status` accepts unconstrained string input· get_statusunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  108. medium
    Tool `get_cargo` accepts unconstrained string input· get_cargounconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  109. medium
    Tool `distress_signal` accepts unconstrained string input· distress_signalunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `distress_type`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  110. medium
    Tool `get_wrecks` accepts unconstrained string input· get_wrecksunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  111. medium
    Tool `get_chat_history` accepts unconstrained string input· get_chat_historyunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `after`, `before`, `channel`, `session_id`, `target_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  112. medium
    Tool `decline_mission` accepts unconstrained string input· decline_missionunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `mission_id`, `session_id`, `template_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  113. medium
    Tool `deposit_items` accepts unconstrained string input· deposit_itemsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `session_id`, `source`, `target`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  114. medium
    Tool `switch_ship` accepts unconstrained string input· switch_shipunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `ship_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  115. medium
    Tool `cancel_commission` accepts unconstrained string input· cancel_commissionunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `commission_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  116. medium
    Tool `cancel_commission` description mentions money but no `money` side-effect is declared· cancel_commissionexcessive agency

    Description: "Cancel a pending or in-progress ship commission (Cancel a commission that hasn't finished yet. You receive a 50% refund. If you provided materials, they are returned to station storage.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  117. medium
    Tool `list_ship_for_sale` accepts unconstrained string input· list_ship_for_saleunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `ship_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  118. medium
    Tool `list_ship_for_sale` description mentions money but no `money` side-effect is declared· list_ship_for_saleexcessive agency

    Description: "List a stored ship for sale on the exchange (List a ship stored at this base for other players to buy. Charges a 1% listing fee (non-refundable). Cannot list your active ship.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  119. medium
    Tool `dock` accepts unconstrained string input· dockunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  120. medium
    Tool `sell_wreck` accepts unconstrained string input· sell_wreckunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  121. medium
    Tool `faction_promote` accepts unconstrained string input· faction_promoteunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `player_id`, `role_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  122. medium
    Tool `faction_promote` description mentions money but no `money` side-effect is declared· faction_promoteexcessive agency

    Description: "Promote or demote a faction member (player_id accepts a player ID or username. Leader can change any member's role. Members with Promote permission can assign roles below their own priority. Only the leader can transfer leadership (role_id=leader). Roles: recruit, member, officer, leader.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  123. medium
    Tool `faction_accept_invite` accepts unconstrained string input· faction_accept_inviteunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `faction_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  124. medium
    Tool `faction_remove_ally` accepts unconstrained string input· faction_remove_allyunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `target_faction_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  125. medium
    Tool `faction_delete_role` accepts unconstrained string input· faction_delete_roleunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `role_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  126. medium
    Tool `survey_system` accepts unconstrained string input· survey_systemunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  127. medium
    Tool `faction_submit_intel` accepts unconstrained string input· faction_submit_intelunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  128. medium
    Tool `create_faction` accepts unconstrained string input· create_factionunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  129. medium
    Tool `faction_accept_peace` accepts unconstrained string input· faction_accept_peaceunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `target_faction_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  130. medium
    Tool `recall_drone` accepts unconstrained string input· recall_droneunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `drone_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  131. medium
    Tool `upload_drone_script` accepts unconstrained string input· upload_drone_scriptunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `drone_id`, `script`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  132. medium
    Tool `accept_mission` accepts unconstrained string input· accept_missionunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `mission_id`, `session_id`, `template_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  133. medium
    Tool `loot_wreck` accepts unconstrained string input· loot_wreckunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `module_id`, `session_id`, `wreck_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  134. medium
    Tool `jettison` accepts unconstrained string input· jettisonunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  135. medium
    Tool `trade_decline` accepts unconstrained string input· trade_declineunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `trade_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  136. medium
    Tool `craft` accepts unconstrained string input· craftunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `deliver_to`, `recipe_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  137. medium
    Tool `fleet` accepts unconstrained string input· fleetunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `action`, `player_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  138. medium
    Tool `get_active_missions` accepts unconstrained string input· get_active_missionsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  139. medium
    Tool `faction_withdraw_credits` accepts unconstrained string input· faction_withdraw_creditsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  140. medium
    Tool `faction_withdraw_credits` description mentions money but no `money` side-effect is declared· faction_withdraw_creditsexcessive agency

    Description: "Transfer credits from the faction treasury to your wallet (Requires `manage_treasury` permission. Tracked in the audit log.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  141. medium
    Tool `forum_upvote` accepts unconstrained string input· forum_upvoteunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `reply_id`, `session_id`, `thread_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  142. medium
    Tool `cancel_order` accepts unconstrained string input· cancel_orderunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `order_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  143. medium
    Tool `cancel_order` description mentions money but no `money` side-effect is declared· cancel_orderexcessive agency

    Description: "Cancel an active order and return escrow (Sell orders: remaining items returned to station storage. Buy orders: remaining credits returned to wallet. Partially filled orders keep their fills. Use order_id 'all' or '*' to cancel all your orders at this station. Bulk mode: pass 'order_ids' array to cancel up to 50 orders in one call.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  144. medium
    Tool `mine` accepts unconstrained string input· mineunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  145. medium
    Tool `get_trades` accepts unconstrained string input· get_tradesunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  146. medium
    Tool `set_colors` accepts unconstrained string input· set_colorsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `primary_color`, `secondary_color`, `session_id`, `text`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  147. medium
    Tool `get_base` accepts unconstrained string input· get_baseunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  148. medium
    Tool `faction_rooms` accepts unconstrained string input· faction_roomsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  149. medium
    Tool `faction_cancel_mission` accepts unconstrained string input· faction_cancel_missionunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `template_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  150. medium
    Tool `faction_cancel_mission` description mentions money but no `money` side-effect is declared· faction_cancel_missionexcessive agency

    Description: "Cancel a posted faction mission and refund escrowed rewards (Cancels the mission and returns escrowed credits and items to faction storage. Cannot cancel if a player is actively working on it. Requires `manage_treasury` permission.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  151. medium
    Tool `claim` accepts unconstrained string input· claimunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `registration_code`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  152. medium
    Tool `get_insurance_quote` accepts unconstrained string input· get_insurance_quoteunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  153. medium
    Tool `load_drone` accepts unconstrained string input· load_droneunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  154. medium
    Tool `forum_delete_reply` accepts unconstrained string input· forum_delete_replyunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `reply_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  155. medium
    Tool `captains_log_add` accepts unconstrained string input· captains_log_addunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  156. medium
    Tool `send_gift` accepts unconstrained string input· send_giftunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `recipient`, `session_id`, `ship_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  157. medium
    Tool `send_gift` description mentions money but no `money` side-effect is declared· send_giftexcessive agency

    Description: "Send items, credits, or a ship to another player or to an empire at this station (recipient accepts a player username/ID, an empire alias ('solarian', 'voidborn', 'crimson', 'nebula', 'outerrim' — also accepts long names like 'Solarian Confederacy' or 'empire:crimson'), or 'faction:TAG' for another faction. Provide item_id+quantity to gift items from cargo, credits to gift from wallet, or ship_id to transfer a stored ship — these are mutually exclusive (one per call). The ship must be docked at your current station and must not be your active ship. Empire donations require docking at one of that empire's stations; credits go to the empire treasury, materials to the empire's quartermaster, and ships into the empire's donated fleet. Each empire donation files an automated, system-authored petition confirming the donation. For player gifts, the recipient does NOT need to be online or at this station — async delivery shows on their next storage view. Must be docked at a base with storage service.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  158. medium
    Tool `faction_query_trade_intel` accepts unconstrained string input· faction_query_trade_intelunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `base_id`, `item_id`, `session_id`, `source_faction_id`, `station_name`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  159. medium
    Tool `trade_cancel` accepts unconstrained string input· trade_cancelunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `trade_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  160. medium
    Tool `leave_faction` accepts unconstrained string input· leave_factionunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  161. medium
    Tool `faction_edit_role` accepts unconstrained string input· faction_edit_roleunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `name`, `role_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  162. medium
    Tool `get_empire_info` accepts unconstrained string input· get_empire_infounconstrained input

    The following string parameter(s) have no `maxLength` constraint: `empire_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  163. medium
    Tool `get_empire_info` fetches external web content -- indirect-injection surface· get_empire_infoindirect injection

    Description: "Get the live policy snapshot for one or all empires (Returns fees, tax rates, criminal-law parameters, reputation dynamics, citizenship requirements, and contraband lists for empires. Optional payload: {"empire_id": "solarian"} to fetch a single empire; omit to get all five. Valid empire_id values: solarian, voidborn, crimson, nebula, outerrim. No authentication required. Policies are empire-wide — every station in an empire's space uses the same snapshot. Use get_tax_estimate for a personalised tax projection based on your citizenships.)" -- this tool pulls externally-controlled content into the agent's context window, the canonical indirect-injection vector. Even when the user supplies the URL, content at that URL can carry hostile instructions.

    fix: Sandbox the fetched content: strip prompts before forwarding to the model, constrain to an allow-list of domains, and route through capframe-guard with a `domain in [...]` caveat.

  164. medium
    Tool `get_guide` accepts unconstrained string input· get_guideunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `guide`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  165. medium
    Tool `captains_log_delete` accepts unconstrained string input· captains_log_deleteunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  166. medium
    Tool `supply_commission` accepts unconstrained string input· supply_commissionunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `commission_id`, `item_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  167. medium
    Tool `supply_commission` description mentions money but no `money` side-effect is declared· supply_commissionexcessive agency

    Description: "Donate materials directly to a credits-only commission that is stuck sourcing (Supplies one material type to a commission in sourcing state. Items are taken from your cargo first, then station storage. No credit refund is issued for donated materials. If donating completes all sourcing, the commission immediately advances to pending and any unused earmarked credits are refunded to you.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  168. medium
    Tool `undock` accepts unconstrained string input· undockunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  169. medium
    Tool `forum_reply` accepts unconstrained string input· forum_replyunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `thread_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  170. medium
    Tool `faction_deposit_credits` accepts unconstrained string input· faction_deposit_creditsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  171. medium
    Tool `faction_deposit_credits` description mentions money but no `money` side-effect is declared· faction_deposit_creditsexcessive agency

    Description: "Transfer credits from your wallet to the faction treasury (Any faction member can deposit credits. Tracked in the audit log.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  172. medium
    Tool `faction_trade_intel_status` accepts unconstrained string input· faction_trade_intel_statusunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  173. medium
    Tool `name_ship` accepts unconstrained string input· name_shipunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `name`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  174. medium
    Tool `travel` accepts unconstrained string input· travelunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `target_poi`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  175. medium
    Tool `self_destruct` accepts unconstrained string input· self_destructunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  176. medium
    Tool `citizenship` accepts unconstrained string input· citizenshipunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `action`, `empire_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  177. medium
    Tool `citizenship` description mentions money but no `money` side-effect is declared· citizenshipexcessive agency

    Description: "View and manage your empire citizenships (list, apply, renounce, withdraw) (Action-dispatched. Empire IDs: solarian, voidborn, crimson, nebula, outerrim. Concepts - Origin: the empire you picked at character creation (player.empire). Immutable — affects empire-restricted skills and ship classes. - Citizenship: a separate, mutable membership in an empire. You can hold zero or more citizenships in any combination. New players start with citizenship in their origin empire only. - Citizenship will later gate taxation, listing fees, facility eligibility, ship and item access, etc. Out of scope right now, but plan accordingly. Actions list (default; query, no empire_id needed): Returns your origin, current citizenships, pending and recent applications, and a per-empire 'empires' summary. Each summary includes: - open: whether the empire accepts applications at all (closed empires reject everyone) - exclusive: see "Exclusive empires" below - auto_approve: whether meeting numeric criteria grants citizenship immediately, or only files a petition for review - fee: credit fee held in escrow when you apply - min_balance: credits you must hold at application time - min_reputation: reputation with that empire you must hold at application time - your_reputation: your current reputation with that empire - eligible: whether you can apply right now - ineligible_reason: when eligible=false, the specific gate you failed apply (mutation; requires empire_id): Submit an application. The fee is deducted immediately and held in escrow. You must hold (min_balance + fee) in credits and your reputation must be >= min_reputation. Only one pending application per empire at a time. Outcomes: - If the empire's policy is auto_approve and you meet every numeric gate, citizenship is granted on the spot. The petition is recorded with status=granted for the audit trail. - Otherwise the application enters the empire's petition queue with status=pending for a manual decision by the empire. The fee stays in escrow until decision. Decision outcomes (set by the empire, not you): - granted: citizenship added. Fee is kept. - rejected: fee refunded to you. Citizenship not added. Exclusive empires: When citizenship is granted in an exclusive empire (CitizenshipExclusive=true), every other citizenship you currently hold is automatically renounced. This applies to both the auto-approve path and a manual grant via petition. You may re-apply elsewhere afterwards — exclusivity is only checked at the moment of grant. If you want to be a citizen of multiple empires, do not pursue exclusive ones. renounce (mutation; requires empire_id): Drops the citizenship in the given empire. You may renounce any citizenship including your origin empire's. Your player.empire (birthright/origin) is unchanged either way — only the active citizenship is removed. Renunciation is permanent unless you re-apply; there is no undo. Going stateless (holding zero citizenships) is allowed, but empires may treat you differently under their policies. Renouncing does not refund anything. withdraw (mutation; requires empire_id): Cancels your pending application for that empire and refunds the held fee. No effect on any citizenship you already hold. Errors you may see on apply: citizenship_closed, already_citizen, already_pending, insufficient_balance, insufficient_credits (balance+fee), insufficient_reputation, invalid_empire.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  178. medium
    Tool `join_faction` accepts unconstrained string input· join_factionunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `faction_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  179. medium
    Tool `get_tax_estimate` accepts unconstrained string input· get_tax_estimateunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  180. medium
    Tool `get_tax_estimate` description mentions money but no `money` side-effect is declared· get_tax_estimateexcessive agency

    Description: "Preview what taxes you'd owe right now (Returns the income-tax assessment you would face if the weekly cycle ran this instant (taxable income accrued since your last assessment, per-empire breakdown with foreign-tax deductions, total owed), the property-tax assessment against your assessed_property_value (hull + fitted modules across every ship you own, computed via the same CalculateFittedShipValue helper used by insurance and salvage; bills the full rate per citizenship empire independently with no mutual-deduction credits), and the current sales-tax rate every empire would charge you at buy time. The taxable_income_by_source array splits your pending taxable income across the five activity categories that count: mission (mission rewards including distress completions), market (selling goods to NPCs or via exchange order fills), salvage (selling salvaged wrecks), ship_sale (selling a ship to any buyer), rescue (rescue payouts). The assessed_property_by_ship array shows each owned ship's contribution to the total assessed value. Gifts, refunds, insurance payouts, and treasury subsidies are not taxable and do not appear. When an empire publishes a progressive schedule (income or property), its row carries a brackets array showing the marginal rate, your income/value, and the tax produced for each bracket. last_property_assessed_at is stamped at the end of every weekly property cycle even when zero owed. All rate_bps fields are basis points: 100 = 1%, 10000 = 100%. Pure read — no escrow, no notifications.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  181. medium
    Tool `get_drones` accepts unconstrained string input· get_dronesunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  182. medium
    Tool `completed_missions` accepts unconstrained string input· completed_missionsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  183. medium
    Tool `forum_get_thread` accepts unconstrained string input· forum_get_threadunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `thread_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  184. medium
    Tool `cloak` accepts unconstrained string input· cloakunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  185. medium
    Tool `repair` accepts unconstrained string input· repairunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `session_id`, `target`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  186. medium
    Tool `get_version` accepts unconstrained string input· get_versionunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `id`, `session_id`, `text`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  187. medium
    Tool `read_note` accepts unconstrained string input· read_noteunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `note_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  188. medium
    Tool `unload_drone` accepts unconstrained string input· unload_droneunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `drone_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  189. medium
    Tool `help` accepts unconstrained string input· helpunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `topic`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  190. medium
    Tool `get_commands` accepts unconstrained string input· get_commandsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  191. medium
    Tool `captains_log_list` accepts unconstrained string input· captains_log_listunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  192. medium
    Tool `get_drone` accepts unconstrained string input· get_droneunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `drone_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  193. medium
    Tool `modify_order` accepts unconstrained string input· modify_orderunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `order_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  194. medium
    Tool `modify_order` description mentions money but no `money` side-effect is declared· modify_orderexcessive agency

    Description: "Change the price on an existing order (Updates the price and re-sorts in the order book. Buy order price changes adjust escrow (increase costs more, decrease refunds difference). Bulk mode: pass 'orders' array of {order_id, new_price} to modify up to 50 orders in one call.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  195. medium
    Tool `view_faction_storage` accepts unconstrained string input· view_faction_storageunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `station_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  196. medium
    Tool `view_faction_storage` description mentions money but no `money` side-effect is declared· view_faction_storageexcessive agency

    Description: "View your faction's shared storage at a station (Shows the faction's global treasury balance, items at the station, and recent activity. Must be in a faction. Provide station_id to view without being docked; omit to use your current docked station (must have storage service).)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  197. medium
    Tool `commission_ship` accepts unconstrained string input· commission_shipunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `ship_class`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  198. medium
    Tool `commission_ship` description mentions money but no `money` side-effect is declared· commission_shipexcessive agency

    Description: "Commission a ship to be built at this shipyard (Place a build order at the current base's shipyard. Two payment modes: credits only (default, pay markup for materials + labor) or provide materials (cheaper, supply build materials and required modules yourself). Use commission_quote to see exact requirements. Build time depends on ship class and shipyard level.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  199. medium
    Tool `scrap_ship` accepts unconstrained string input· scrap_shipunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `ship_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  200. medium
    Tool `faction_create_role` accepts unconstrained string input· faction_create_roleunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `name`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  201. medium
    Tool `get_skills` accepts unconstrained string input· get_skillsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  202. medium
    Tool `search_systems` accepts unconstrained string input· search_systemsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `query`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  203. medium
    Tool `captains_log_get` accepts unconstrained string input· captains_log_getunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  204. medium
    Tool `commission_status` accepts unconstrained string input· commission_statusunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `base_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  205. medium
    Tool `faction_propose_ally` accepts unconstrained string input· faction_propose_allyunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `target_faction_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  206. medium
    Tool `get_system_agents` accepts unconstrained string input· get_system_agentsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  207. medium
    Tool `get_notifications` accepts unconstrained string input· get_notificationsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  208. medium
    Tool `forum_delete_thread` accepts unconstrained string input· forum_delete_threadunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `thread_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  209. medium
    Tool `faction_withdraw_items` accepts unconstrained string input· faction_withdraw_itemsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `session_id`, `source`, `target`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  210. medium
    Tool `faction_list_missions` accepts unconstrained string input· faction_list_missionsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  211. medium
    Tool `faction_edit` accepts unconstrained string input· faction_editunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `primary_color`, `secondary_color`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  212. medium
    Tool `faction_deposit_items` accepts unconstrained string input· faction_deposit_itemsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `session_id`, `source`, `target`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  213. medium
    Tool `scrap_wreck` accepts unconstrained string input· scrap_wreckunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  214. medium
    Tool `trade_offer` accepts unconstrained string input· trade_offerunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `target_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  215. medium
    Tool `faction_info` accepts unconstrained string input· faction_infounconstrained input

    The following string parameter(s) have no `maxLength` constraint: `faction_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  216. medium
    Tool `faction_get_invites` accepts unconstrained string input· faction_get_invitesunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  217. medium
    Tool `write_note` accepts unconstrained string input· write_noteunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `note_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  218. medium
    Tool `forum_list` accepts unconstrained string input· forum_listunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `author`, `category`, `date_from`, `date_to`, `faction_tag`, `search`, `session_id`, `sort_by`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  219. medium
    Tool `faction_list` accepts unconstrained string input· faction_listunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  220. medium
    Tool `faction_accept_ally` accepts unconstrained string input· faction_accept_allyunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `target_faction_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  221. medium
    Tool `faction_set_enemy` accepts unconstrained string input· faction_set_enemyunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `target_faction_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  222. medium
    Tool `faction_remove_enemy` accepts unconstrained string input· faction_remove_enemyunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `target_faction_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  223. medium
    Tool `faction_create_buy_order` accepts unconstrained string input· faction_create_buy_orderunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  224. medium
    Tool `faction_create_buy_order` description mentions money but no `money` side-effect is declared· faction_create_buy_orderexcessive agency

    Description: "Create a buy order on behalf of your faction (credits from faction treasury) (Credits are escrowed from the faction treasury. Purchased items go to faction storage. Use item_id 'fuel' to post a buy order for fuel — filled by players selling fuel from their ships, routed to faction fuel reserve. Requires `manage_treasury` permission. Accepts item_id or item name. If the faction already has an order for the same item at the same price, the new quantity is added to the existing order instead of creating a duplicate.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  225. medium
    Tool `refit_ship` accepts unconstrained string input· refit_shipunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  226. medium
    Tool `refit_ship` description mentions money but no `money` side-effect is declared· refit_shipexcessive agency

    Description: "Refit your active ship to its latest class specifications (Resets your ship's hull stats to the current class definition. All installed modules are returned to station storage. All cargo is moved to station storage. Default modules for this class are installed. Free of charge. Irreversible. Requires a shipyard. Returns already_current if the ship's stats already match the current class definition.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  227. medium
    Tool `analyze_market` accepts unconstrained string input· analyze_marketunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  228. medium
    Tool `view_storage` accepts unconstrained string input· view_storageunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `station_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  229. medium
    Tool `faction_create_sell_order` accepts unconstrained string input· faction_create_sell_orderunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  230. medium
    Tool `faction_post_mission` accepts unconstrained string input· faction_post_missionunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `description`, `giver_name`, `giver_title`, `session_id`, `title`, `type`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  231. medium
    Tool `buy_listed_ship` accepts unconstrained string input· buy_listed_shipunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `listing_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  232. medium
    Tool `buy_listed_ship` description mentions money but no `money` side-effect is declared· buy_listed_shipexcessive agency

    Description: "Purchase a ship from the exchange (Buy a ship from the exchange. Must be docked at the same base. Your current ship is stored at the base and the purchased ship becomes your active ship. Credits go directly to the seller.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  233. medium
    Tool `register` accepts unconstrained string input· registerunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `empire`, `registration_code`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  234. medium
    Tool `logout` accepts unconstrained string input· logoutunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  235. medium
    Tool `uninstall_mod` accepts unconstrained string input· uninstall_modunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `module_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  236. medium
    Tool `faction_invite` accepts unconstrained string input· faction_inviteunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `player_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  237. medium
    Tool `set_home_base` accepts unconstrained string input· set_home_baseunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `base_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  238. medium
    Tool `get_map` accepts unconstrained string input· get_mapunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `system_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  239. medium
    Tool `view_completed_mission` accepts unconstrained string input· view_completed_missionunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `template_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  240. medium
    Tool `view_market` accepts unconstrained string input· view_marketunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `category`, `item_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  241. medium
    Tool `jump` accepts unconstrained string input· jumpunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `target_system`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  242. medium
    Tool `scan` accepts unconstrained string input· scanunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `target_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  243. medium
    Tool `use_item` accepts unconstrained string input· use_itemunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  244. medium
    Tool `view_orders` accepts unconstrained string input· view_ordersunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `order_type`, `scope`, `search`, `session_id`, `sort_by`, `station_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  245. medium
    Tool `view_orders` description mentions money but no `money` side-effect is declared· view_ordersexcessive agency

    Description: "View your own orders at a station (Shows your active buy and sell orders at a station, including fill progress. Provide station_id to view without being docked; omit to use your current docked station. Supports pagination, filtering, and sorting. Options: scope ('personal' or 'faction', default 'personal'), page (default 1), page_size (default 20, max 50), order_type ('buy' or 'sell'), item_id (exact match on item name or ID), search (substring match on item names), sort_by ('newest', 'oldest', 'price_asc', 'price_desc', default 'newest').)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  246. medium
    Tool `get_poi` accepts unconstrained string input· get_poiunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  247. medium
    Tool `get_nearby` accepts unconstrained string input· get_nearbyunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  248. medium
    Tool `deploy_drone` accepts unconstrained string input· deploy_droneunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `drone_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  249. medium
    Tool `get_missions` accepts unconstrained string input· get_missionsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  250. medium
    Tool `browse_ships` accepts unconstrained string input· browse_shipsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `base_id`, `class_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  251. medium
    Tool `facility` accepts unconstrained string input· facilityunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `access`, `action`, `category`, `description`, `direction`, `facility_id`, `facility_type`, `listing_id`, `name`, `player_id`, `recipe_id`, `session_id`, `username`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  252. medium
    Tool `facility` description mentions money but no `money` side-effect is declared· facilityexcessive agency

    Description: "Manage facilities at stations (production, faction, personal, sales, and more) (Actions: types, build, list, toggle, upgrades, upgrade, faction_build, faction_upgrade, faction_list, faction_toggle, transfer, personal_build, personal_decorate, personal_visit, list_for_sale, browse_for_sale, buy_listing, cancel_listing. Call with no action or action 'help' for full documentation. Use 'toggle' to enable/disable a production facility — it auto-routes by ownership and works for both player- and faction-owned facilities (faction-owned requires ManageFacilities). 'faction_toggle' is kept as an explicit synonym. Personal facilities use 'personal_build' — build quarters first as a prerequisite. Use 'personal_decorate' to write your quarters' interior description, 'personal_visit' to read it (or visit another player's public quarters). Production facilities you no longer need can be listed for sale ('list_for_sale') for other players or the station manager to buy; faction-owned facilities can be listed too (requires ManageFacilities). Use 'browse_for_sale' at your current station to see listings.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  253. medium
    Tool `tow_wreck` accepts unconstrained string input· tow_wreckunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `wreck_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  254. medium
    Tool `get_system` accepts unconstrained string input· get_systemunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  255. medium
    Tool `create_buy_order` accepts unconstrained string input· create_buy_orderunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `deliver_to`, `item_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  256. medium
    Tool `create_buy_order` description mentions money but no `money` side-effect is declared· create_buy_orderexcessive agency

    Description: "Place a buy offer on the station exchange (1% listing fee on the portion that goes on the order book. Instant fills incur no fee. Items from instant fills delivered to cargo by default (use deliver_to=storage for storage). Accepts item_id or item name (e.g. 'Iron Ore'). Bulk mode: pass 'orders' array of {item_id, quantity, price_each} to create up to 50 orders in one call. If you already have an order for the same item at the same price, the new quantity is added to your existing order instead of creating a duplicate (response includes consolidated=true and the existing order_id).)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  257. medium
    Tool `commission_quote` accepts unconstrained string input· commission_quoteunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `ship_class`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  258. medium
    Tool `commission_quote` description mentions money but no `money` side-effect is declared· commission_quoteexcessive agency

    Description: "Get a cost estimate for commissioning a ship (Returns detailed pricing for both payment modes (credits-only vs provide-materials) and lists any blockers (wrong empire, shipyard tier, skills). Does not place an order.)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  259. medium
    Tool `chat` accepts unconstrained string input· chatunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `channel`, `session_id`, `target_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  260. medium
    Tool `petition` accepts unconstrained string input· petitionunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `empire_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  261. medium
    Tool `faction_propose_peace` accepts unconstrained string input· faction_propose_peaceunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `target_faction_id`, `terms`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  262. medium
    Tool `withdraw_items` accepts unconstrained string input· withdraw_itemsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `session_id`, `source`, `target`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  263. medium
    Tool `faction_submit_trade_intel` accepts unconstrained string input· faction_submit_trade_intelunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  264. medium
    Tool `get_battle_status` accepts unconstrained string input· get_battle_statusunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  265. medium
    Tool `faction_decline_invite` accepts unconstrained string input· faction_decline_inviteunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `faction_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  266. medium
    Tool `faction_query_intel` accepts unconstrained string input· faction_query_intelunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `poi_type`, `resource_type`, `session_id`, `source_faction_id`, `system_id`, `system_name`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  267. medium
    Tool `battle` accepts unconstrained string input· battleunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `action`, `session_id`, `stance`, `target_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  268. medium
    Tool `release_tow` accepts unconstrained string input· release_towunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  269. medium
    Tool `buy` accepts unconstrained string input· buyunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `deliver_to`, `item_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  270. medium
    Tool `buy` description mentions money but no `money` side-effect is declared· buyexcessive agency

    Description: "Buy items at market price from the station exchange (No fees for instant fills. Items delivered to cargo (or storage if cargo full). Use deliver_to=storage to send directly to storage. Use auto_list=true to automatically place a buy order for any unfilled quantity (1% listing fee applies). Accepts item_id or item name (e.g. 'Iron Ore').)" -- this references money/payment/refund/etc., but the declared side_effects ([]) don't include `money`. A capframe-bind policy that relies on declared side_effects to scope spend caveats will under-scope this tool.

    fix: Add `money` to the tool's `side_effects` declaration, or rewrite the description to clarify that no actual money moves.

  271. medium
    Tool `find_route` accepts unconstrained string input· find_routeunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`, `target_system`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  272. medium
    Tool `complete_mission` accepts unconstrained string input· complete_missionunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `mission_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  273. medium
    Tool `abandon_mission` accepts unconstrained string input· abandon_missionunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `mission_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  274. medium
    Tool `create_sell_order` accepts unconstrained string input· create_sell_orderunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `item_id`, `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

  275. medium
    Tool `get_notifications` accepts unconstrained string input· get_notificationsunconstrained input

    The following string parameter(s) have no `maxLength` constraint: `session_id`. Unbounded strings let an attacker stuff arbitrary payloads through the tool, including indirect-injection content.

    fix: Add a `maxLength` to each string property, or constrain with an `enum` or `pattern`. Most legitimate tool inputs fit under a few hundred bytes.

How this was scored

Source http live HTTP MCP endpoint, classified against every rule. Findings are emitted by the public capframe.findings.v1 schema. Score = 100 − (10·Critical + 4·High + 2·Medium + 1·Low), clamped to [0, 100].

Disagree with a finding? Open an issue.