{"data":{"skill":{"slug":"tahodev-taiwan-oil-price","name":"taiwan-oil-price","icon":"📦","repo":"https://github.com/tahodev/baodao-skill/tree/3ce4b58e4525f5a66390e1236b6d38702790225a/taiwan-oil-price","status":"approved","author":"tahodev","authorVersion":null,"skillstoreRevision":1},"audit":{"id":"fbd86127-499b-4b20-8c6c-cdc19e7fbe00","skill_id":"747c5348-2ebe-4b73-8161-a6feabc97bf8","version":1,"content_hash":"v3:2aab20a3878daa05021884e089a7dd7739e08581:e5b5b28bfb5758376e97eb6b88bd2865185bcd0021e00abadc3fc40cfcfc8e14:64e7bd1aafa793d68a6c07621819090b0f8b4133ff5c26f0a682028bf7497c8b:736b696c6c732f7461686f6465762f74616977616e2d6f696c2d7072696365:54e7a0754d7517b295a55ddae555018a","risk_level":"safe","is_blocked":false,"safe_to_publish":true,"analysis_status":"ok","agent_auto_install_policy":"allowed","manual_install_policy":"allowed","summary":"Markdown formatting, public CPC URLs, Python HTML decoding, and readable multilingual text explain 18 false positives. Four temporary-file findings expose overwrite or data-tampering risks through predictable shared paths. No evidence found of prompt injection, credential access, or data exfiltration.","remediation":[{"issue":"Downloads write to predictable shared temporary files, which can follow attacker-created symlinks or collide with concurrent runs.","severity":"medium","suggestion":"Create a private temporary directory with mktemp -d, download inside it, and remove it after processing."},{"issue":"Parsers trust predictable shared files that another local process may replace or modify.","severity":"medium","suggestion":"Read only files from the same private temporary directory, or pass downloaded data directly to parsers without shared intermediate files."}],"risk_factor_evidence":[{"factor":"external_commands","evidence":[{"file":"SKILL.md","line_end":19,"line_start":19},{"file":"SKILL.md","line_end":26,"line_start":24},{"file":"SKILL.md","line_end":28,"line_start":26},{"file":"SKILL.md","line_end":28,"line_start":28},{"file":"SKILL.md","line_end":32,"line_start":30},{"file":"SKILL.md","line_end":38,"line_start":32},{"file":"SKILL.md","line_end":44,"line_start":38},{"file":"SKILL.md","line_end":46,"line_start":44},{"file":"SKILL.md","line_end":48,"line_start":46},{"file":"SKILL.md","line_end":58,"line_start":48},{"file":"SKILL.md","line_end":68,"line_start":58},{"file":"SKILL.md","line_end":68,"line_start":68},{"file":"SKILL.md","line_end":72,"line_start":72}]},{"factor":"network","evidence":[{"file":"SKILL.md","line_end":25,"line_start":25},{"file":"SKILL.md","line_end":45,"line_start":45},{"file":"SKILL.md","line_end":72,"line_start":72}]},{"factor":"filesystem","evidence":[{"file":"SKILL.md","line_end":25,"line_start":25},{"file":"SKILL.md","line_end":31,"line_start":31},{"file":"SKILL.md","line_end":45,"line_start":45},{"file":"SKILL.md","line_end":50,"line_start":50}]}],"critical_findings":[],"high_findings":[],"medium_findings":[{"title":"Temp directory access","locations":[{"file":"SKILL.md","line_end":25,"line_start":25}],"confidence":0.95,"description":"curl -sm 30 'https://vipmbr.cpc.com.tw/opendata/sixtypeoillistprice' -o /tmp/oil.json","review_kind":"capability","source_category":"filesystem","source_severity":"medium","confidence_reasoning":"curl writes to the predictable shared path /tmp/oil.json without exclusive creation. A preexisting symlink can redirect writes to files writable by the caller."},{"title":"Temp directory access","locations":[{"file":"SKILL.md","line_end":31,"line_start":31}],"confidence":0.92,"description":"jq -r '.[] | select(.型別名稱==\"汽柴油零售\") | \"\\(.產品名稱) \\(.參考牌價_金額) \\(.牌價生效日期)\"' /tmp/oil.json","review_kind":"capability","source_category":"filesystem","source_severity":"medium","confidence_reasoning":"jq trusts a predictable shared temporary file without ownership or integrity checks. Local replacement or concurrent downloads can corrupt reported prices."},{"title":"Temp directory access","locations":[{"file":"SKILL.md","line_end":45,"line_start":45}],"confidence":0.95,"description":"curl -sm 30 -A 'Mozilla/5.0' 'https://www.cpc.com.tw/historyprice.aspx?n=2890' -o /tmp/cpc.html","review_kind":"capability","source_category":"filesystem","source_severity":"medium","confidence_reasoning":"curl writes to the fixed shared path /tmp/cpc.html without exclusive creation. A preexisting symlink can cause unintended overwrite under the caller's permissions."},{"title":"Temp directory access","locations":[{"file":"SKILL.md","line_end":50,"line_start":50}],"confidence":0.92,"description":"t = open('/tmp/cpc.html', encoding='utf-8', errors='replace').read()","review_kind":"capability","source_category":"filesystem","source_severity":"medium","confidence_reasoning":"Python reads a predictable shared HTML file without verifying ownership or provenance. Local file substitution or concurrent runs can inject false historical price rows."}],"low_findings":[],"dangerous_patterns":[],"files_scanned":1,"total_lines":73,"audit_model":"codex","audited_at":"2026-10-13T03:46:22.151+00:00","created_at":"2026-10-13T18:35:59.00276+00:00","static_findings":[{"id":"external_commands:SKILL.md:19:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"2. 看 `牌價生效日期` 判斷是「本週」還是「下週」價(週日中午公告次週牌價)","category":"external_commands","line_end":19,"severity":"medium","line_start":19},{"id":"external_commands:SKILL.md:24:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","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":"2026-09-20 實測:HTTP 200、約 17.5KB、51 列 JSON 陣列,不需瀏覽器 UA、免金鑰。這是中油刊登在 data.gov.tw(資料集 166537「台灣中油公司各項油品牌","category":"external_commands","line_end":28,"severity":"medium","line_start":28},{"id":"external_commands:SKILL.md:30:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":32,"severity":"medium","line_start":30},{"id":"external_commands:SKILL.md:32:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":38,"severity":"medium","line_start":32},{"id":"external_commands:SKILL.md:38:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"中油**週日中午公告次週牌價、週一零時生效**。所以週日下午到週日半夜查到的 `牌價生效日期` 會是**明天(下週)**:這是已公告的下週牌價,可以直接回答「下週會漲還是跌」——跟舊制「不能預測」不同","category":"external_commands","line_end":44,"severity":"medium","line_start":38},{"id":"external_commands:SKILL.md:44:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":46,"severity":"medium","line_start":44},{"id":"external_commands:SKILL.md:46:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":48,"severity":"medium","line_start":46},{"id":"external_commands:SKILL.md:48:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```python","category":"external_commands","line_end":58,"severity":"medium","line_start":48},{"id":"external_commands:SKILL.md:58:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":68,"severity":"medium","line_start":58},{"id":"external_commands:SKILL.md:68:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- **燃料油、天然氣、液化石油氣也在同一 JSON**:篩 `型別名稱` 取用;單位各異(公升/公秉/立方公尺),回報時帶上 `計價單位`。","category":"external_commands","line_end":68,"severity":"medium","line_start":68},{"id":"external_commands:SKILL.md:72:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"Taiwan CPC fuel prices, keyless. Primary path: official open-data JSON `https://vipmbr.cpc.com.tw/op","category":"external_commands","line_end":72,"severity":"medium","line_start":72},{"id":"network:SKILL.md:25:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"curl -sm 30 'https://vipmbr.cpc.com.tw/opendata/sixtypeoillistprice' -o /tmp/oil.json","category":"network","line_end":25,"severity":"low","line_start":25},{"id":"network:SKILL.md:45:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"curl -sm 30 -A 'Mozilla/5.0' 'https://www.cpc.com.tw/historyprice.aspx?n=2890' -o /tmp/cpc.html","category":"network","line_end":45,"severity":"low","line_start":45},{"id":"network:SKILL.md:72:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"Taiwan CPC fuel prices, keyless. Primary path: official open-data JSON `https://vipmbr.cpc.com.tw/op","category":"network","line_end":72,"severity":"low","line_start":72},{"id":"filesystem:SKILL.md:25:temp-directory-access","file":"SKILL.md","pattern":"Temp directory access","snippet":"curl -sm 30 'https://vipmbr.cpc.com.tw/opendata/sixtypeoillistprice' -o /tmp/oil.json","category":"filesystem","line_end":25,"severity":"medium","line_start":25},{"id":"filesystem:SKILL.md:31:temp-directory-access","file":"SKILL.md","pattern":"Temp directory access","snippet":"jq -r '.[] | select(.型別名稱==\"汽柴油零售\") | \"\\(.產品名稱) \\(.參考牌價_金額) \\(.牌價生效日期)\"' /tmp/oil.json","category":"filesystem","line_end":31,"severity":"medium","line_start":31},{"id":"filesystem:SKILL.md:45:temp-directory-access","file":"SKILL.md","pattern":"Temp directory access","snippet":"curl -sm 30 -A 'Mozilla/5.0' 'https://www.cpc.com.tw/historyprice.aspx?n=2890' -o /tmp/cpc.html","category":"filesystem","line_end":45,"severity":"medium","line_start":45},{"id":"filesystem:SKILL.md:50:temp-directory-access","file":"SKILL.md","pattern":"Temp directory access","snippet":"t = open('/tmp/cpc.html', encoding='utf-8', errors='replace').read()","category":"filesystem","line_end":50,"severity":"medium","line_start":50},{"id":"obfuscation:SKILL.md:53:deprecated-unescape-function","file":"SKILL.md","pattern":"Deprecated unescape function","snippet":"cells = [html.unescape(re.sub(r'<[^>]+>', '', c)).strip()","category":"obfuscation","line_end":53,"severity":"medium","line_start":53},{"id":"obfuscation:SKILL.md:1:heuristic-high-file-entropy-6-74-bits-possible-b","file":"SKILL.md","pattern":"[HEURISTIC] High file entropy (6.74 bits) - possible binary/encrypted content","snippet":"File: SKILL.md","category":"obfuscation","line_end":1,"severity":"high","line_start":1}],"finding_verdicts":[{"id":"external_commands:SKILL.md:19:ruby-shell-backtick-execution","reason":"The backticks format a field name in Markdown instructions about effective dates. No shell substitution or Ruby execution occurs.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:24:ruby-shell-backtick-execution","reason":"These backticks delimit a Markdown bash example containing a fixed CPC download command. Temporary-file risks are adjudicated separately.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:26:ruby-shell-backtick-execution","reason":"The matched backticks close a Markdown code fence. They are not an executable shell or Ruby expression.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:28:ruby-shell-backtick-execution","reason":"Inline backticks mark JSON field names in explanatory prose. The paragraph contains no executable backtick substitution.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:30:ruby-shell-backtick-execution","reason":"The backticks open a Markdown example using jq with a fixed filter. Downloaded values are parsed as data, not shell commands.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:32:ruby-shell-backtick-execution","reason":"The match is a closing Markdown code fence before explanatory prose. No Ruby or shell backtick execution is present.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:38:ruby-shell-backtick-execution","reason":"Backticks format an effective-date field in a paragraph explaining announcement timing. They do not execute the field name.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:44:ruby-shell-backtick-execution","reason":"The match opens a Markdown bash example with a fixed public-history download. The predictable output path is assessed under filesystem findings.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:46:ruby-shell-backtick-execution","reason":"These backticks close the download example in Markdown. No executable command substitution appears.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:48:ruby-shell-backtick-execution","reason":"The backticks delimit Python source that reads and extracts HTML table text. The source contains no shell invocation or dynamic code execution.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:58:ruby-shell-backtick-execution","reason":"This is a closing Markdown code fence followed by documented observations and limitations. It does not execute anything.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:68:ruby-shell-backtick-execution","reason":"Inline backticks identify product-type and pricing-unit fields in a reporting instruction. No shell or Ruby code is invoked.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:72:ruby-shell-backtick-execution","reason":"Backticks format an official URL and JSON field names within the English summary. The text contains no executable backtick expression.","verdict":"false_positive","confidence":1},{"id":"network:SKILL.md:25:hardcoded-url","reason":"The fixed HTTPS request retrieves public fuel-price data from CPC, matching the skill purpose. No credentials or local file contents are transmitted.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:45:hardcoded-url","reason":"The fixed CPC HTTPS URL retrieves a public price-history page with a generic browser user agent. No sensitive payload or upload is present.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:72:hardcoded-url","reason":"The URL is documentation for the same public CPC data source used in the workflow. No additional destination or exfiltration instruction appears.","verdict":"false_positive","confidence":1},{"id":"filesystem:SKILL.md:25:temp-directory-access","reason":"curl writes to the predictable shared path /tmp/oil.json without exclusive creation. A preexisting symlink can redirect writes to files writable by the caller.","verdict":"confirmed","confidence":0.95},{"id":"filesystem:SKILL.md:31:temp-directory-access","reason":"jq trusts a predictable shared temporary file without ownership or integrity checks. Local replacement or concurrent downloads can corrupt reported prices.","verdict":"confirmed","confidence":0.92},{"id":"filesystem:SKILL.md:45:temp-directory-access","reason":"curl writes to the fixed shared path /tmp/cpc.html without exclusive creation. A preexisting symlink can cause unintended overwrite under the caller's permissions.","verdict":"confirmed","confidence":0.95},{"id":"filesystem:SKILL.md:50:temp-directory-access","reason":"Python reads a predictable shared HTML file without verifying ownership or provenance. Local file substitution or concurrent runs can inject false historical price rows.","verdict":"confirmed","confidence":0.92},{"id":"obfuscation:SKILL.md:53:deprecated-unescape-function","reason":"This is Python's standard html.unescape function for decoding HTML entities after tag removal. It neither executes input nor conceals code.","verdict":"false_positive","confidence":1},{"id":"obfuscation:SKILL.md:1:heuristic-high-file-entropy-6-74-bits-possible-b","reason":"The complete file is readable Chinese and English Markdown with short transparent command examples. No evidence found of binary, encrypted, or hidden executable content.","verdict":"false_positive","confidence":0.99}],"semantic_findings":[],"subject_marketplace_commit_sha":"2aab20a3878daa05021884e089a7dd7739e08581","subject_content_hash":"e5b5b28bfb5758376e97eb6b88bd2865185bcd0021e00abadc3fc40cfcfc8e14","subject_tree_hash":"64e7bd1aafa793d68a6c07621819090b0f8b4133ff5c26f0a682028bf7497c8b","subject_plugin_path":"skills/tahodev/taiwan-oil-price","audit_payload_hash":"54e7a0754d7517b295a55ddae555018a","confirmed_risk_level":"safe","scanner_version":"3.0.0","policy_version":"skillstore-security-audit-policy-v1","subject":{"marketplaceCommitSha":"2aab20a3878daa05021884e089a7dd7739e08581","contentHash":"e5b5b28bfb5758376e97eb6b88bd2865185bcd0021e00abadc3fc40cfcfc8e14","treeHash":"64e7bd1aafa793d68a6c07621819090b0f8b4133ff5c26f0a682028bf7497c8b","pluginPath":"skills/tahodev/taiwan-oil-price","auditPayloadHash":"54e7a0754d7517b295a55ddae555018a"},"scannerVersion":"3.0.0","policyVersion":"skillstore-security-audit-policy-v1"},"auditTranslation":null,"localization":{"requestedLocale":"en","contentLocale":"en","availableLocales":["en"],"fallbackToEnglish":false},"attestation":{"availability":"issued","url":"/api/skills/tahodev-taiwan-oil-price/audits/1/attestation","status":"active"},"trust":{"publicState":"public","auditState":"complete","auditCurrentness":null,"confirmedRiskLevel":"safe","confirmedFindingCount":0,"capabilityReviewCount":4,"needsReviewCount":0,"falsePositiveCount":0,"agentAutoInstallPolicy":"allowed","manualInstallPolicy":"allowed","artifactSignatureState":"available","attestationState":"active","verificationState":"not_verified"},"isLatest":true}}