SagaSmith

Security checks across malware telemetry and agentic risk

Overview

SagaSmith mostly implements D&D campaign tools, but it also includes broad personal-assistant instructions that are not clearly disclosed by the D&D skill description.

Install only if you want both a persistent D&D campaign manager and are comfortable reviewing or removing the bundled general-assistant templates. Before use, check AGENTS.md and templates/agent/identity.md, limit calendar/email/social/message tools unless explicitly needed, and treat save/load/delete actions as real changes to local campaign data.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (87)

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Content
def _row(model: Any, fields: tuple[str, ...]) -> dict[str, Any]:
    return {field: _json_value(getattr(model, field)) for field in fields}


def _snapshot_hash(payload: dict[str, Any]) -> str:
Confidence
50% confidence
Finding
return {field: _json_value(getattr(model, field)) for field in fields}

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Content
"schema_version": SNAPSHOT_SCHEMA_VERSION,
            "campaign_id": campaign_id,
            "captured_at": datetime.now(UTC).isoformat(),
            "campaign": {field: _json_value(getattr(campaign, field)) for field in _CAMPAIGN_FIELDS},
            "state": state,
        }
Confidence
50% confidence
Finding
"campaign": {field: _json_value(getattr(campaign, field)) for field in _CAMPAIGN_FIELDS},

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Content
aggregate = self._find_aggregate(session, revision)
        payload = dict(revision.before_state_json or {})
        state_attribute = "sheet_json" if isinstance(aggregate, Character) else "state_json"
        current = dict(getattr(aggregate, state_attribute) or {})
        setattr(aggregate, state_attribute, payload)

        if isinstance(aggregate, Character):
Confidence
50% confidence
Finding
current = dict(getattr(aggregate, state_attribute) or {})

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
This is a mismatch because the description presents the skill as an autonomous AI Dungeon Master with persona behavior and module generation, while the code is primarily a backend service/toolkit for D&D data management: campaign lifecycle, module import/index/search, rule ingestion/search, snapshots, undo, audit logs, characters, and helper dice/combat utilities. Some described areas are partially supported (campaign lifecycle, module handling, rule adjudication support through search/dice helpers), but key claimed behavior—an immersive Minthara Baenre DM persona and autonomous DMing—is not implemented in the provided code. Additionally, the code includes several substantial capabilities not stated in the description, especially snapshot management, undo/audit systems, character persistence, event logging, and workspace file synchronization.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The top-level documentation states that file-based persistence is deprecated, that all campaign state is stored in the SQL database, and that no new code should call this module. However, the implementation repeatedly writes combat state to `combat_state.json` via `save_combat()` and deletes that file in `clear()`, which directly contradicts the stated storage model and operational guidance.

Intent-Code Divergence

Low
Confidence
95% confidence
Finding
The top-level documentation states this module is deprecated, exists only for backward compatibility, and that no new code should call it. However, the module contains fully active read/write/delete behavior for a JSON cache file via load_chapter_cache, _write_cache, and clear_cache, so the documentation communicates disuse while the code still performs stateful persistence operations.

Intent-Code Divergence

Low
Confidence
96% confidence
Finding
Lines L005-L010 present operational guidance claiming the module is deprecated and should not be called, but they are not inside a comment or string literal after the initial docstring ends at L003. As written, this text would be parsed as code and break execution, creating a direct divergence between the file's documented intent as a backward-compatibility module and what the code can actually do.

Intent-Code Divergence

Low
Confidence
93% confidence
Finding
The header text explicitly states the module exists only for backward compatibility, that campaign state is stored in the SQL database, and that no new code should call this module. However, the file implements active persistence helpers such as save_scene_index() and set_current_scene() that create directories and write JSON state to disk, which conflicts with the stated intent of being effectively retired.

Intent-Code Divergence

