{"data":{"skill":{"slug":"aaron-he-zhu-serp-analysis","name":"serp-analysis","icon":"📦","repo":"https://github.com/aaron-he-zhu/aaron-marketing-skills/tree/main/seo-geo/research/serp-analysis","status":"approved","author":"aaron-he-zhu","authorVersion":null,"skillstoreRevision":null},"audit":{"id":"1a258df2-dc12-43f7-8408-d084e494b7cf","skill_id":"7e098604-b0d8-4641-adcc-302bac78d83e","version":2,"content_hash":"51ca9144b83477a28f91552192a73c26","risk_level":"safe","is_blocked":false,"safe_to_publish":true,"analysis_status":"ok","agent_auto_install_policy":"allowed","manual_install_policy":"allowed","summary":"Most static findings are false positives from Markdown fences, relative repository links, metadata URLs, and inline path templates. Two medium findings are confirmed because the skill instructs agents to run bundled Python connector commands for live SERP data; no prompt injection, secret exfiltration, or arbitrary path traversal evidence was found.","remediation":[{"issue":"Shell connector commands are embedded in the skill instructions.","severity":"medium","suggestion":"Require explicit user approval before running connector commands, keep keyword arguments quoted, and document that live network calls may occur."},{"issue":"Allowed tool metadata does not clearly describe shell connector usage.","severity":"medium","suggestion":"Align the declared tool requirements with the documented connector workflow or provide host-native alternatives for environments without shell access."},{"issue":"The saved report path uses a topic placeholder.","severity":"low","suggestion":"State that the topic should be converted to a safe slug before writing the memory file."}],"risk_factor_evidence":[{"factor":"external_commands","evidence":[{"file":"SKILL.md","line_end":25,"line_start":23},{"file":"SKILL.md","line_end":27,"line_start":25},{"file":"SKILL.md","line_end":29,"line_start":27},{"file":"SKILL.md","line_end":33,"line_start":29},{"file":"SKILL.md","line_end":37,"line_start":33},{"file":"SKILL.md","line_end":37,"line_start":37},{"file":"SKILL.md","line_end":49,"line_start":49},{"file":"SKILL.md","line_end":51,"line_start":51},{"file":"SKILL.md","line_end":84,"line_start":82},{"file":"SKILL.md","line_end":88,"line_start":84},{"file":"SKILL.md","line_end":90,"line_start":88},{"file":"SKILL.md","line_end":94,"line_start":90},{"file":"SKILL.md","line_end":96,"line_start":94},{"file":"SKILL.md","line_end":100,"line_start":96},{"file":"SKILL.md","line_end":102,"line_start":100},{"file":"SKILL.md","line_end":116,"line_start":102},{"file":"SKILL.md","line_end":116,"line_start":116}]},{"factor":"network","evidence":[{"file":"SKILL.md","line_end":10,"line_start":10},{"file":"SKILL.md","line_end":14,"line_start":14}]},{"factor":"filesystem","evidence":[{"file":"SKILL.md","line_end":39,"line_start":39},{"file":"SKILL.md","line_end":43,"line_start":43},{"file":"SKILL.md","line_end":47,"line_start":47},{"file":"SKILL.md","line_end":49,"line_start":49},{"file":"SKILL.md","line_end":112,"line_start":112},{"file":"SKILL.md","line_end":116,"line_start":116},{"file":"SKILL.md","line_end":123,"line_start":123},{"file":"SKILL.md","line_end":127,"line_start":127}]},{"factor":"env_access","evidence":[{"file":"SKILL.md","line_end":49,"line_start":49}]}],"critical_findings":[],"high_findings":[],"medium_findings":[{"title":"Ruby/shell backtick execution","locations":[{"file":"SKILL.md","line_end":49,"line_start":49}],"confidence":0.87,"description":"**Zero-dependency live SERP (keyless)**: `python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/connectors/firecraw","review_kind":"capability","source_category":"external_commands","source_severity":"medium","confidence_reasoning":"The line instructs an agent to run a Python connector command with a user-supplied keyword and live network search. This is legitimate functionality but still real external command execution that expands runtime risk."},{"title":"Ruby/shell backtick execution","locations":[{"file":"SKILL.md","line_end":51,"line_start":51}],"confidence":0.86,"description":"**Second keyless engine for corroboration**: `python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/connectors/tavi","review_kind":"capability","source_category":"external_commands","source_severity":"medium","confidence_reasoning":"The line instructs an agent to run a second Python connector command for live search and AI answer retrieval. The command is purposeful, but it is still external command execution and should require appropriate execution controls."}],"low_findings":[],"dangerous_patterns":[],"files_scanned":4,"total_lines":416,"audit_model":"codex","audited_at":"2026-07-04T16:20:50.57+00:00","created_at":"2026-07-07T02:34:37.511754+00:00","static_findings":[{"id":"external_commands:SKILL.md:23:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":25,"severity":"medium","line_start":23},{"id":"external_commands:SKILL.md:25:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":27,"severity":"medium","line_start":25},{"id":"external_commands:SKILL.md:27:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":29,"severity":"medium","line_start":27},{"id":"external_commands:SKILL.md:29:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":33,"severity":"medium","line_start":29},{"id":"external_commands:SKILL.md:33:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Expected output**: a prioritized SERP brief plus the standard handoff summary for `memory/research","category":"external_commands","line_end":37,"severity":"medium","line_start":33},{"id":"external_commands:SKILL.md:37:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- **Promotes**: durable keyword priorities, competitor facts, and pending strategy decisions to `mem","category":"external_commands","line_end":37,"severity":"medium","line_start":37},{"id":"external_commands:SKILL.md:49:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Zero-dependency live SERP (keyless)**: `python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/connectors/firecraw","category":"external_commands","line_end":49,"severity":"medium","line_start":49},{"id":"external_commands:SKILL.md:51:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Second keyless engine for corroboration**: `python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/connectors/tavi","category":"external_commands","line_end":51,"severity":"medium","line_start":51},{"id":"external_commands:SKILL.md:82:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":84,"severity":"medium","line_start":82},{"id":"external_commands:SKILL.md:84:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":88,"severity":"medium","line_start":84},{"id":"external_commands:SKILL.md:88:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":90,"severity":"medium","line_start":88},{"id":"external_commands:SKILL.md:90:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":94,"severity":"medium","line_start":90},{"id":"external_commands:SKILL.md:94:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":96,"severity":"medium","line_start":94},{"id":"external_commands:SKILL.md:96:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":100,"severity":"medium","line_start":96},{"id":"external_commands:SKILL.md:100:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":102,"severity":"medium","line_start":100},{"id":"external_commands:SKILL.md:102:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":116,"severity":"medium","line_start":102},{"id":"external_commands:SKILL.md:116:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Write path: `memory/research/serp-analysis/YYYY-MM-DD-<topic>.md`; promote durable difficulty/intent","category":"external_commands","line_end":116,"severity":"medium","line_start":116},{"id":"network:SKILL.md:10:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"homepage: \"https://github.com/aaron-he-zhu/aaron-marketing-skills\"","category":"network","line_end":10,"severity":"low","line_start":10},{"id":"network:SKILL.md:14:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"metadata: {\"author\": \"aaron-he-zhu\", \"version\": \"13.0.0\", \"discipline\": \"seo-geo\", \"phase\": \"researc","category":"network","line_end":14,"severity":"low","line_start":14},{"id":"filesystem:SKILL.md:39:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"- **Primary next skill**: [content-writer](../../build/content-writer/SKILL.md) when the user is rea","category":"filesystem","line_end":39,"severity":"high","line_start":39},{"id":"filesystem:SKILL.md:43:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"> Emit the standard shape from [skill-contract.md §Handoff Summary Format](../../../references/skill","category":"filesystem","line_end":43,"severity":"high","line_start":43},{"id":"filesystem:SKILL.md:47:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"Optional integrations: ~~SEO tool, ~~search console, ~~AI monitor. Before fetching third-party SERP ","category":"filesystem","line_end":47,"severity":"high","line_start":47},{"id":"filesystem:SKILL.md:49:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"**Zero-dependency live SERP (keyless)**: `python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/connectors/firecraw","category":"filesystem","line_end":49,"severity":"high","line_start":49},{"id":"filesystem:SKILL.md:112:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"See [references/platforms/youtube.md](../../../references/platforms/youtube.md) for YouTube-as-citat","category":"filesystem","line_end":112,"severity":"high","line_start":112},{"id":"filesystem:SKILL.md:116:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"Write path: `memory/research/serp-analysis/YYYY-MM-DD-<topic>.md`; promote durable difficulty/intent","category":"filesystem","line_end":116,"severity":"high","line_start":116},{"id":"filesystem:SKILL.md:123:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"- [YouTube as citation surface](../../../references/platforms/youtube.md) — Video SERP / outlier pac","category":"filesystem","line_end":123,"severity":"high","line_start":123},{"id":"filesystem:SKILL.md:127:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"Primary: [content-writer](../../build/content-writer/SKILL.md).","category":"filesystem","line_end":127,"severity":"high","line_start":127},{"id":"env_access:SKILL.md:49:generic-api-secret-keys","file":"SKILL.md","pattern":"Generic API/secret keys","snippet":"**Zero-dependency live SERP (keyless)**: `python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/connectors/firecraw","category":"env_access","line_end":49,"severity":"high","line_start":49}],"finding_verdicts":[{"id":"external_commands:SKILL.md:23:ruby-shell-backtick-execution","reason":"This is an opening Markdown code fence for a prompt example, not Ruby or shell execution. There is no command or executable payload on these lines.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:25:ruby-shell-backtick-execution","reason":"This is a closing Markdown code fence around a natural language prompt example. It does not instruct code execution or include shell syntax.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:27:ruby-shell-backtick-execution","reason":"This is an opening Markdown code fence for another natural language prompt. No executable command is present.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:29:ruby-shell-backtick-execution","reason":"This is a closing Markdown code fence for a prompt example. It is documentation formatting, not command execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:33:ruby-shell-backtick-execution","reason":"The backticked text is a memory directory name in expected output guidance. It is not a shell command or dynamic execution path.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:SKILL.md:37:ruby-shell-backtick-execution","reason":"The backticked paths identify repository memory files for handoff notes. They are not commands and do not invoke an interpreter.","verdict":"false_positive","confidence":0.96},{"id":"external_commands:SKILL.md:49:ruby-shell-backtick-execution","reason":"The line instructs an agent to run a Python connector command with a user-supplied keyword and live network search. This is legitimate functionality but still real external command execution that expands runtime risk.","verdict":"confirmed","severity":"medium","confidence":0.87},{"id":"external_commands:SKILL.md:51:ruby-shell-backtick-execution","reason":"The line instructs an agent to run a second Python connector command for live search and AI answer retrieval. The command is purposeful, but it is still external command execution and should require appropriate execution controls.","verdict":"confirmed","severity":"medium","confidence":0.86},{"id":"external_commands:SKILL.md:82:ruby-shell-backtick-execution","reason":"This is an opening Markdown code fence for a multi-keyword prompt example. It contains no executable shell command.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:84:ruby-shell-backtick-execution","reason":"This is documentation formatting around a prompt example. The detected backticks do not indicate Ruby or shell execution.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:88:ruby-shell-backtick-execution","reason":"This is an opening Markdown code fence for a historical SERP prompt. It is natural language guidance, not executable code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:90:ruby-shell-backtick-execution","reason":"This is Markdown formatting near prompt examples. No command invocation or interpreter directive appears in the cited lines.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:94:ruby-shell-backtick-execution","reason":"This is an opening Markdown code fence for a local SERP comparison prompt. It is not a shell command.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:96:ruby-shell-backtick-execution","reason":"This is Markdown formatting around prompt examples. There is no executable command on the cited lines.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:100:ruby-shell-backtick-execution","reason":"This is an opening Markdown code fence for a mobile versus desktop prompt. It contains only user-facing prompt text.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:102:ruby-shell-backtick-execution","reason":"This is a closing Markdown code fence followed by prose instructions. It does not run Ruby, shell, or any other interpreter.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:116:ruby-shell-backtick-execution","reason":"The backticked text is an output file path template for saving research notes. It is not an external command execution instruction.","verdict":"false_positive","confidence":0.94},{"id":"network:SKILL.md:10:hardcoded-url","reason":"The URL is the public project homepage in frontmatter metadata. It is not a runtime network request or data exfiltration endpoint.","verdict":"false_positive","confidence":0.97},{"id":"network:SKILL.md:14:hardcoded-url","reason":"The URL appears inside metadata for the OpenClaw homepage. It does not instruct the agent to call that URL or send user data.","verdict":"false_positive","confidence":0.96},{"id":"filesystem:SKILL.md:39:path-traversal-sequence","reason":"The relative path is a Markdown link to another skill inside the same repository. It is documentation navigation, not filesystem traversal with user input.","verdict":"false_positive","confidence":0.96},{"id":"filesystem:SKILL.md:43:path-traversal-sequence","reason":"The relative path is a Markdown link to a shared reference file. It does not read arbitrary user-controlled paths.","verdict":"false_positive","confidence":0.96},{"id":"filesystem:SKILL.md:47:path-traversal-sequence","reason":"The relative paths point to repository documentation such as SECURITY.md and CONNECTORS.md. They are static documentation links, not traversal operations.","verdict":"false_positive","confidence":0.95},{"id":"filesystem:SKILL.md:49:path-traversal-sequence","reason":"The line references a bundled connector path under the plugin root and a repository README link. The execution risk is covered separately, but the path itself is not arbitrary traversal.","verdict":"false_positive","confidence":0.82},{"id":"filesystem:SKILL.md:112:path-traversal-sequence","reason":"The relative path is a Markdown link to a platform reference document. It is not a filesystem access primitive.","verdict":"false_positive","confidence":0.96},{"id":"filesystem:SKILL.md:116:path-traversal-sequence","reason":"The line defines a conventional output path under memory/research for generated notes. It does not contain a traversal sequence or instruct writing outside that directory, though slugifying the topic would reduce ambiguity.","verdict":"false_positive","confidence":0.78},{"id":"filesystem:SKILL.md:123:path-traversal-sequence","reason":"The relative path is a Markdown reference link for YouTube guidance. It is static documentation navigation, not path traversal.","verdict":"false_positive","confidence":0.96},{"id":"filesystem:SKILL.md:127:path-traversal-sequence","reason":"The relative path is a Markdown link to the recommended next skill. It does not create a user-controlled file access path.","verdict":"false_positive","confidence":0.96},{"id":"env_access:SKILL.md:49:generic-api-secret-keys","reason":"The line mentions FIRECRAWL_API_KEY as an optional credential for a legitimate connector. It does not instruct the agent to reveal, log, or send secrets outside the intended API authentication flow.","verdict":"false_positive","confidence":0.84}],"semantic_findings":[],"subject_marketplace_commit_sha":null,"subject_content_hash":null,"subject_tree_hash":null,"subject_plugin_path":null,"audit_payload_hash":null,"confirmed_risk_level":null,"scanner_version":null,"policy_version":null,"subject":{"marketplaceCommitSha":null,"contentHash":null,"treeHash":null,"pluginPath":null,"auditPayloadHash":null},"scannerVersion":null,"policyVersion":null},"auditTranslation":null,"localization":{"requestedLocale":"en","contentLocale":"en","availableLocales":["en"],"fallbackToEnglish":false},"attestation":{"availability":"not_attestable","url":null,"status":null,"reason":"confirmed_risk_level does not match the canonical trust resolver"},"trust":{"publicState":"public","auditState":"complete","auditCurrentness":null,"confirmedRiskLevel":"safe","confirmedFindingCount":0,"capabilityReviewCount":2,"needsReviewCount":0,"falsePositiveCount":0,"agentAutoInstallPolicy":"allowed","manualInstallPolicy":"allowed","artifactSignatureState":"available","attestationState":"not_attestable","verificationState":"not_verified"},"isLatest":false}}