{"data":{"skill":{"slug":"aaron-he-zhu-competitor-analysis","name":"competitor-analysis","icon":"📦","repo":"https://github.com/aaron-he-zhu/aaron-marketing-skills/tree/main/seo-geo/research/competitor-analysis","status":"approved","author":"aaron-he-zhu","authorVersion":"17.0.0","skillstoreRevision":1},"audit":{"id":"fca899ce-ac9f-4762-b72e-b97c3de08f34","skill_id":"dfbe8425-e452-460a-bb85-a631f6bc061e","version":3,"content_hash":"v3:d71c7417a35d5c2624161bd2fe8de8a41a362128:3c1093f9193bd72946c779536b4d5415b6f87f3ac6beb77ef754ee9ec8cf2e7a:f49e783cdb24e70d7e791830447a334b10b0670a060b37f650d7e48230f844f5:736b696c6c732f6161726f6e2d68652d7a68752f636f6d70657469746f722d616e616c79736973:025a0f0c8696a76c9e56f1b3736941d6","risk_level":"safe","is_blocked":false,"safe_to_publish":true,"analysis_status":"ok","agent_auto_install_policy":"allowed","manual_install_policy":"allowed","summary":"Two findings are confirmed: line 48 instructs execution of a local Firecrawl connector that performs network requests against a supplied target. The remaining 27 findings are Markdown code fences, inline identifiers, repository links, or scoped output paths and do not demonstrate shell execution or path traversal.","remediation":[{"issue":"The workflow instructs the agent to execute a repository-provided Python connector.","severity":"medium","suggestion":"Require explicit user confirmation, verify the connector source, and invoke it with a fixed executable plus a structured argument list."},{"issue":"The connector retrieves a user-supplied competitor URL over the network.","severity":"low","suggestion":"Allow only HTTP and HTTPS public destinations, block private and link-local addresses, and retain robots.txt enforcement."}],"risk_factor_evidence":[{"factor":"external_commands","evidence":[{"file":"references/analysis-templates.md","line_end":139,"line_start":117},{"file":"SKILL.md","line_end":24,"line_start":22},{"file":"SKILL.md","line_end":26,"line_start":24},{"file":"SKILL.md","line_end":28,"line_start":26},{"file":"SKILL.md","line_end":32,"line_start":28},{"file":"SKILL.md","line_end":36,"line_start":32},{"file":"SKILL.md","line_end":36,"line_start":36},{"file":"SKILL.md","line_end":48,"line_start":48},{"file":"SKILL.md","line_end":93,"line_start":54},{"file":"SKILL.md","line_end":95,"line_start":93},{"file":"SKILL.md","line_end":99,"line_start":95},{"file":"SKILL.md","line_end":101,"line_start":99},{"file":"SKILL.md","line_end":105,"line_start":101},{"file":"SKILL.md","line_end":107,"line_start":105},{"file":"SKILL.md","line_end":111,"line_start":107},{"file":"SKILL.md","line_end":111,"line_start":111}]},{"factor":"network","evidence":[{"file":"SKILL.md","line_end":48,"line_start":48},{"file":"SKILL.md","line_end":10,"line_start":10},{"file":"SKILL.md","line_end":13,"line_start":13}]},{"factor":"filesystem","evidence":[{"file":"SKILL.md","line_end":38,"line_start":38},{"file":"SKILL.md","line_end":42,"line_start":42},{"file":"SKILL.md","line_end":46,"line_start":46},{"file":"SKILL.md","line_end":48,"line_start":48},{"file":"SKILL.md","line_end":54,"line_start":54},{"file":"SKILL.md","line_end":85,"line_start":85},{"file":"SKILL.md","line_end":89,"line_start":89},{"file":"SKILL.md","line_end":111,"line_start":111},{"file":"SKILL.md","line_end":119,"line_start":119},{"file":"SKILL.md","line_end":123,"line_start":123}]}],"critical_findings":[],"high_findings":[],"medium_findings":[{"title":"Ruby/shell backtick execution","locations":[{"file":"SKILL.md","line_end":48,"line_start":48}],"confidence":0.97,"description":"**Zero-dependency competitor fetch (keyless)**: `python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/connectors/f","review_kind":"capability","source_category":"external_commands","source_severity":"medium","confidence_reasoning":"Line 48 explicitly instructs the agent to run python3 with a repository connector and a supplied target. This is real external command execution, even though it supports the stated workflow."}],"low_findings":[{"title":"Fetch API call","locations":[{"file":"SKILL.md","line_end":48,"line_start":48}],"confidence":0.98,"description":"**Zero-dependency competitor fetch (keyless)**: `python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/connectors/f","review_kind":"capability","source_category":"network","source_severity":"low","confidence_reasoning":"Line 48 documents a Firecrawl connector that scrapes, maps, or searches remote sites using a supplied target. This is intentional outbound network access."}],"dangerous_patterns":[],"files_scanned":5,"total_lines":537,"audit_model":"codex","audited_at":"2026-07-12T11:16:26.574+00:00","created_at":"2026-07-12T23:00:04.840144+00:00","static_findings":[{"id":"external_commands:references/analysis-templates.md:117:ruby-shell-backtick-execution","file":"references/analysis-templates.md","pattern":"Ruby/shell backtick execution","snippet":"For domain-level comparison, run `domain-authority-auditor` and add the CITE score row here when ava","category":"external_commands","line_end":139,"severity":"medium","line_start":117},{"id":"external_commands:SKILL.md:22:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":24,"severity":"medium","line_start":22},{"id":"external_commands:SKILL.md:24:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":26,"severity":"medium","line_start":24},{"id":"external_commands:SKILL.md:26:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":28,"severity":"medium","line_start":26},{"id":"external_commands:SKILL.md:28:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":32,"severity":"medium","line_start":28},{"id":"external_commands:SKILL.md:32:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Expected output**: a prioritized competitor brief plus the standard handoff summary for `memory/re","category":"external_commands","line_end":36,"severity":"medium","line_start":32},{"id":"external_commands:SKILL.md:36:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- **Promotes**: durable competitor facts, keyword priorities, entity candidates, and pending strateg","category":"external_commands","line_end":36,"severity":"medium","line_start":36},{"id":"external_commands:SKILL.md:48:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"**Zero-dependency competitor fetch (keyless)**: `python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/connectors/f","category":"external_commands","line_end":48,"severity":"medium","line_start":48},{"id":"external_commands:SKILL.md:54:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"1. No competitors named and none inferable from `CLAUDE.md`, prior research, or the user's niche → a","category":"external_commands","line_end":93,"severity":"medium","line_start":54},{"id":"external_commands:SKILL.md:93:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":95,"severity":"medium","line_start":93},{"id":"external_commands:SKILL.md:95:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":99,"severity":"medium","line_start":95},{"id":"external_commands:SKILL.md:99:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":101,"severity":"medium","line_start":99},{"id":"external_commands:SKILL.md:101:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":105,"severity":"medium","line_start":101},{"id":"external_commands:SKILL.md:105:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":107,"severity":"medium","line_start":105},{"id":"external_commands:SKILL.md:107:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":111,"severity":"medium","line_start":107},{"id":"external_commands:SKILL.md:111:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Write path: `memory/research/competitor-analysis/YYYY-MM-DD-<topic>.md`; promote durable competitor ","category":"external_commands","line_end":111,"severity":"medium","line_start":111},{"id":"network:SKILL.md:48:fetch-api-call","file":"SKILL.md","pattern":"Fetch API call","snippet":"**Zero-dependency competitor fetch (keyless)**: `python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/connectors/f","category":"network","line_end":48,"severity":"low","line_start":48},{"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:13:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"metadata: {\"author\": \"aaron-he-zhu\", \"version\": \"17.0.0\", \"discipline\": \"seo-geo\", \"phase\": \"researc","category":"network","line_end":13,"severity":"low","line_start":13},{"id":"filesystem:SKILL.md:38:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"- **Primary next skill**: [content-gap-analysis](../content-gap-analysis/SKILL.md) when the competit","category":"filesystem","line_end":38,"severity":"high","line_start":38},{"id":"filesystem:SKILL.md:42: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":42,"severity":"high","line_start":42},{"id":"filesystem:SKILL.md:46:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"Optional integrations: ~~SEO tool, ~~analytics, ~~AI monitor. Without tools, ask for competitor URLs","category":"filesystem","line_end":46,"severity":"high","line_start":46},{"id":"filesystem:SKILL.md:48:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"**Zero-dependency competitor fetch (keyless)**: `python3 \"${CLAUDE_PLUGIN_ROOT}/scripts/connectors/f","category":"filesystem","line_end":48,"severity":"high","line_start":48},{"id":"filesystem:SKILL.md:54:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"1. No competitors named and none inferable from `CLAUDE.md`, prior research, or the user's niche → a","category":"filesystem","line_end":54,"severity":"high","line_start":54},{"id":"filesystem:SKILL.md:85:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"For a pairwise topic-coverage gap map (\"content [competitor] has that I don't, sorted by traffic pot","category":"filesystem","line_end":85,"severity":"high","line_start":85},{"id":"filesystem:SKILL.md:89:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"When a competitor invests in video, benchmark their YouTube outliers (views >=2x their channel avera","category":"filesystem","line_end":89,"severity":"high","line_start":89},{"id":"filesystem:SKILL.md:111:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"Write path: `memory/research/competitor-analysis/YYYY-MM-DD-<topic>.md`; promote durable competitor ","category":"filesystem","line_end":111,"severity":"high","line_start":111},{"id":"filesystem:SKILL.md:119:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"- [platforms/youtube.md](../../../references/platforms/youtube.md) — YouTube outlier and title-packa","category":"filesystem","line_end":119,"severity":"high","line_start":119},{"id":"filesystem:SKILL.md:123:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"Primary: [content-gap-analysis](../content-gap-analysis/SKILL.md). Also: [serp-analysis](../serp-ana","category":"filesystem","line_end":123,"severity":"high","line_start":123}],"finding_verdicts":[{"id":"external_commands:references/analysis-templates.md:117:ruby-shell-backtick-execution","reason":"Line 117 places the skill name domain-authority-auditor in Markdown inline code. It contains no shell expression or executable command.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:22:ruby-shell-backtick-execution","reason":"Line 22 is the opening fence for a Markdown prompt example. It does not execute Ruby or shell code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:24:ruby-shell-backtick-execution","reason":"Line 24 closes a Markdown prompt example. The backticks are formatting syntax, not command substitution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:26:ruby-shell-backtick-execution","reason":"Line 26 opens a Markdown prompt example. No executable code appears in this span.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:28:ruby-shell-backtick-execution","reason":"Line 28 closes a Markdown prompt example. The following text is a section heading, not shell input.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:32:ruby-shell-backtick-execution","reason":"The span describes expected output and formats memory/research as inline code. It provides no external command.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:36:ruby-shell-backtick-execution","reason":"Line 36 lists fixed memory paths in Markdown inline code. It does not invoke a shell or interpreter.","verdict":"false_positive","confidence":0.98},{"id":"external_commands:SKILL.md:48:ruby-shell-backtick-execution","reason":"Line 48 explicitly instructs the agent to run python3 with a repository connector and a supplied target. This is real external command execution, even though it supports the stated workflow.","verdict":"confirmed","severity":"medium","confidence":0.97},{"id":"external_commands:SKILL.md:54:ruby-shell-backtick-execution","reason":"The span contains inline filenames, Markdown links, prose instructions, and a fenced prompt example. It does not contain an executable shell command.","verdict":"false_positive","confidence":0.97},{"id":"external_commands:SKILL.md:93:ruby-shell-backtick-execution","reason":"Lines 93 through 95 are a fenced natural-language prompt example. The fence is not shell backtick execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:95:ruby-shell-backtick-execution","reason":"Line 95 closes a natural-language prompt example. No command is executed.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:99:ruby-shell-backtick-execution","reason":"Lines 99 through 101 format a natural-language SERP question. They contain no shell expression.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:101:ruby-shell-backtick-execution","reason":"Line 101 closes a Markdown example block. It is formatting syntax only.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:105:ruby-shell-backtick-execution","reason":"Lines 105 through 107 format a natural-language historical analysis prompt. They do not invoke an external command.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:107:ruby-shell-backtick-execution","reason":"Line 107 closes a Markdown prompt block. The surrounding save instructions are prose, not shell code.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:111:ruby-shell-backtick-execution","reason":"Line 111 formats fixed output paths as inline code. It requests a document write but contains no external command.","verdict":"false_positive","confidence":0.98},{"id":"network:SKILL.md:48:fetch-api-call","reason":"Line 48 documents a Firecrawl connector that scrapes, maps, or searches remote sites using a supplied target. This is intentional outbound network access.","verdict":"confirmed","severity":"low","confidence":0.98},{"id":"network:SKILL.md:10:hardcoded-url","reason":"Line 10 is repository homepage metadata. It does not instruct the agent to contact the URL or transmit data.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:13:hardcoded-url","reason":"Line 13 repeats the public repository homepage inside metadata. It is attribution metadata, not an operational network endpoint.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:38:path-traversal-sequence","reason":"Line 38 is a relative Markdown link to an adjacent skill document. It does not use user input or perform a filesystem traversal operation.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:42:path-traversal-sequence","reason":"Line 42 is a relative Markdown documentation link. The parent-directory segments resolve a repository reference and are not an executed path.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:46:path-traversal-sequence","reason":"Line 46 links to CONNECTORS.md using a fixed repository-relative path. It does not read an arbitrary or user-controlled file.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:48:path-traversal-sequence","reason":"Line 48 uses CLAUDE_PLUGIN_ROOT for a fixed connector path and fixed relative documentation links. No user-controlled filesystem path or traversal sequence is present.","verdict":"false_positive","confidence":0.96},{"id":"filesystem:SKILL.md:54:path-traversal-sequence","reason":"Line 54 mentions CLAUDE.md and links to an adjacent skill document. It neither constructs nor accesses a user-controlled traversal path.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:SKILL.md:85:path-traversal-sequence","reason":"Line 85 is a Markdown handoff link to an adjacent skill. It is documentation navigation, not filesystem traversal.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:89:path-traversal-sequence","reason":"Line 89 contains a fixed relative Markdown link to a YouTube reference document. No file operation is specified.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:111:path-traversal-sequence","reason":"Line 111 names a scoped memory output path and a fixed documentation link. The write target has no parent-directory traversal or user-controlled directory component.","verdict":"false_positive","confidence":0.98},{"id":"filesystem:SKILL.md:119:path-traversal-sequence","reason":"Line 119 is a fixed repository-relative Markdown link. Parent-directory segments in a documentation link do not establish a traversal vulnerability.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:123:path-traversal-sequence","reason":"Line 123 contains fixed Markdown links to related skills. It does not accept a path value or direct a filesystem read outside the repository.","verdict":"false_positive","confidence":0.99}],"semantic_findings":[],"subject_marketplace_commit_sha":"d71c7417a35d5c2624161bd2fe8de8a41a362128","subject_content_hash":"3c1093f9193bd72946c779536b4d5415b6f87f3ac6beb77ef754ee9ec8cf2e7a","subject_tree_hash":"f49e783cdb24e70d7e791830447a334b10b0670a060b37f650d7e48230f844f5","subject_plugin_path":"skills/aaron-he-zhu/competitor-analysis","audit_payload_hash":"025a0f0c8696a76c9e56f1b3736941d6","confirmed_risk_level":null,"scanner_version":null,"policy_version":null,"subject":{"marketplaceCommitSha":"d71c7417a35d5c2624161bd2fe8de8a41a362128","contentHash":"3c1093f9193bd72946c779536b4d5415b6f87f3ac6beb77ef754ee9ec8cf2e7a","treeHash":"f49e783cdb24e70d7e791830447a334b10b0670a060b37f650d7e48230f844f5","pluginPath":"skills/aaron-he-zhu/competitor-analysis","auditPayloadHash":"025a0f0c8696a76c9e56f1b3736941d6"},"scannerVersion":null,"policyVersion":null},"auditTranslation":null,"localization":{"requestedLocale":"en","contentLocale":"en","availableLocales":["en","zh-hans"],"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}}