公開フィード・静的JSON APIの使い方

社内の監視スクリプトやGoogle Apps Scriptから、公開情報を取得するためのガイドです。最初に「取得前に確認すること」を読み、用途に合うURLを選んでください。認証キーは不要です。

取得前に確認すること

配信元は https://vuln.shirusu.dev です。以下のパスをこのURLに続けます。すべて静的ファイルで、検索条件をクエリで渡す機能はありません。

収集・更新は JST 1日2回(09:00 / 17:00) を予定しています。処理の遅延や失敗もあるため、取得時には generated_at とソースごとの last_success を確認してください。API側の実装は収集スケジュールを変更しません。時刻変更はW-3で統合します。

優先度は対応を検討するための判断材料であり、自社環境への影響有無の断定ではありません。KEV未掲載は「悪用なし」を意味しません。 製品名が一致しても影響があるとは限らず、バージョン範囲・構成・一次情報の確認が必要です。

demo: true のJSONと「デモ・架空データ」表示のフィードは検証用です。実際の脆弱性として通知しないでください。

フィードを購読する

パス掲載内容
/feed.xmlP0/P1の脆弱性・公式告知・事故を更新順に最大50件。初回観測(baseline)も掲載
/feed.json同じ内容のJSON Feed 1.1版
/feeds/p0.xmlP0のみ、最大50件
/feeds/advisories.xmlCVE未付与を含む公式セキュリティ告知、最大50件
/feeds/incidents.xml侵害・事故、最大50件
/feeds/changes.xml直近14日の通知対象となる実質変更、最大50件。変更前後を記載
/feeds/products/<slug>.xml監視製品に一致する脆弱性・告知、最大50件

<slug> は監視製品IDです(例: wordpress、ec_cube)。全製品のURLはAPIの index.json で確認できます。

RSSのGUIDとJSON Feedのidは対象IDと改訂ハッシュを組み合わせます。EPSSの小変動や取得時刻だけの更新ではIDを変更しません。公式の改訂日時や重要な事実が変わると新しいIDになります。フィードの日付は公式更新日時、公開日時、初回観測日時の順に採用します。不明な日時は推測しません。

通常のフィードは現在情報の一覧です。差分通知には changes/latest.json または /feeds/changes.xml を使い、取得済みのイベントIDを利用側で保存してください。初回baseline、説明だけの編集、EPSS微変動は変更フィードから除きます。

APIのURLを選ぶ

以下のパスには /api/v1/ を付けます。

