Back to skill

Security audit

Gorm Expert

Security checks for vulnerabilities and agentic risk

Overview

This GORM helper skill is mostly transparent, but its bundled database scaffolding has tenant-isolation and migration-safety issues users should review before use.

Review before installing or using the scaffolded dbcore package in a real application. Treat the scripts as local code generators, manually review generated SQL before running it, do not rely on the bundled BaseModel for tenant security without fixes, and do not expose the pprof or insecure telemetry examples in production.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
assets/dbcore/base_model.go:132
Finding
Incomplete Multi-Tenant Write Isolation Allows Tenant Spoofing and Reassignment<![CDATA[ ## Vulnerability Details **File Location**: `assets/dbcore/base_model.go:132-180` **Vulnerability Type**: Incomplete tenant authorization enforcement **Risk Level**: High ### Vulnerable Code ```go // GetTxDB 获取数据库连接(优先从 ctx 中取事务连接) // 当 TenantEnabled=true 时,自动注入租户隔离条件 func (m *BaseModel[T]) GetTxDB(ctx context.Context) *gorm.DB { db := GetDB(ctx, m.DB).WithContext(ctx) if globalConfig.TenantEnabled && globalConfig.TenantExtractor != nil { tenantID := globalConfig.TenantExtractor(ctx) if tenantID != "" { db = db.Where(safeField(globalConfig.TenantField)+" = ?", tenantID) } else if globalConfig.TenantStrict { // 严格模式:无租户信息时拒绝所有查询,防止数据越权 db = db.Where("1 = 0") } } return db } // ==================== 插入操作 ==================== func (m *BaseModel[T]) Insert(ctx context.Context, v *T) error { autoFillID(v) return m.GetTxDB(ctx).Create(v).Error } func (m *BaseModel[T]) InsertBatch(ctx context.Context, v []*T, batchSize int) error { if len(v) == 0 { return nil } autoFillIDBatch(v) if batchSize <= 0 { batchSize = 100 } return m.GetTxDB(ctx).CreateInBatches(v, batchSize).Error } // ==================== 更新操作 ==================== func (m *BaseModel[T]) Update(ctx context.Context, id string, v map[string]interface{}) error { if id == "" { return gorm.ErrMissingWhereClause } return m.GetTxDB(ctx).Model(new(T)).Where("id = ?", id).Updates(v).Error } func (m *BaseModel[T]) UpdateBy(ctx context.Context, v map[string]interface{}, query string, args ...interface{}) error { if query == "" { return gorm.ErrMissingWhereClause } return m.GetTxDB(ctx).Model(new(T)).Where(query, args...).Updates(v).Error } ``` ### Technical Analysis Tenant enforcement is implemented exclusively as a GORM `WHERE` condition. That condition restricts which existing rows can be selected, updated, or deleted, but it does not securely control the value written into the tenant column. The `Insert` and `InsertBatch` methods pass caller-provided obj ...[truncated 2853 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate configuration when tenant mode is enabled: - Reject `TenantEnabled: true` if `TenantExtractor` is nil. - In strict mode, return an explicit error when the tenant ID is missing rather than relying only on `WHERE 1 = 0`. 2. Enforce tenant ownership on insert: - Resolve the tenant ID from the trusted context. - Set the configured tenant field on every object before calling `Create` or `CreateInBatches`. - Overwrite any caller-provided tenant value rather than trusting it. - Consider a GORM create callback if reflection-based assignment must support generic models. 3. Protect updates: - Reject update maps containing the configured tenant field. - Alternatively, delete that key from the map and preserve the existing tenant value. - Provide a separate, explicitly privileged administrative operation for legitimate tenant transfers. 4. Apply equivalent protections to full-model writes such as `Save`, which can also persist a caller-controlled tenant field. 5. Prefer immutable tenant ownership at the database layer where practical: - Use database triggers or repository-specific constraints to prevent ordinary operations from changing tenant IDs. - Apply composite uniqueness and indexing rules that include the tenant column. 6. Add security tests covering: - Insert with a spoofed tenant ID. - Batch insert containing mixed tenant IDs. - Update and `Save` attempts that change tenant ownership. - Missing tenant context in strict mode. - `TenantEnabled` with a nil extractor. - Read, update, and delete attempts across two distinct tenants. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/migration_gen.py:201
Finding
Migration Generator Permits SQL Injection Through Unvalidated Identifiers and GORM Tags<![CDATA[ ## Vulnerability Details **File Location**: `scripts/migration_gen.py:201-254` **Vulnerability Type**: SQL generation injection **Risk Level**: Medium ### Vulnerable Code ```python def generate_migration( old_fields: Dict[str, FieldDef], new_fields: Dict[str, FieldDef], table: str, db_type: str = "mysql", ) -> Tuple[str, str]: """返回 (up_sql, down_sql)""" up_stmts: List[str] = [] down_stmts: List[str] = [] added = {k: v for k, v in new_fields.items() if k not in old_fields} removed = {k: v for k, v in old_fields.items() if k not in new_fields} changed = {} for k in new_fields: if k in old_fields: n, o = new_fields[k], old_fields[k] if n.db_type != o.db_type or n.nullable != o.nullable or n.default != o.default: changed[k] = (o, n) def col_def(f: FieldDef, include_null: bool = True) -> str: parts = [f.db_type] if include_null: parts.append("NULL" if f.nullable else "NOT NULL") if f.default is not None: parts.append(f"DEFAULT {f.default}") if f.comment: parts.append(f"COMMENT '{f.comment}'") return " ".join(parts) # 新增列 for col, f in added.items(): algorithm = ", ALGORITHM=INSTANT" if db_type == "mysql" else "" up_stmts.append( f"ALTER TABLE `{table}` ADD COLUMN `{col}` {col_def(f)}{algorithm};" ) down_stmts.append( f"ALTER TABLE `{table}` DROP COLUMN `{col}`;" ) # 删除列(up 删,down 加回) for col, f in removed.items(): up_stmts.append( f"ALTER TABLE `{table}` DROP COLUMN `{col}`;" ) down_stmts.append( f"ALTER TABLE `{table}` ADD COLUMN `{col}` {col_def(f)}, ALGORITHM=INSTANT;" ) # 修改列 for col, (old_f, new_f) in changed.items(): up_stmts.append( f"ALTER TABLE `{table}` MODIFY COLUMN `{col}` {col_def(new_f)};" + ...[truncated 3953 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate every SQL identifier: - Restrict table, column, and index names to a conservative expression such as `^[A-Za-z_][A-Za-z0-9_]*$`. - Reject embedded quoting characters, whitespace, separators, comments, and semicolons. - Apply validation both to CLI input and parsed GORM tags. 2. Implement dialect-specific identifier quoting: - Escape embedded quote characters correctly if broader identifier support is required. - Use double-quoted identifiers for PostgreSQL and backtick-quoted identifiers for MySQL. - Do not use MySQL syntax for PostgreSQL output. 3. Treat defaults and types as structured data: - Parse types and allow only recognized database type names plus validated numeric size or precision parameters. - Allowlist safe default forms such as numeric literals, properly escaped strings, `NULL`, and explicitly supported functions. - Reject arbitrary SQL expressions unless a separate unsafe mode is deliberately requested. 4. Escape comments using the selected database dialect's string-literal rules. Reject control characters that cannot be represented safely. 5. Add a safe-by-default output policy: - Clearly mark generated SQL as requiring review. - Avoid automatically executing generated output. - If an unsafe passthrough mode is retained, require an explicit flag and prominently annotate the result. 6. Add adversarial tests for: - Backticks and double quotes in identifiers. - Single quotes and newlines in comments. - Semicolons and SQL comments in defaults and types. - Crafted index names. - Malicious `--table` values. - Differences between MySQL and PostgreSQL quoting rules. 7. Run migrations with least privilege and require code review or approval gates before generated SQL reaches a production database. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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 (39)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill advertises broad GORM review and optimization expertise, but it also includes local filesystem scaffolding and template-copy behavior that is not prominently disclosed in the description. Hidden or under-declared write behavior is dangerous because it can cause unauthorized project modifications when the skill is triggered for what appears to be analysis-only assistance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill advertises broad GORM review and optimization expertise, but it also includes local filesystem scaffolding and template-copy behavior that is not prominently disclosed in the description. Hidden or under-declared write behavior is dangerous because it can cause unauthorized project modifications when the skill is triggered for what appears to be analysis-only assistance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill advertises broad GORM review and optimization expertise, but it also includes local filesystem scaffolding and template-copy behavior that is not prominently disclosed in the description. Hidden or under-declared write behavior is dangerous because it can cause unauthorized project modifications when the skill is triggered for what appears to be analysis-only assistance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The skill advertises broad GORM review and optimization expertise, but it also includes local filesystem scaffolding and template-copy behavior that is not prominently disclosed in the description. Hidden or under-declared write behavior is dangerous because it can cause unauthorized project modifications when the skill is triggered for what appears to be analysis-only assistance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill advertises broad GORM review and optimization expertise, but it also includes local filesystem scaffolding and template-copy behavior that is not prominently disclosed in the description. Hidden or under-declared write behavior is dangerous because it can cause unauthorized project modifications when the skill is triggered for what appears to be analysis-only assistance.

Ae1

High
Category
analysis-evasion
Content
| Go 代码审查 | `scripts/analyze_gorm.py` | `python3 scripts/analyze_gorm.py - <<< "代码"`(R1–R27;CI 用 `--format json`) |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The skill description begins in Chinese and the rest of the README is written entirely in Chinese, which indicates a fixed language choice for the skill's natural-language interface. Under the policy, language constraints should either offer user opt-in/choice or be clearly justified as region-specific; neither is present here.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill explicitly instructs the agent to run local Python scripts and includes examples that read stdin and write output files, but it does not declare any tool scope such as allowed-tools or permissions. That creates an authorization gap where a reviewer or runtime cannot easily constrain file read/write and environment access, increasing the chance of unintended local actions when the skill is invoked.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger list includes broad everyday terms like '缓存', '迁移', and '写struct', which can cause the skill to activate in unrelated conversations. Because this skill recommends script execution and supports file-writing workflows, overbroad triggering increases the risk of accidental invocation of code-generation or local-modification behavior in contexts where the user did not intend to use this skill.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The example advises launching a goroutine inside an AfterCreate hook to avoid blocking, but GORM hooks may run before the surrounding transaction is durably committed. This can trigger side effects such as sending a welcome email for a user record that is later rolled back, creating inconsistent behavior and possible information leakage or duplicate/out-of-order notifications.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
This markdown file includes example code that initializes an OTLP HTTP exporter and sends tracing data to an external collector. The surrounding documentation does not warn that trace attributes such as SQL statements and service metadata may be transmitted off-process, which is a privacy and data-handling concern for observability setups.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The document starts a pprof HTTP server on :6060 with default handlers and no access control, network binding restriction, or warning. If exposed beyond localhost or reachable in production, pprof endpoints can leak memory contents, goroutine stacks, execution details, and profiling data that materially aid attackers and may expose secrets.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This markdown file includes `UPDATE` and `DELETE` raw SQL examples that can directly modify or remove data, but the surrounding description does not warn readers about the destructive nature of these operations or advise caution before use. Under the markdown-specific SQP-2 criteria, examples affecting user data or system integrity should include some disclosure of the risk.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The entire markdown document is written in Chinese and does not offer any language choice or indicate that the content is intentionally region-specific. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
This markdown file contains user-facing instructional content exclusively in Chinese, and there is no indication that the skill or reference is region-specific or that users can opt into this locale. Under the policy, forcing a specific language without user choice is a natural-language policy violation.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The document states that `*gorm.DB` is stateful and not goroutine-safe, then later claims `Session(&gorm.Session{NewDB: true})` makes goroutine use safe. That oversimplifies a concurrency-sensitive API and may cause developers to share derived handles across goroutines under false safety assumptions, leading to race conditions, condition leakage, or cross-tenant query corruption in production code.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The module docstring and CLI usage text are entirely in Chinese, and later user-facing messages are also emitted only in Chinese. This imposes a specific language/locale on users without opt-in or documented justification, which matches the language-policy violation criteria.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The success message, issue formatting text, parser description, and argument help strings are all hardcoded in Chinese. Because the script does not offer the user a language choice or indicate a justified region-specific constraint, this is a natural-language locale policy concern.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
This code file contains user-facing natural language in the module docstring and later emits Chinese-language guidance, errors, and generated comments. Under the policy rule, forcing a specific language without opt-in is a locale/language policy violation because users are not offered an alternative or told the skill is intentionally Chinese-only.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The module docstring and usage instructions are presented only in Chinese, which imposes a specific language on users. The file does not provide any opt-in, alternate locale, or justification that this is a region-specific tool, so it matches the natural-language locale policy violation criteria.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
Returned complexity labels, findings text, EXPLAIN guidance, parser description, help text, and error messages are all emitted in Chinese. Because users are not given any language or locale choice, this constitutes a natural-language policy violation under the provided criteria.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
This Go file contains user-facing natural-language comments and usage guidance entirely in Chinese, including the header and operational notes. Under the policy, forcing a specific language without user opt-in or a documented region-specific justification is a natural-language policy concern.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
This Go file contains extensive natural-language comments exclusively in Chinese, including operational descriptions and usage notes. Under the stated policy, forcing a specific language without offering choice or documenting a justified locale constraint is a natural-language policy issue.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The file's natural-language guidance and example error text are written exclusively in Chinese, including the top-level usage instructions and later user-visible error strings. Under the stated policy, forcing a specific language without user opt-in is a locale/language policy concern.

Natural-Language Policy Violations

Low
Confidence
98% confidence
Finding
The returned error message "订单状态不允许完成操作" is hard-coded in a single language. If surfaced to users or operators, it enforces a specific locale without any documented choice mechanism.

Static analysis

No suspicious patterns detected.