Skip to content

feat(widgets): Shodan インスタンス監査ウィジェットを追加 - #36

Merged
hitalin merged 1 commit into
mainfrom
feat/shodan-instance-audit
Aug 8, 2026
Merged

feat(widgets): Shodan インスタンス監査ウィジェットを追加#36
hitalin merged 1 commit into
mainfrom
feat/shodan-instance-audit

Conversation

@hitalin

@hitalin hitalin commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

なぜ

自分の Misskey インスタンスが外からどう見えているかを点検する手段が無かった。
Shodan 本来の用途(公開インターネットに露出したホストのスキャン)と Misskey を
繋いだ、管理者向けの防御的セルフ監査ツール。

何をするか

ホスト名 → IP を解決し、Shodan のホスト情報を取得して表示する。

  • 露出ポートを危険度別に色分け — 80/443 は「✓ 想定内」に畳み、PostgreSQL /
    Redis / node_exporter など公開すべきでないものは 🚨、SSH や 8080 は ⚠ で名前付き表示
  • TLS の失効判定 — 日付をそのまま出さず残日数を計算する。失効済みは赤、
    14 日以内は赤、30 日以内は橙。証明書は最初に見つかったものでなく最も早く切れるものを選ぶ
  • CVE は CVSS 降順 + 実証/推定の別 — Shodan の CVE はバナーのバージョン表記からの
    推測が多い。未検証を同列の赤で並べると警報疲れで本当に危険なものが埋もれるため、
    実証済 / 推定 を明示し、見出しにも実証済み件数を出す
  • データ鮮度 — Shodan のスキャン日を併記(30 日超は橙)。いつ時点の話かを隠さない

セキュリティ

API キーは widget.is に一切書かず、Secret Vault(クエリ認証 param=key)が
サーバーサイドで注入する。既存の wakatime / hackerone と同じ流儀。

capabilities: ["notedeck-api", "secret-vault"]Nd:call("vault.fetch", ...)
導出するため、S2 / S10 上は高権限アイテム = 人手レビュー必須 Tier になる
(既存の Vault 系ウィジェットと同じ扱い)。

ホスト名は文字種検証のうえ Uri:encode_component でエスケープしてから
クエリ文字列に入れる。不正な入力は HTTP リクエストを 1 本も出さずに弾く。

クレジット消費への配慮

/shodan/host は 1 回につきクエリクレジットを 1 消費する。既存ウィジェットの
Async:interval による自動更新をそのまま採用すると課金が嵩むため、
結果を Mk:save にキャッシュする方式にした。

  • カラムを開き直してもキャッシュを描くだけで消費ゼロ(実測で HTTP 0 件)
  • 実取得は「そのホストで初めて監査するとき」と「更新ボタン」だけ
  • ホストを変えるとキャッシュは自動で無効化。6 時間超のキャッシュは印を付けるが自動再取得はしない
  • busy フラグで連打を抑止し、ボタンには 更新 (1 クレジット) とコストを明示
  • IPv4 直指定なら名前解決を省略してリクエストを 1 本節約

検証

AiScript 1.2.1(ウィジェットが宣言するバージョン)の実インタプリタにモック応答を
流して、9 系統を確認した — 正常 / クリーン / 未インデックス / 名前解決失敗 /
大文字空白混じり入力 / IP 直指定 / 不正文字 / 401 / 未設定。全系統で実行時エラー 0 件。

pnpm run registry:build + check-registry-integrity.mjs は警告 0 件。

アイコン

Shodan 公式ロゴは simple-icons(CC0)に収録が無く商標でもあるため手貼りせず、
lucide の radar で代替した。

🤖 Generated with Claude Code

自分の Misskey インスタンスが外からどう見えているかを Shodan で点検する
管理者向けの防御的セルフ監査ツール。露出ポートを危険度別に色分けし、
稼働サービス・TLS 失効判定・CVE (CVSS と実証/推定の別)・Shodan の
スキャン日を表示する。

API キーは widget.is に書かず、Secret Vault (クエリ認証 param=key) が
サーバーサイドで注入する。既存の wakatime / hackerone と同じ流儀。

/shodan/host は 1 回につきクエリクレジットを 1 消費するため、
既存ウィジェットの Async:interval による自動更新は採用せず、
結果を Mk:save にキャッシュする。カラムを開き直してもキャッシュを描く
だけで消費はなく、実取得は初回と手動更新のみ。連打も busy で抑止する。

判定は AiScript 1.2.1 の実インタプリタにモック応答を流して検証した
(正常 / クリーン / 未インデックス / 名前解決失敗 / 大文字空白混じり /
IP 直指定 / 不正文字 / 401 / 未設定 の 9 系統)。

アイコンは Shodan 公式ロゴが simple-icons (CC0) に無く商標でもあるため
手貼りせず、lucide の radar で代替した。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
misstore 9a06881 Aug 08 2026, 10:59 PM

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@hitalin, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 59 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 25dba8d4-d908-48dc-9df3-3a8115be6fdb

📥 Commits

Reviewing files that changed from the base of the PR and between 059112a and 9a06881.

⛔ Files ignored due to path filters (1)
  • public/registry/widgets/shodan-instance-audit/icon.svg is excluded by !**/*.svg
📒 Files selected for processing (6)
  • public/registry/index.json
  • public/registry/widgets.json
  • public/registry/widgets/shodan-instance-audit/api.json
  • public/registry/widgets/shodan-instance-audit/meta.json
  • public/registry/widgets/shodan-instance-audit/widget.is
  • scripts/sync-icons.js

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant