{"data":{"skill":{"slug":"tahodev-air-quality","name":"air-quality","icon":"📦","repo":"https://github.com/tahodev/kurashi-skill/tree/09cb7f9eac85f0c85633cce08328a1a57854a94f/air-quality","status":"approved","author":"tahodev","authorVersion":null,"skillstoreRevision":1},"audit":{"id":"8b3b7036-d20f-45d2-b043-dd690b1c4591","skill_id":"b18814ab-f755-46ec-bcfb-9227a7f80da9","version":1,"content_hash":"v3:7f17813fb6af1acc7d8fd3fb5f05480f5be52783:22982047e3605eff0eea6b27d7bd6f6a1df36a218018c692e66f1d57c8494a0b:d55a2224ee5844c71ba6c45fd2ff11378477399c7c691dfe42dd6e4e828e27ec:736b696c6c732f7461686f6465762f6169722d7175616c697479:9b90c5cb8b940e170019ca7ccfb66a10","risk_level":"safe","is_blocked":false,"safe_to_publish":true,"analysis_status":"ok","agent_auto_install_policy":"allowed","manual_install_policy":"allowed","summary":"All 70 static findings are false positives after reviewing their source context. Network requests retrieve public AEROS data, and filesystem operations maintain a dedicated CSV cache. No evidence found of credential access, data exfiltration, executable obfuscation, or prompt injection.","remediation":[],"risk_factor_evidence":[{"factor":"network","evidence":[{"file":"lookup.py","line_end":17,"line_start":17},{"file":"lookup.py","line_end":23,"line_start":23},{"file":"lookup.py","line_end":32,"line_start":32},{"file":"lookup.py","line_end":12,"line_start":12},{"file":"lookup.py","line_end":18,"line_start":18},{"file":"lookup.py","line_end":19,"line_start":19},{"file":"lookup.py","line_end":14,"line_start":14},{"file":"SKILL.md","line_end":20,"line_start":20},{"file":"SKILL.md","line_end":21,"line_start":21},{"file":"SKILL.md","line_end":22,"line_start":22},{"file":"SKILL.md","line_end":23,"line_start":23},{"file":"SKILL.md","line_end":24,"line_start":24},{"file":"SKILL.md","line_end":25,"line_start":25},{"file":"SKILL.md","line_end":30,"line_start":30},{"file":"SKILL.md","line_end":54,"line_start":54},{"file":"SKILL.md","line_end":64,"line_start":64},{"file":"SKILL.md","line_end":76,"line_start":76}]},{"factor":"filesystem","evidence":[{"file":"lookup.py","line_end":9,"line_start":9},{"file":"lookup.py","line_end":15,"line_start":15},{"file":"lookup.py","line_end":9,"line_start":9},{"file":"lookup.py","line_end":15,"line_start":15},{"file":"lookup.py","line_end":35,"line_start":35},{"file":"lookup.py","line_end":28,"line_start":28},{"file":"SKILL.md","line_end":83,"line_start":83}]},{"factor":"external_commands","evidence":[{"file":"SKILL.md","line_end":12,"line_start":12},{"file":"SKILL.md","line_end":20,"line_start":20},{"file":"SKILL.md","line_end":21,"line_start":21},{"file":"SKILL.md","line_end":22,"line_start":22},{"file":"SKILL.md","line_end":23,"line_start":23},{"file":"SKILL.md","line_end":24,"line_start":24},{"file":"SKILL.md","line_end":25,"line_start":25},{"file":"SKILL.md","line_end":31,"line_start":29},{"file":"SKILL.md","line_end":33,"line_start":31},{"file":"SKILL.md","line_end":33,"line_start":33},{"file":"SKILL.md","line_end":39,"line_start":37},{"file":"SKILL.md","line_end":41,"line_start":39},{"file":"SKILL.md","line_end":43,"line_start":41},{"file":"SKILL.md","line_end":43,"line_start":43},{"file":"SKILL.md","line_end":49,"line_start":45},{"file":"SKILL.md","line_end":53,"line_start":49},{"file":"SKILL.md","line_end":55,"line_start":53},{"file":"SKILL.md","line_end":57,"line_start":55},{"file":"SKILL.md","line_end":57,"line_start":57},{"file":"SKILL.md","line_end":63,"line_start":61},{"file":"SKILL.md","line_end":65,"line_start":63},{"file":"SKILL.md","line_end":67,"line_start":65},{"file":"SKILL.md","line_end":67,"line_start":67},{"file":"SKILL.md","line_end":68,"line_start":68},{"file":"SKILL.md","line_end":69,"line_start":69},{"file":"SKILL.md","line_end":71,"line_start":71},{"file":"SKILL.md","line_end":77,"line_start":75},{"file":"SKILL.md","line_end":79,"line_start":77},{"file":"SKILL.md","line_end":85,"line_start":79},{"file":"SKILL.md","line_end":85,"line_start":85},{"file":"SKILL.md","line_end":87,"line_start":86}]}],"critical_findings":[],"high_findings":[],"medium_findings":[],"low_findings":[],"dangerous_patterns":[],"files_scanned":4,"total_lines":223,"audit_model":"codex","audited_at":"2026-10-13T02:52:29.971+00:00","created_at":"2026-10-13T18:59:03.546383+00:00","static_findings":[{"id":"network:lookup.py:17:fetch-api-call","file":"lookup.py","pattern":"Fetch API call","snippet":"def fetch(url, timeout=60):","category":"network","line_end":17,"severity":"low","line_start":17},{"id":"network:lookup.py:23:fetch-api-call","file":"lookup.py","pattern":"Fetch API call","snippet":"meta = json.loads(fetch(BASE + \"/data/map/kyokuNoudo/metadata.json\").decode(\"utf-8\"))","category":"network","line_end":23,"severity":"low","line_start":23},{"id":"network:lookup.py:32:fetch-api-call","file":"lookup.py","pattern":"Fetch API call","snippet":"raw = fetch(url)","category":"network","line_end":32,"severity":"low","line_start":32},{"id":"network:lookup.py:12:python-http-libraries","file":"lookup.py","pattern":"Python HTTP libraries","snippet":"import argparse, csv, io, json, os, sys, urllib.request","category":"network","line_end":12,"severity":"low","line_start":12},{"id":"network:lookup.py:18:python-http-libraries","file":"lookup.py","pattern":"Python HTTP libraries","snippet":"req = urllib.request.Request(url, headers={\"User-Agent\": \"kurashi-skill/air-quality\"})","category":"network","line_end":18,"severity":"low","line_start":18},{"id":"network:lookup.py:19:python-http-libraries","file":"lookup.py","pattern":"Python HTTP libraries","snippet":"with urllib.request.urlopen(req, timeout=timeout) as r:","category":"network","line_end":19,"severity":"low","line_start":19},{"id":"network:lookup.py:14:hardcoded-url","file":"lookup.py","pattern":"Hardcoded URL","snippet":"BASE = \"https://soramame.env.go.jp\"","category":"network","line_end":14,"severity":"low","line_start":14},{"id":"filesystem:lookup.py:9:hidden-file-in-home-directory","file":"lookup.py","pattern":"Hidden file in home directory","snippet":"外部パッケージ不要。CSVは ~/.cache/kurashi-skill/air-quality/ に保存し、","category":"filesystem","line_end":9,"severity":"high","line_start":9},{"id":"filesystem:lookup.py:15:hidden-file-in-home-directory","file":"lookup.py","pattern":"Hidden file in home directory","snippet":"CACHE = os.path.expanduser(\"~/.cache/kurashi-skill/air-quality\")","category":"filesystem","line_end":15,"severity":"high","line_start":15},{"id":"filesystem:lookup.py:9:hidden-file-access","file":"lookup.py","pattern":"Hidden file access","snippet":"外部パッケージ不要。CSVは ~/.cache/kurashi-skill/air-quality/ に保存し、","category":"filesystem","line_end":9,"severity":"medium","line_start":9},{"id":"filesystem:lookup.py:15:hidden-file-access","file":"lookup.py","pattern":"Hidden file access","snippet":"CACHE = os.path.expanduser(\"~/.cache/kurashi-skill/air-quality\")","category":"filesystem","line_end":15,"severity":"medium","line_start":15},{"id":"filesystem:lookup.py:35:python-file-write-append","file":"lookup.py","pattern":"Python file write/append","snippet":"open(path, \"wb\").write(raw)","category":"filesystem","line_end":35,"severity":"medium","line_start":35},{"id":"filesystem:lookup.py:28:python-os-file-operations","file":"lookup.py","pattern":"Python os file operations","snippet":"os.makedirs(CACHE, exist_ok=True)","category":"filesystem","line_end":28,"severity":"medium","line_start":28},{"id":"sensitive:lookup.py:14:environment-file-access","file":"lookup.py","pattern":"Environment file access","snippet":"BASE = \"https://soramame.env.go.jp\"","category":"sensitive","line_end":14,"severity":"high","line_start":14},{"id":"sensitive:lookup.py:74:certificate-key-files","file":"lookup.py","pattern":"Certificate/key files","snippet":"hit = select_hits(hdr, data, a.item, keyword=a.keyword, pref=a.pref, station=a.station)","category":"sensitive","line_end":74,"severity":"high","line_start":74},{"id":"external_commands:SKILL.md:12:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"環境省の大気汚染物質広域監視システム(AEROS、通称そらまめくん)が公開する測定値(速報値)を読むスキル。公式のAPI利用者向けコーナーが `soramame/api/data_search` を開","category":"external_commands","line_end":12,"severity":"medium","line_start":12},{"id":"external_commands:SKILL.md:20:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| 全国の最新1時間値(全測定局) | `https://soramame.env.go.jp/data/sokutei/noudoAll/{YYYY}/{MM}/{DD}/{HH}.csv` |","category":"external_commands","line_end":20,"severity":"medium","line_start":20},{"id":"external_commands:SKILL.md:21:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| 測定局ごとの今日の値 | `https://soramame.env.go.jp/data/sokutei/NoudoTime/{SKT_CD}/today.csv` |","category":"external_commands","line_end":21,"severity":"medium","line_start":21},{"id":"external_commands:SKILL.md:22:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| 測定局ごとの直近7日 | `https://soramame.env.go.jp/data/sokutei/NoudoTime/{SKT_CD}/7day.csv` |","category":"external_commands","line_end":22,"severity":"medium","line_start":22},{"id":"external_commands:SKILL.md:23:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| 公式API(都道府県別・月次履歴JSON) | `https://soramame.env.go.jp/soramame/api/data_search?Start_YM={yyyymm}&TDF","category":"external_commands","line_end":23,"severity":"medium","line_start":23},{"id":"external_commands:SKILL.md:24:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| PM2.5注意喚起エリア | `https://soramame.env.go.jp/data/sokutei/pm25/alert.csv` |","category":"external_commands","line_end":24,"severity":"medium","line_start":24},{"id":"external_commands:SKILL.md:25:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| 最新データ時刻(地図用メタ) | `https://soramame.env.go.jp/data/map/kyokuNoudo/metadata.json` |","category":"external_commands","line_end":25,"severity":"medium","line_start":25},{"id":"external_commands:SKILL.md:29:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":31,"severity":"medium","line_start":29},{"id":"external_commands:SKILL.md:31:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":33,"severity":"medium","line_start":31},{"id":"external_commands:SKILL.md:33:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"最新の時は `metadata.json` の `latest`(2026-09-26実測: `2026/09/26 01:00:00`)から組み立てる。時は2桁の `01`〜`24` 表記に注意(0","category":"external_commands","line_end":33,"severity":"medium","line_start":33},{"id":"external_commands:SKILL.md:37:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":39,"severity":"medium","line_start":37},{"id":"external_commands:SKILL.md:39:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":41,"severity":"medium","line_start":39},{"id":"external_commands:SKILL.md:41:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"測定局名称・住所・局種別(一般局/自排局)・市区町村名を含むので、このCSVだけで局の検索もできる。内訳実測: 一般局1,244、自排局349。緯度経度の列はない(座標での最寄り検索はこのCSVではで","category":"external_commands","line_end":43,"severity":"medium","line_start":41},{"id":"external_commands:SKILL.md:43:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"同梱の `lookup.py` は、`metadata.json` から最新時刻を引き、noudoAll CSVをキャッシュしつつ、局名・住所・市区町村名の部分一致や都道府県コードで絞り込んで項目値の","category":"external_commands","line_end":43,"severity":"medium","line_start":43},{"id":"external_commands:SKILL.md:45:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":49,"severity":"medium","line_start":45},{"id":"external_commands:SKILL.md:49:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":53,"severity":"medium","line_start":49},{"id":"external_commands:SKILL.md:53:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":55,"severity":"medium","line_start":53},{"id":"external_commands:SKILL.md:55:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":57,"severity":"medium","line_start":55},{"id":"external_commands:SKILL.md:57:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"列: `年,月,日,時,SO2,NO,NO2,NOX,CO,OX,NMHC,CH4,THC,SPM,PM2.5,SP,WD,WS,TEMP,HUM`。2026-09-26実測(東京の13101010)","category":"external_commands","line_end":57,"severity":"medium","line_start":57},{"id":"external_commands:SKILL.md:61:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"公式のAPI説明ページ(`/data/apiManual/3.html`)が案内するJSON API。月単位・都道府県単位。","category":"external_commands","line_end":63,"severity":"medium","line_start":61},{"id":"external_commands:SKILL.md:63:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":65,"severity":"medium","line_start":63},{"id":"external_commands:SKILL.md:65:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":67,"severity":"medium","line_start":65},{"id":"external_commands:SKILL.md:67:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `Start_YM` 必須(yyyymm)、`End_YM` 省略で現在の年月","category":"external_commands","line_end":67,"severity":"medium","line_start":67},{"id":"external_commands:SKILL.md:68:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `TDFKN_CD` 必須(01〜47)、`SKT_CD` 複数可(カンマ区切り)","category":"external_commands","line_end":68,"severity":"medium","line_start":68},{"id":"external_commands:SKILL.md:69:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- `REQUEST_DATA`: `SO2,NO,NO2,NOX,CO,OX,NMHC,CH4,THC,SPM,PM2_5,SP,WD,WS,TEMP,HUM`(PM2.5だけ `PM2_5` とア","category":"external_commands","line_end":69,"severity":"medium","line_start":69},{"id":"external_commands:SKILL.md:71:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"返り値は `[{\"SKT_CD\":\"13101010\",\"SKT_DATE\":\"2026/09/01\",\"SKT_TIME\":\"01\",\"PM2_5\":\"3\",\"TEMP\":\"24.3\"}, ...]","category":"external_commands","line_end":71,"severity":"medium","line_start":71},{"id":"external_commands:SKILL.md:75:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":77,"severity":"medium","line_start":75},{"id":"external_commands:SKILL.md:77:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":79,"severity":"medium","line_start":77},{"id":"external_commands:SKILL.md:79:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"`都道府県コード,都道府県名,地域コード,注意喚起実施日時,注意喚起解除日時`。2026-09-26実測: 200、ヘッダ行だけ(発表中の注意喚起なし)。空はエラーではなく「現在なし」。","category":"external_commands","line_end":85,"severity":"medium","line_start":79},{"id":"external_commands:SKILL.md:85:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- **noudoAll の時刻違いで404にならないがSPAページが返る**: 存在しないURLはSPAのシェルHTML(約2.6KB)が200で返る。**受け取ったら先頭行が `測定局コード` で","category":"external_commands","line_end":85,"severity":"medium","line_start":85},{"id":"external_commands:SKILL.md:86:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"- **`-` や空欄**: その局ではその項目を測っていない/未送信。推測で埋めない。測定局が少ない項目(例: PM2.5は約3割の局が未測定)は「この局では測定していない」と伝える。","category":"external_commands","line_end":87,"severity":"medium","line_start":86},{"id":"network:SKILL.md:20:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"| 全国の最新1時間値(全測定局) | `https://soramame.env.go.jp/data/sokutei/noudoAll/{YYYY}/{MM}/{DD}/{HH}.csv` |","category":"network","line_end":20,"severity":"low","line_start":20},{"id":"network:SKILL.md:21:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"| 測定局ごとの今日の値 | `https://soramame.env.go.jp/data/sokutei/NoudoTime/{SKT_CD}/today.csv` |","category":"network","line_end":21,"severity":"low","line_start":21},{"id":"network:SKILL.md:22:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"| 測定局ごとの直近7日 | `https://soramame.env.go.jp/data/sokutei/NoudoTime/{SKT_CD}/7day.csv` |","category":"network","line_end":22,"severity":"low","line_start":22},{"id":"network:SKILL.md:23:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"| 公式API(都道府県別・月次履歴JSON) | `https://soramame.env.go.jp/soramame/api/data_search?Start_YM={yyyymm}&TDF","category":"network","line_end":23,"severity":"low","line_start":23},{"id":"network:SKILL.md:24:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"| PM2.5注意喚起エリア | `https://soramame.env.go.jp/data/sokutei/pm25/alert.csv` |","category":"network","line_end":24,"severity":"low","line_start":24},{"id":"network:SKILL.md:25:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"| 最新データ時刻(地図用メタ) | `https://soramame.env.go.jp/data/map/kyokuNoudo/metadata.json` |","category":"network","line_end":25,"severity":"low","line_start":25},{"id":"network:SKILL.md:30:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"curl -sm 60 -O https://soramame.env.go.jp/data/sokutei/noudoAll/2026/09/26/01.csv","category":"network","line_end":30,"severity":"low","line_start":30},{"id":"network:SKILL.md:54:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"curl -sm 30 https://soramame.env.go.jp/data/sokutei/NoudoTime/13101010/today.csv","category":"network","line_end":54,"severity":"low","line_start":54},{"id":"network:SKILL.md:64:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"curl -sm 120 'https://soramame.env.go.jp/soramame/api/data_search?Start_YM=202609&End_YM=202609&TDFK","category":"network","line_end":64,"severity":"low","line_start":64},{"id":"network:SKILL.md:76:hardcoded-url","file":"SKILL.md","pattern":"Hardcoded URL","snippet":"curl -s https://soramame.env.go.jp/data/sokutei/pm25/alert.csv","category":"network","line_end":76,"severity":"low","line_start":76},{"id":"filesystem:SKILL.md:83:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"共通の取得時チェックリストは [共通レスポンス契約](../docs/response-contract.md) の「取得時の落とし穴チェックリスト」を参照。","category":"filesystem","line_end":83,"severity":"high","line_start":83},{"id":"sensitive:SKILL.md:20:environment-file-access","file":"SKILL.md","pattern":"Environment file access","snippet":"| 全国の最新1時間値(全測定局) | `https://soramame.env.go.jp/data/sokutei/noudoAll/{YYYY}/{MM}/{DD}/{HH}.csv` |","category":"sensitive","line_end":20,"severity":"high","line_start":20},{"id":"sensitive:SKILL.md:21:environment-file-access","file":"SKILL.md","pattern":"Environment file access","snippet":"| 測定局ごとの今日の値 | `https://soramame.env.go.jp/data/sokutei/NoudoTime/{SKT_CD}/today.csv` |","category":"sensitive","line_end":21,"severity":"high","line_start":21},{"id":"sensitive:SKILL.md:22:environment-file-access","file":"SKILL.md","pattern":"Environment file access","snippet":"| 測定局ごとの直近7日 | `https://soramame.env.go.jp/data/sokutei/NoudoTime/{SKT_CD}/7day.csv` |","category":"sensitive","line_end":22,"severity":"high","line_start":22},{"id":"sensitive:SKILL.md:23:environment-file-access","file":"SKILL.md","pattern":"Environment file access","snippet":"| 公式API(都道府県別・月次履歴JSON) | `https://soramame.env.go.jp/soramame/api/data_search?Start_YM={yyyymm}&TDF","category":"sensitive","line_end":23,"severity":"high","line_start":23},{"id":"sensitive:SKILL.md:24:environment-file-access","file":"SKILL.md","pattern":"Environment file access","snippet":"| PM2.5注意喚起エリア | `https://soramame.env.go.jp/data/sokutei/pm25/alert.csv` |","category":"sensitive","line_end":24,"severity":"high","line_start":24},{"id":"sensitive:SKILL.md:25:environment-file-access","file":"SKILL.md","pattern":"Environment file access","snippet":"| 最新データ時刻(地図用メタ) | `https://soramame.env.go.jp/data/map/kyokuNoudo/metadata.json` |","category":"sensitive","line_end":25,"severity":"high","line_start":25},{"id":"sensitive:SKILL.md:30:environment-file-access","file":"SKILL.md","pattern":"Environment file access","snippet":"curl -sm 60 -O https://soramame.env.go.jp/data/sokutei/noudoAll/2026/09/26/01.csv","category":"sensitive","line_end":30,"severity":"high","line_start":30},{"id":"sensitive:SKILL.md:54:environment-file-access","file":"SKILL.md","pattern":"Environment file access","snippet":"curl -sm 30 https://soramame.env.go.jp/data/sokutei/NoudoTime/13101010/today.csv","category":"sensitive","line_end":54,"severity":"high","line_start":54},{"id":"sensitive:SKILL.md:64:environment-file-access","file":"SKILL.md","pattern":"Environment file access","snippet":"curl -sm 120 'https://soramame.env.go.jp/soramame/api/data_search?Start_YM=202609&End_YM=202609&TDFK","category":"sensitive","line_end":64,"severity":"high","line_start":64},{"id":"sensitive:SKILL.md:76:environment-file-access","file":"SKILL.md","pattern":"Environment file access","snippet":"curl -s https://soramame.env.go.jp/data/sokutei/pm25/alert.csv","category":"sensitive","line_end":76,"severity":"high","line_start":76},{"id":"obfuscation:lookup.py:34:heuristic-very-high-entropy-string-5-52-bits-lik","file":"lookup.py","pattern":"[HEURISTIC] Very high entropy string (5.52 bits) - likely encoded/encrypted payload","snippet":"エラー: CSVではなくHTMLが返りました(存在しない時刻の可能性)。metadata.jsonのlatestを確認してください。","category":"obfuscation","line_end":34,"severity":"high","line_start":34},{"id":"obfuscation:SKILL.md:71:heuristic-very-high-entropy-string-5-88-bits-lik","file":"SKILL.md","pattern":"[HEURISTIC] Very high entropy string (5.88 bits) - likely encoded/encrypted payload","snippet":"。2026-09-26実測(東京都・2026年9月・PM2_5とTEMP): 200、約4.4MB、50,830行、85測定局。**月全体を取ると数MBになるの...","category":"obfuscation","line_end":71,"severity":"high","line_start":71},{"id":"obfuscation:SKILL.md:1:heuristic-high-file-entropy-7-07-bits-possible-b","file":"SKILL.md","pattern":"[HEURISTIC] High file entropy (7.07 bits) - possible binary/encrypted content","snippet":"File: SKILL.md","category":"obfuscation","line_end":1,"severity":"high","line_start":1}],"finding_verdicts":[{"id":"network:lookup.py:17:fetch-api-call","reason":"This defines a download helper used for public AEROS metadata and CSV retrieval. Its callers do not transmit credentials or private files.","verdict":"false_positive","confidence":0.99},{"id":"network:lookup.py:23:fetch-api-call","reason":"The request retrieves the latest measurement timestamp from the fixed government HTTPS endpoint. It sends no private payload or authentication secrets.","verdict":"false_positive","confidence":0.99},{"id":"network:lookup.py:32:fetch-api-call","reason":"The URL is constructed for a public hourly CSV under the government HTTPS base. The downloaded bytes are validated and cached, not executed.","verdict":"false_positive","confidence":0.98},{"id":"network:lookup.py:12:python-http-libraries","reason":"urllib.request is a standard library import supporting the documented public data downloads. The import itself performs no network operation.","verdict":"false_positive","confidence":0.99},{"id":"network:lookup.py:18:python-http-libraries","reason":"The request includes only a fixed descriptive User-Agent header. No authorization header, credential, or private request body is supplied.","verdict":"false_positive","confidence":0.99},{"id":"network:lookup.py:19:python-http-libraries","reason":"urlopen retrieves public measurement data with a timeout and default HTTPS certificate verification. No code execution or private data transmission is present.","verdict":"false_positive","confidence":0.98},{"id":"network:lookup.py:14:hardcoded-url","reason":"The hardcoded HTTPS host is Japan's public Soramame environmental monitoring service. It is the documented data source, not an unrelated collection endpoint.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:lookup.py:9:hidden-file-in-home-directory","reason":"This docstring describes a dedicated application cache under the standard user cache directory. It does not instruct access to hidden credentials or configuration.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:lookup.py:15:hidden-file-in-home-directory","reason":"The path is a fixed application-specific cache for public hourly CSV files. No credential directory or unrelated hidden file is targeted.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:lookup.py:9:hidden-file-access","reason":"The matched text documents public CSV caching rather than executable hidden-file access. Subsequent code uses the same dedicated cache directory.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:lookup.py:15:hidden-file-access","reason":"expanduser resolves a fixed public-data cache path. The code does not enumerate hidden files or read secret storage.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:lookup.py:35:python-file-write-append","reason":"The write stores downloaded CSV bytes in the timestamped application cache after checking the header. No unrelated file modification is evident.","verdict":"false_positive","confidence":0.96},{"id":"filesystem:lookup.py:28:python-os-file-operations","reason":"makedirs creates the fixed application cache directory with exist_ok enabled. It performs no deletion or modification of unrelated user directories.","verdict":"false_positive","confidence":0.99},{"id":"sensitive:lookup.py:14:environment-file-access","reason":"The matched env text belongs to the government hostname soramame.env.go.jp. No environment file is opened or environment variable read.","verdict":"false_positive","confidence":1},{"id":"sensitive:lookup.py:74:certificate-key-files","reason":"keyword is a station-search argument passed to select_hits. This line does not access certificate files, keys, or secret material.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:12:ruby-shell-backtick-execution","reason":"The backticks format an API path as inline Markdown code. They are not shell command substitution or Ruby execution.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:20:ruby-shell-backtick-execution","reason":"The table uses Markdown backticks around a public hourly CSV URL. No executable shell expression is present.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:21:ruby-shell-backtick-execution","reason":"The backticks format a public station daily CSV endpoint in a Markdown table. They do not execute a command.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:22:ruby-shell-backtick-execution","reason":"The backticks surround a documented seven-day station CSV URL. This is Markdown formatting, not command substitution.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:23:ruby-shell-backtick-execution","reason":"The backticks format a public monthly-history API URL and its query placeholders. The table contains no shell execution.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:24:ruby-shell-backtick-execution","reason":"The public PM2.5 advisory URL is formatted as inline Markdown code. No backtick execution occurs.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:25:ruby-shell-backtick-execution","reason":"The backticks format the latest-timestamp metadata URL. They are documentation syntax rather than an executable instruction.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:29:ruby-shell-backtick-execution","reason":"The match is a Markdown code fence around a fixed curl download of public data. The command contains no substitution or private upload.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:31:ruby-shell-backtick-execution","reason":"This closes a Markdown code fence and precedes timestamp-format documentation. Neither syntax executes backtick commands.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:33:ruby-shell-backtick-execution","reason":"Inline code spans mark metadata fields, an example timestamp, and zero-padded hours. No shell command is supplied.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:37:ruby-shell-backtick-execution","reason":"The fenced block contains CSV column names. It is a data-format example with no executable shell content.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:39:ruby-shell-backtick-execution","reason":"The match closes a CSV-header code block and introduces station-field documentation. This is Markdown, not shell substitution.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:41:ruby-shell-backtick-execution","reason":"The inline backticks mark the missing-data sentinel and helper identifiers in explanatory prose. They are not executable expressions.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:43:ruby-shell-backtick-execution","reason":"The prose names lookup.py and metadata.json using Markdown code spans. It describes data filtering without shell substitution.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:45:ruby-shell-backtick-execution","reason":"The fence contains a fixed Python invocation for station lookup and commented sample results. It has no injected shell expression or unrelated command.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:49:ruby-shell-backtick-execution","reason":"The matched backticks delimit documented command examples. They do not perform backtick execution.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:53:ruby-shell-backtick-execution","reason":"The Markdown fence contains a fixed curl request for a public station daily CSV. No secret access, upload, or command substitution appears.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:55:ruby-shell-backtick-execution","reason":"This closes the curl example and precedes CSV-column documentation. The backticks are Markdown delimiters, not executable shell syntax.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:57:ruby-shell-backtick-execution","reason":"Inline code spans document CSV columns and the seven-day filename. They contain no command execution.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:61:ruby-shell-backtick-execution","reason":"The line formats an API manual path and introduces a fenced example. This is documentation syntax, not shell substitution.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:63:ruby-shell-backtick-execution","reason":"The fenced curl command uses a single-quoted, fixed public API URL. Its query string cannot become shell operators in the shown invocation.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:65:ruby-shell-backtick-execution","reason":"The match closes the monthly API command example and introduces parameter documentation. The backticks are Markdown formatting.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:67:ruby-shell-backtick-execution","reason":"The backticks mark Start_YM and End_YM query parameter names. They do not invoke shell commands.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:68:ruby-shell-backtick-execution","reason":"The backticks format prefecture and station query parameter names. No executable expression appears.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:69:ruby-shell-backtick-execution","reason":"The line lists measurement field names and the PM2_5 spelling in Markdown code spans. It is data documentation, not shell code.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:71:ruby-shell-backtick-execution","reason":"The backticks enclose a sample API response and a missing-data marker. No evaluation or executable command is requested.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:75:ruby-shell-backtick-execution","reason":"The fenced command retrieves the public PM2.5 advisory CSV using a fixed URL. It contains no command substitution or private upload.","verdict":"false_positive","confidence":0.99},{"id":"external_commands:SKILL.md:77:ruby-shell-backtick-execution","reason":"The code fence closes the advisory download example and precedes its column documentation. No backtick execution occurs.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:79:ruby-shell-backtick-execution","reason":"Inline backticks format advisory CSV columns and validation identifiers in surrounding prose. These are Markdown code spans, not executable shell expressions.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:85:ruby-shell-backtick-execution","reason":"The line formats the expected CSV header and metadata filename while describing response validation. It contains no shell command substitution.","verdict":"false_positive","confidence":1},{"id":"external_commands:SKILL.md:86:ruby-shell-backtick-execution","reason":"The prose marks the missing-value sentinel and station filter parameter with Markdown backticks. It instructs accurate data handling, not code execution.","verdict":"false_positive","confidence":1},{"id":"network:SKILL.md:20:hardcoded-url","reason":"The URL documents the public government hourly measurement CSV. Its purpose matches the skill and no private data transfer is requested.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:21:hardcoded-url","reason":"The URL is the documented public government station daily-data endpoint. It is not an exfiltration destination.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:22:hardcoded-url","reason":"This public government endpoint provides seven-day station measurements. The documentation requests no credentials or unrelated transmission.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:23:hardcoded-url","reason":"The query parameters select public measurements by month, prefecture, and pollutant. No private payload or secret is included.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:24:hardcoded-url","reason":"The fixed HTTPS URL retrieves public PM2.5 advisories from the government data service. It matches the documented functionality.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:25:hardcoded-url","reason":"The URL retrieves public latest-timestamp metadata used to select the correct CSV. No private information is sent.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:30:hardcoded-url","reason":"The curl example downloads a fixed public hourly CSV with a timeout. It does not upload files or disable HTTPS verification.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:54:hardcoded-url","reason":"The curl example retrieves daily measurements for a fixed public station code. No authentication or private payload is supplied.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:64:hardcoded-url","reason":"The fixed API URL requests public Tokyo PM2.5 and temperature records for a specified month. Its query contains no secrets.","verdict":"false_positive","confidence":0.99},{"id":"network:SKILL.md:76:hardcoded-url","reason":"The curl command reads the public government PM2.5 advisory CSV. No unrelated host or private upload is involved.","verdict":"false_positive","confidence":0.99},{"id":"filesystem:SKILL.md:83:path-traversal-sequence","reason":"The parent-directory sequence is a static Markdown link to shared documentation. No user-controlled filesystem path or executable traversal operation appears.","verdict":"false_positive","confidence":0.99},{"id":"sensitive:SKILL.md:20:environment-file-access","reason":"The env substring is part of the public government hostname. The line documents a CSV endpoint, not a local environment file.","verdict":"false_positive","confidence":1},{"id":"sensitive:SKILL.md:21:environment-file-access","reason":"The matched text is the env component of soramame.env.go.jp. No environment file or secret variable is referenced.","verdict":"false_positive","confidence":1},{"id":"sensitive:SKILL.md:22:environment-file-access","reason":"The env text occurs inside a public HTTPS hostname. The line does not access local configuration or credentials.","verdict":"false_positive","confidence":1},{"id":"sensitive:SKILL.md:23:environment-file-access","reason":"The government hostname contains env as a domain label. The monthly API documentation does not read any environment file.","verdict":"false_positive","confidence":1},{"id":"sensitive:SKILL.md:24:environment-file-access","reason":"The match comes from the government domain in an advisory URL. It is not a reference to a sensitive environment file.","verdict":"false_positive","confidence":1},{"id":"sensitive:SKILL.md:25:environment-file-access","reason":"The env substring belongs to the public metadata endpoint hostname. No environment-file access is present.","verdict":"false_positive","confidence":1},{"id":"sensitive:SKILL.md:30:environment-file-access","reason":"curl downloads a public CSV from a hostname containing env. It neither reads nor transmits an environment file.","verdict":"false_positive","confidence":1},{"id":"sensitive:SKILL.md:54:environment-file-access","reason":"The command references the public government domain rather than a local environment file. No secret access is requested.","verdict":"false_positive","confidence":1},{"id":"sensitive:SKILL.md:64:environment-file-access","reason":"The env match is inside the quoted public API hostname. All query arguments select public data rather than local secrets.","verdict":"false_positive","confidence":1},{"id":"sensitive:SKILL.md:76:environment-file-access","reason":"The advisory download URL contains env in its domain name. The command does not access an environment file.","verdict":"false_positive","confidence":1},{"id":"obfuscation:lookup.py:34:heuristic-very-high-entropy-string-5-52-bits-lik","reason":"The string is a readable Japanese error explaining an invalid CSV response. It is displayed by sys.exit, not decoded or executed.","verdict":"false_positive","confidence":1},{"id":"obfuscation:SKILL.md:71:heuristic-very-high-entropy-string-5-88-bits-lik","reason":"The line contains a readable API response example and Japanese explanations of size and missing values. No encoded executable payload is present.","verdict":"false_positive","confidence":1},{"id":"obfuscation:SKILL.md:1:heuristic-high-file-entropy-7-07-bits-possible-b","reason":"The full file is readable Japanese and English Markdown with YAML front matter and data examples. Multibyte text explains the entropy signal.","verdict":"false_positive","confidence":1}],"semantic_findings":[],"subject_marketplace_commit_sha":"7f17813fb6af1acc7d8fd3fb5f05480f5be52783","subject_content_hash":"22982047e3605eff0eea6b27d7bd6f6a1df36a218018c692e66f1d57c8494a0b","subject_tree_hash":"d55a2224ee5844c71ba6c45fd2ff11378477399c7c691dfe42dd6e4e828e27ec","subject_plugin_path":"skills/tahodev/air-quality","audit_payload_hash":"9b90c5cb8b940e170019ca7ccfb66a10","confirmed_risk_level":"safe","scanner_version":"3.0.0","policy_version":"skillstore-security-audit-policy-v1","subject":{"marketplaceCommitSha":"7f17813fb6af1acc7d8fd3fb5f05480f5be52783","contentHash":"22982047e3605eff0eea6b27d7bd6f6a1df36a218018c692e66f1d57c8494a0b","treeHash":"d55a2224ee5844c71ba6c45fd2ff11378477399c7c691dfe42dd6e4e828e27ec","pluginPath":"skills/tahodev/air-quality","auditPayloadHash":"9b90c5cb8b940e170019ca7ccfb66a10"},"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-air-quality/audits/1/attestation","status":"active"},"trust":{"publicState":"public","auditState":"complete","auditCurrentness":null,"confirmedRiskLevel":"safe","confirmedFindingCount":0,"capabilityReviewCount":0,"needsReviewCount":0,"falsePositiveCount":0,"agentAutoInstallPolicy":"allowed","manualInstallPolicy":"allowed","artifactSignatureState":"available","attestationState":"active","verificationState":"not_verified"},"isLatest":true}}