
CISA KEV、ThreatFox、URLhaus、MalwareBazaarのフィードを集約し、検索、変更追跡、STIX/CSV/JSONLエクスポート機能を備えた脅威インテル監視台。
エビデンス優先の脅威観測システムであり、現在のソース状態、実質的な変更イベント、運用上のフェッチテレメトリを意味論的に分離して保持します。欠落、失効、無効化、または利用不可のデータは、視覚的にも欠落したまま表示されます。インターフェースがデモレコードや推測された帰属を代用することはありません。
現在のリリースでは、エビデンスの日付と端末ローカルの確認状態を堅牢化し、重要な読み取り失敗をすべて、成功したゼロ件状態と視覚的に明確に区別できるようにし、相関リクエストを安定化させ、エビデンスドロワー、制限付き調査フィルター、ソース解釈、エクスポート集計を強化しています。アニメーションによるすべてのリプレイマークは、保持された NEW、UPDATED、または REMOVED イベントのいずれかに対応しており、装飾的なネットワークトラフィックではありません。

Pulse — ソース間の関連性、ソースの健全性、現在の状態の分析。

Replay — 保持された NEW、UPDATED、REMOVED 遷移のページ範囲内での再構築。
追加のライブ画面には、おおよその公開IPインフラ地理情報と、ファーストパーティの URLhaus / MalwareBazaar エビデンスビューが含まれます。これらの画面は、このREADMEでは意図的にプレースホルダーや重複したスクリーンショットでは表現されていません。
本番キャプチャは、稼働中の v1.2.0 オブザーバトリーからのソースを保持するスクリーンショットです。表示用にトリミングおよびリサイズ/圧縮されています。表示されるエビデンス、タイムスタンプ、件数、IOC値、インターフェース状態は、再生成または置換されていません。
本番の Worker は Cloudflare D1 をバックエンドとしています。フィード認証情報は、サーバーのみの Cloudflare Worker シークレットとして保持され、ブラウザで必要になることはありません。
1.2.022.13.0 以降このデプロイは demand-driven モードで動作します。このリポジトリは現在、標準の Cloudflare Workers を直接ターゲットとしています。スケジュールされたトリガーは v1.2.0 では意図的に有効化されていないため、アプリケーションは継続的な収集を主張しません。将来のスケジューラーは、別途の正確性と運用上の検証の後に、同じ runIngestionCycle() オペレーションを呼び出すことができます。
ブラウザは、初回使用時と、開いている間は5分ごとに、明示的な制限付きメンテナンスリクエストを送信します:
POST /api/ingest
↓
runIngestionCycle()
↓
configuration → TTL → backoff → D1 lease → fetch → normalize → validate
↓
snapshot cache + current observations + material events + cycle statistics
通常の読み取りは分離されており、ローカルで行われます:
GET /api/observations → D1 current state, scoped before pagination
GET /api/search → D1 current state, scoped before pagination
GET /api/kev → D1 current CISA catalog
GET /api/events → D1 material change ledger
GET /api/geo → local observations + bounded cached IP enrichment
これらの GET ルートはいずれもソースアダプターを呼び出しません。このプロジェクトが将来、真にサポートされたスケジューラーを獲得した場合、2つ目のリフレッシュ実装を作成することなく、同じ runIngestionCycle() オペレーションを呼び出すことができます。
カバレッジはソースごとに表示されます。制限付き API が完全なカタログとして提示されることはありません。
DB バインディングは、以下の個別のデータセットを保持します:
threat_source_cache と threat_source_cache_chunks: ソースごとの最新の検証済みスナップショット。世代キー付きチャンクで保存されます。observations: 安定したソースアイデンティティごとの最新の正規化された現在の状態。初回取り込み、最新のソース目撃、最後の実質的な変更、現在のハッシュ、リビジョン数、最新の取り込み結果を保持します。observation_events: 意味のある NEW、UPDATED、正当化できる REMOVED エビデンスイベント。以前と現在の正規化されたペイロード、ハッシュ、決定論的なフィールド差分により、以前の状態を再構築できます。source_fetch_log: レスポンス本文や認証情報を含まない、制限付きのフェッチ試行テレメトリ。source_ingest_cycles: フェッチ済み、有効、拒否、新規、更新、変更なし、削除されたレコードの、リフレッシュごとの制限付き件数。source_refresh_lease: 同時実行される isolate が上流のリフレッシュを重複させないための、D1 をバックエンドとするソースごとの短期リース。ingestion_runtime: 最新の取り込みサイクル全体の健全性。geo_ip_cache: 検証済みのおおよその IP 位置情報結果と、制限付きのネガティブキャッシュエントリ。成功した結果は30日後に失効し、失敗したルックアップは5分後に再試行されます。失効した D1 行は GEO リクエスト中に機会的に削除され、isolate フォールバックは2,000エントリに制限されます。ランタイムスキーマ定義は db/schema.ts にあります。初期化では、依存するインデックスを作成する前に、既存の observations テーブルに新しい現在の状態のカラムを追加します。
これらの問いは意図的に区別されています:
observations と検証済みのソーススナップショットがこれに答えます。/api/observations?window=... は、上流の observedAt によって現在の観測値をフィルタリングします。observation_events と /api/revisions がこれに答えます。現在の状態は、7日間の履歴テーブルとして不正確に説明されることはありません。実質的なイベント台帳は7日間保持されます。フェッチとサイクルのテレメトリは2日間保持され、ソースごとに200行に制限されます。7日間再出現しない非カタログの現在の観測値は削除されます。CISA は、成功した応答が常に完全なカタログであるため、最新の状態を維持します。そのカタログから除外された行は、削除されるまで30日間利用可能です。
現在、REMOVED イベントを作成できるのは CISA の不在のみです。そのアダプターが完全な現在のカタログを取得するためです。制限付きの ThreatFox、URLhaus、または MalwareBazaar の結果に存在しないことは、削除として扱われません。
変更のない目撃は、現在の lastObservedInSnapshotAt/lastIngestedAt を進めますが、イベントを作成したり revisionCount を増加させたりしません。lastChangedAt は、その後の変更のない目撃でも保持されます。
Exploited ビューは以下を分離します:
dateAdded が明示的な TODAY、7D、または 30D の範囲内にあるレコード。1日未満のオブザーバトリーウィンドウが CISA の精度として提示されることはありません。現在のカタログは、サーバーサイド検索、ベンダー、製品、新規追加、ランサムウェア関連、追加日フィルター、不透明なカーソルページネーションをサポートしています。CVE、ベンダー、製品、脆弱性名、追加日、期日、ランサムウェア関連、必要なアクションを表示します。CVSS スコアを独自に作成することはありません。
コンテンツハッシュは、オブザーバトリーの簿記情報ではなく、正規化されたエビデンスフィールドを対象としています。ハッシュが変更されると、以前の正規化ペイロード、新しい正規化ペイロード、以前/新しいハッシュ、および以下の項目に対する決定論的な差分を含む UPDATED イベントが生成されます:
プロビナンスドロワーは /api/revisions?id=... を照会し、現在のハッシュ、最後の実質的な変更、リビジョン数、保持されたイベント、フィールドレベルの差分を公開します。変動する取り込みタイムスタンプは、コンテンツ差分には表示されません。
ドロワーはまた、受け入れられたレコードごとに、バージョン管理されたエビデンストレースを公開します: 受け入れられた正規化フィールド、存在しないままのオプションフィールド、表示専用の変換、分類の根拠、安定したアイデンティティの根拠。このトレースは保持されたエビデンスのみを説明します。拒否された上流の値は保持されず、合成のオブザーバトリーアイデンティティが割り当てられることもありません。拒否は、制限付きのフィールドと理由コードを持つサイクルごとの集計件数として別途表現されます。そのスキーマより前に収集された古いサイクルは、再構築されるのではなく、内訳がないものとしてラベル付けされます。
Recent Events は実質的な変更のみを表示します。完全な CISA リフレッシュ後に、変更のない SEEN 行を何百件も出力することはありません。それらの目撃はソースサイクル統計に要約されます。
デフォルトの Briefing ビューは、現在のブラウザにのみ保存されているバージョン管理された確認カーソルと、保持された実質的なイベント台帳を比較します。初回使用とストレージの消去は、新しいアクティビティではなく初期ベースラインとしてラベル付けされます。保存されたカーソルが保持された台帳より古い場合、インターフェースは完全な差分を証明できないと明記します。
確認操作はサーバーイベントを変更または削除することはありません。カーソルは、意図的な端末移行のために JSON としてエクスポートおよびインポートできます。アカウント同期状態として提示されることはなく、生成された端末識別子がサーバーに送信されることもありません。
Briefing の合計は、現在返された台帳ページを表し、表示中/ページ範囲内としてラベル付けされます。保持された完全な台帳の合計として提示されることはありません。
インポートされた確認タイムスタンプは、保存または比較の前に厳密に検証され、UTC ISO-8601 に正規化されます。ブラウザストレージはオプションとして扱われます: ブロックされた、または失敗したローカルストレージは、コンパクトなインラインエラーを生成し、Briefing をクラッシュさせることはありません。
Export ワークベンチは、すでに読み込まれた検証済みの表示ページを、CSV、JSONL、STIX 2.1、無害化(defang)されたテキスト、または適用されたポリシーと利用可能なレコードハッシュを含むエビデンスマニフェストとしてフォーマットします。アクティブなローカル検索とソーススコープは Export に引き継がれます。空のソース許可リストは0レコードをエクスポートします。STIX は CISA の CVE を Vulnerability オブジェクトとして、検証済みのファイルハッシュ(MalwareBazaar の SHA-256 値を含む)を Indicator オブジェクトとして表現します。選択済み、出力済み、サポート対象外の件数は区別されます。サポート対象外のレコードは、黙って破棄されるのではなく、バンドルメタデータで開示されます。Export は上流の収集を行いません。欠落した信頼度は欠落したままになり、ソース間の不一致は別々のレコードとして残り、削除された台帳イベントが現在の状態のエクスポートに黙って入り込むことはありません。これらの成果物はエビデンスの伝達手段であり、ファイアウォールのブロック推奨ではありません。
失効したソースは、1、2、5、15、30分の制限付き再試行遅延を使用します。有効なより大きな Retry-After は最大1時間まで尊重されます。バックオフ中は、有効な以前のスナップショットが古いものとして提供され、空の失敗したソースはオフラインのままになります。
フェッチの前に、対象となるソースは短期の条件付き D1 リースを取得します。別の isolate は未失効の保持者を置き換えることができないため、1つのリフレッシュだけが進行します。D1 が利用できない場合、システムは明示的に縮退したスナップショット専用モードと isolate メモリリースを報告します。そのフォールバックは分散型として説明されることはありません。
現在の観測値、ソース固有のワークスペース、ローカル検索、CISA カタログ、実質的なイベント、レコードリビジョンは、制限付きのサーバーサイドカーソルクエリを使用します。ソースと種類の制約は、並べ替えとページネーションの前に適用されます。カーソルは安定したソートタプルをエンコードし、長さ/文字/スキーマが検証され、不正な形式の場合は HTTP 400 でフェイルクローズします。ブラウザがローカルでページネーションするためだけに完全な7日間のデータセットを受け取ることはありません。
API リミッターは、Worker isolate にスコープされたインメモリの固定ウィンドウカウンターです。これは、グローバルに権威のある Cloudflare レート制限ではなく、ベストエフォートの isolate ローカル保護として正確に報告されています。通常の読み取りは、報告されたクライアント IP ごとに1分あたり120リクエストに制限されます。取り込みには別の1分あたり6リクエストのバケットがあり、GEO には別の1分あたり12リクエストのバケットがあります。D1 書き込みは、この制御を過大評価するためだけにすべての読み取りに追加されることはありません。
POST /api/ingest — 明示的なデマンド駆動メンテナンスサイクル。TTL、バックオフ、D1 リースを尊重します。GET /api/observations?window=24h&scope=urlhaus&limit=100&cursor=... — ページングされたローカルの現在の状態ウィンドウ。検証済みスコープは all、urlhaus、malwarebazaar、infrastructure です。GET /api/search?q=indicator&window=24h&scope=urlhaus&limit=100&cursor=... — ページングされたスコープ付きローカル検索。上流への呼び出しはゼロです。GET /api/kev?limit=50&q=...&vendor=...&product=...&ransomware=known&addedSince=YYYY-MM-DD&cursor=... — 完全な現在の CISA カタログ。GET /api/events?limit=50&cursor=... — 実質的なイベント台帳。GET /api/revisions?id=...&limit=50&cursor=... — 現在のレコードと保持されたリビジョン。GET /api/correlations?id=... — データセットレベルの現在の状態における完全一致インディケーターのピア。ローカルの Cloudflare 開発は、サーバー専用の認証情報を .dev.vars から読み取ります。.dev.vars.example を .dev.vars にコピーし、使用を許可されたフィードのみを入力してください:
THREATFOX_AUTH_KEY=
URLHAUS_AUTH_KEY=
MALWAREBAZAAR_AUTH_KEY=
本番環境の認証情報は、Cloudflare Worker シークレットとして保存する必要があります。クライアントに公開されるコミット済みソースや GitHub 変数に含めてはなりません。アプリケーションは Workers ランタイムのバインディングサーフェスのみを通じてこれらにアクセスします。これらが NEXT_PUBLIC_*、クライアントコンポーネント、HTML、ログ、フィクスチャ、またはコミットされたファイルに出現してはなりません。
このリポジトリは標準の Cloudflare Workers を直接ターゲットとしています。wrangler.jsonc は Worker 設定の信頼できる情報源であり、DB という名前のドラフト D1 バインディングを宣言します。Wrangler 4 は、最初の認証付きデプロイ時にその D1 リソースを自動的にプロビジョニングし、以降のデプロイでもバインディングのリンクを維持します。アカウント固有の D1 識別子はコミットされません。
開発および本番コマンド:
npm ci
npm run dev
npm run build
npm run preview
# authenticated Cloudflare session / CI only
npm run deploy
GitHub Actions の検証は、すべてのプルリクエストと main へのプッシュで実行されます。本番デプロイは deploy production ワークフローを通じて意図的に手動であり、CLOUDFLARE_API_TOKEN と CLOUDFLARE_ACCOUNT_ID という名前のリポジトリシークレットが必要です。これにより、レビューされていないブランチや不完全な認証情報の設定が自動的に公開されることを防ぎます。
npm ci
npm audit --omit=dev --audit-level=high
npm audit --audit-level=high
npm test
npm run lint
npm test はサポートされているテストエントリポイントです。決定論的スイートの前に完全な本番ビルドを実行し、アーティファクトレベルのクライアントシークレット分離が dist/client を検査できるようにします。クリーンなチェックアウトに対して node --test を直接実行すると、その必要なビルドアーティファクトが意図的に省略されます。テストは、厳密なカレンダーと確認タイムスタンプの解析、オプションの端末ストレージ、安定した相関依存関係、正規化されたエビデンス、正規のタグハッシュ、実質的なイベントの作成、変更のない再取り込み、以前のペイロードの保持、最後の変更の耐久性、フィールド差分、イベント保持と台帳ギャップ、エビデンストレース、空ソースのエクスポートポリシー、STIX 表現/件数の整合性、TTL/バックオフの適格性、リフレッシュリース、サーバーサイドのページネーション前スコープ適用の配線、専用の GEO/Recent-KEV クエリ、カーソル検証、読み取りパスの分離、ソースカバレッジ、外部参照ポリシー、レート制限の正確性、ソース障害の分離、クライアントシークレットの分離をカバーしています。
GEO モードは、検証済みの公開 IPv4/IPv6 観測値のみをプロットします。専用の D1 クエリが、一般的な観測ページを再利用する代わりに、要求された現在の状態ウィンドウ全体から対象となる IP レコードを選択します。レスポンスは、候補レコードの合計と、2,000レコードの安全性上限に達したかどうかを報告します。呼び出し元は、任意の上流の宛先や IP リストを指定できません。GeoJS が固定のプライマリプロバイダーであり、FreeIPAPI が固定のフォールバックです。任意の上流 URL は不可能です。アプリケーションは、12アドレスのリクエスト上限、30日間の D1 成功キャッシュ、5分間の再試行キャッシュ、専用のルートリミッターを通じて外部作業を制限します。プロットされたすべてのポイントは、実際のプロバイダーのプロビナンスを保持し、その基になるローカルレコードを開くことができます。
MIT ライセンスのもとでリリースされています。LICENSE を参照してください。
GEO モードを選択すると、サーバーは検証済みの各公開IP候補を、通常の HTTPS リクエストメタデータとともに GeoJS に送信し、フォールバックが必要な場合には FreeIPAPI にも送信します。したがって、これらのプロバイダーは、どの公開アドレスが照会されたかを観測できます。プライベート、予約、ドキュメント、クライアント指定のアドレスは送信されません。relationship モードは位置情報リクエストを実行しません。
Replay ワークスペースは、オブザーバトリーの検出時刻順に、実質的な台帳遷移の現在のページを再構築します。NEW、UPDATED、REMOVED の動きは、保存されたイベントのみによって駆動されます。これは明示的にページ範囲内であり、完全な履歴スナップショットやネットワークトラフィック量の再構築を主張するものではありません。
Natural Earth 由来の world-atlas パッケージがローカルのベースマップを提供します。マップは同じ場所に配置された IP をクラスタリングし、ホバー詳細とプロビナンスへのクリックスルーをサポートし、ジオロケート済み、除外済み、利用不可、保留中の件数を報告します。プライベート、予約、ドキュメント、マルチキャスト、その他の非公開レンジは、プロバイダー呼び出しの前に除外されます。
IP 位置情報は、明示的におおよそのインフラストラクチャ位置として提示されます。これは、アクターの位置、イベントの発信元、国籍、所有権の調査結果、または帰属の主張ではありません。失敗したエンリッチメントは存在しないままになります。アプリケーションが代わりの座標を生成することはありません。
デフォルトのビジュアライゼーションは、ソースと明示的に指定されたマルウェアファミリーにリンクされた個々の観測値のインタラクティブな力指向フィールドのままです。キャンバスは、ノードのドラッグ、フィールドのパン、ズーム、アニメーション化されたリンクトラフィック、直接のプロビナンス検査をサポートしています。GEO は、独自のプロビナンスと失敗セマンティクスを持つ別のエビデンスサーフェスです。
| ソース | 認証情報 | TTL | 実際のカバレッジ |
|---|
| CISA KEV | なし | 30分 | 検証済みの完全な現在のカタログ |
| ThreatFox | THREATFOX_AUTH_KEY | 15分 | 要求された24時間のIOCウィンドウ |
| URLhaus | URLHAUS_AUTH_KEY | 15分 | recent エンドポイントが返す最新500レコード |
| MalwareBazaar | MALWAREBAZAAR_AUTH_KEY | 15分 | エンドポイントが返す最新100メタデータレコード |
GET /api/geo?window=24h — 検証済みのローカル公開IP観測値からのみ候補を導出し、リクエストごとに最大12件のキャッシュされていないプロバイダー結果を取得し、プロビナンス付きのキャッシュされたおおよその WGS84 ポイントを返します。GET /api/status — ソース、現在の状態、鮮度、取り込みモード、サイクル、リース、レート制限のセマンティクス。