パス内容・上限
index.jsonエンドポイントとスキーマのURL一覧、生成時刻、各ソースの最終成功時刻
vulnerabilities/latest.jsonP0〜P2で直近30日に公開または更新された脆弱性、最大1,000件
vulnerabilities/<CVE>.json詳細ページを生成したCVEのみ。itemに1件を格納
products/<slug>.json監視製品に一致する脆弱性・告知、最大1,000件
advisories.jsonCVE未付与を含む告知、最大1,000件
incidents.json侵害・事故、最大1,000件
changes/latest.json直近14日の実質変更、最大1,000件
status.jsonソース別の取得状態、最終成功時刻、カバレッジ
watch/latest.json日次レポートの最新参照。成果物がなければ report: null
schemas/*.json各応答を検証するJSON Schema(draft-07)。対応はindexのschema欄を参照

日時の抽出範囲はデータの generated_at を基準にします。古いスナップショットでも直近扱いの項目が残るため、利用側で生成時刻を必ず確認してください。未来日時は最新一覧から除きます。

JSONはUTF-8、1ファイル最大2 MiBです。一覧の件数上限より先に容量上限へ達した場合も省略します。total は絞り込み後・省略前の件数、items は返却データ、limit は件数上限、truncated は省略の有無です。ページングはありません。truncated: true を全件取得できた状態として扱わず、製品別APIなどに分けて取得してください。単一詳細が容量上限を超えた場合はビルドを失敗させます。

JSONの項目を読む

項目意味
schema_version / generated_atAPIの契約版(1)とデータ生成時刻
id / kind / cve安定した対象ID、vulnerability・advisory・incidentの区分、CVEまたはnull
title / title_ja / official_title表示用見出し、日本語見出し、公式原題。日本語がなければ公式原題を使用
priority / priority_reasonsP0〜P3またはnullと判定理由
kev / exploitationKEV掲載情報と悪用確認状況。unknownは不明
epss / cvss_maxEPSS(0〜1)と取得済みCVSSの最大値(0〜10)。未取得はnull
affected_products製品ID、vendor、product、ecosystem、package、元識別子、version_ranges、fixed
version_ranges / fixed原文raw、introduced、fixed、match_status。境界未解析はnull。rawを勝手にバージョン式として評価しない
fixed_versions公式データから取得した修正版。空配列は「修正版なし」の断定ではない
summary_ja / impact_ja / action_ja / ai_status日本語の補助要約・影響・対策とAI処理状態。未生成ではnull
description / action公式説明・公式対策のフォールバック。一次情報も確認する
published_at / modified_at / date公式公開・更新日時と、一覧整列用の日付(欠落時は初回観測)
url / sources / source_evidenceサイト詳細URL(ページなしはnull)、一次情報URL、取得時刻・原文参照・原文日時
before / after変更イベントの前後の公開事実。変更イベントにはsource_idとevidence_idsも付く

vendorやpackageは元データで不明ならnullです。製品名からベンダーやパッケージを推測しません。source_evidence.source_ref は原文の参照位置、captured_at は取得時刻です。

status.json の status はok・failed・degraded・stale・never_runなどを保持します。result: unavailable は取得失敗や鮮度不足、success_new_items_unknown は取得成功だが新着件数が不明な状態です。last_new_records は直近成功時に新規または原文ハッシュが変わったレコード数です。0なら no_new_items、1以上なら new_or_updated_items となります。過去のエクスポートで件数が不明な場合はnullを保持し、取得成功を「新着なし」とは表示しません。失敗時は以前の件数が残っていてもunavailableです。カバレッジは出力に含まれるソースの正常数/総数です。未登録・未収集の情報まで網羅する数値ではありません。

watch/latest.json はW-3との接続用です。公開用の reports.json(items配列)または report.json が存在すれば最新レポートのID・日付・生成時刻・収集状態を返します。通知先や内部台帳は公開しません。nullを「重大情報なし」と解釈しないでください。

Google Apps Scriptで取得する

次の例は取得・照合の入口です。メール送信は行いません。ETagに依存せず毎回200応答を読みます。例外になった場合は前回データを保持し、監視失敗として担当者に示してください。

function fetchWatchData() {
  const base = 'https://vuln.shirusu.dev/api/v1/';
  function getJson(path) {
    const response = UrlFetchApp.fetch(base + path, {
      method: 'get',
      muteHttpExceptions: true,
      followRedirects: false,
      headers: { Accept: 'application/json' }
    });
    if (response.getResponseCode() !== 200) {
      throw new Error('取得失敗: ' + path + ' HTTP ' + response.getResponseCode());
    }
    const data = JSON.parse(response.getContentText('UTF-8'));
    if (data.schema_version !== 1 || data.demo === true) {
      throw new Error('未対応スキーマまたはデモデータ');
    }
    const age = Date.now() - Date.parse(data.generated_at);
    if (!Number.isFinite(age) || age < 0 || age > 36 * 60 * 60 * 1000) {
      throw new Error('データ鮮度不足');
    }
    return data;
  }
  const status = getJson('status.json');
  if (!Array.isArray(status.sources) || status.sources.length === 0 ||
      status.sources.some(s => s.status !== 'ok' || !s.last_success ||
        !Number.isFinite(Date.parse(s.last_success)) ||
        Date.now() - Date.parse(s.last_success) > s.interval_hours * 2 * 3600000)) {
    throw new Error('取得失敗またはカバレッジ不足。重大情報なしとは判定しない');
  }
  const data = getJson('products/wordpress.json');
  if (!Array.isArray(data.items) || data.truncated !== false) {
    throw new Error('不完全な一覧。前回データを保持する');
  }
  if (status.generated_at !== data.generated_at) {
    throw new Error('更新途中の可能性。次回再取得する');
  }
  return data.items; // 自社製品・バージョンとの照合はここから実装
}

全API・フィードに Access-Control-Allow-Origin: * と Cache-Control: public, max-age=600 を設定します。10分未満の頻繁な取得は避けてください。障害時は待機時間を延ばし、空配列で前回データを上書きしないでください。

用語と確認先

RSSとJSON Feedは新着情報を購読する形式、JSON SchemaはJSONの構造を検証する契約です。KEVは米CISAの既知悪用脆弱性カタログ、CVSSは深刻度の指標、EPSSは悪用確率の推定値です。掲載根拠は各項目のsources、取得状況はステータスページ、情報源の方針はソースについてで確認してください。

公式仕様(2026-10-29確認): Astro RSS・ JSON Feed 1.1・ Cloudflare Headers・ Pagesファイル上限・ UrlFetchApp。

最終更新: 2026-10-29。実環境への配信・Apps Scriptでの実通信は公開後の確認事項です。