Low
Confidence
95% confidence
Finding
The top-level documentation states this is deprecated, only for backward compatibility, and that all campaign state is stored in the SQL database with no new callers expected. However, the module defines and exposes write-capable functions such as update_party, update_character, update_hp, and update_spell_slots that actively persist live state to live_party.json, which contradicts the stated intent of being effectively retired.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The manifest describes a D&D 5e AI Dungeon Master focused on campaign management, module generation, and rule adjudication. This file additionally instructs the agent to perform heartbeat-driven email, calendar, social notification, weather, project-status, documentation, and git push tasks, which are generic personal-assistant capabilities not justified by the stated game-mastering scope.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
The manifest frames the skill as an autonomous D&D Dungeon Master bundle, but these instructions authorize external web activity, calendar access, outbound communications, and optional voice synthesis. Those capabilities are not obviously required for campaign lifecycle management, module generation, or rule adjudication.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The `read_only` property explicitly returns `True`, which communicates no mutating side effects. However, `_ensure_ready()` calls `self.database.upgrade_schema()` when `migrate` is enabled, which is a database-modifying operation and contradicts the read-only claim.

Intent-Code Divergence

Medium
Confidence
84% confidence
Finding
The module docstring says this is "rule retrieval" and the class docstring says it searches the indexed SRD without spawning a fresh process, both suggesting a retrieval-only utility. In practice, the tool may execute `upgrade_schema()` on first use, which is a write-side administrative action not reflected in the documentation.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
README 介绍了 Snapshot 存档/读档/撤销等会直接影响战役状态和持久化数据的操作,但在功能说明处没有提醒这些操作会写入或恢复数据库状态。虽然示例中展示了这些功能如何工作,但缺少面向用户的明确风险提示,如覆盖当前进度、自动保存副作用或需谨慎操作的说明。

Missing User Warnings

Medium
Confidence
83% confidence
Finding
README 说明技能可导入并解析用户上传的模组文件,还提到专有结构解析,但没有说明这些文件会被如何处理、存储或索引,也没有任何对敏感内容、受版权保护材料或本地数据持久化的提醒。对会接触用户文档内容的技能描述而言,这属于缺少用户告知。

Natural-Language Policy Violations

Low
Confidence
71% confidence
Finding
该文件是中文 README,并通过中英文切换链接表明项目支持多语言,但正文未明确说明技能运行时是否允许用户自由选择语言。若技能默认随文档语言固定输出中文,可能与要求提供语言选择或用户自选的组织策略冲突。

Missing User Warnings

Low
Confidence
83% confidence
Finding
This markdown file documents that created characters are 'Saved to database,' which is a persistent user-data write. While the examples show the behavior, the README does not include a clear caution or warning section explaining that campaign actions will modify and persist local state.

Missing User Warnings

Low
Confidence
85% confidence
Finding
The example states that a module is generated as 'modules/sewer_shadows.md' and then imported, implying local file creation and downstream data ingestion. The README lacks an explicit warning that using generation/import features will create files and alter local skill data.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The campaign management example shows 'Auto-saving current' followed by restoring a prior slot, which affects persistent campaign state and can be difficult to reverse if misunderstood. Although the example includes an inline warning symbol, the README does not provide a general user warning that save/load operations can overwrite or roll back campaign progress.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The delete method irreversibly removes a campaign via session.delete(campaign), but there is no confirmation prompt, logging, print statement, or explanatory docstring/comment warning users about the destructive action. For code files, destructive operations should have some visible disclosure unless the warning is documented elsewhere.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The code stores Chinese strings such as '完成', '进行中', and '待触发' in quest_progress keys, and later uses '初始状态' as a snapshot label. This imposes a specific language in user-visible data without offering user choice or documenting a justified locale restriction.

Natural-Language Policy Violations

Low
Confidence
89% confidence
Finding
The initial snapshot is labeled '初始状态', which is a user-visible string in a fixed language. Under the language/locale policy, skills should not force a specific language unless users can opt in or the restriction is clearly documented and justified.

Missing User Warnings

Low
Confidence
86% confidence
Finding
This code writes a ToolAudit entry containing the event content and metadata after creating a campaign event. For code files, safety-relevant data persistence should have some visible disclosure such as a user-facing log, prompt, or explanatory comment/docstring; this block stores additional user-supplied data without such disclosure nearby.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This code file invokes `command.upgrade(...)` to modify the database schema, which is a potentially irreversible operation affecting user or system data. The file contains no confirmation prompt, logging/print disclosure, or explanatory comment/docstring on the `upgrade_database` function warning callers about this action.

VirusTotal

64/64 vendors flagged this skill as clean.

View on VirusTotal