crafted by Mize ↗
Open Repository Intelligence Open Repository Intelligence
CodeLens ACTIVE
CodeLens Engine
StatusOnline
Versionv0.4
ModelClaude Sonnet
Latency—
0
GOOD
改善余地があります
susumuiwamoto1717-stack/vibe-55-haneda-flight-board
非公開APIをブラウザに成りすまして叩き、結果をJSファイルに埋め込むという「動けば正義」精神で動いているが、テストとレート制限だけはちゃんと書いてある几帳面なスクレイパー。
⭐ 0 Stars
·
🍴 0 Forks
·
📝 28 Commits
·
💬 0 Issues
·
🔵 HTML
·
なし(標準ライブラリ http.server + 単一HTML)
🔍 重要ファイル 5 件を精査 全 13 ファイル中 AI が優先度順に選択
0
✦ 品質
0
🛡 セキュリティ
0
⚙ 保守性
📋 概要

Pythonで実装された羽田空港フライト情報表示Webアプリ。fetch_haneda.pyが羽田公式の非公開APIからダイヤを取得してflights_data.jsを生成し、server.pyのローカルHTTPサーバー経由でindex.htmlに配信する構成。

🎯 今すぐ直すべき3点
  1. server.py run_update()内のsubprocess.run([sys.executable, 'fetch_haneda.py'], check=True)はコマンドインジェクションリスクは低いが、/api/updateエンドポイントにはIPベースのアクセス制限(localhostのみ許可)を追加する。現状はローカルネットワーク上の任意ホストからPOSTで外部APIへのリクエストを強制実行できる。
    ↗
  2. fetch_aircraft.py get_key()内でopen(fn).read().strip()を使っているが、ファイル読み込みにtry/exceptがなく、パーミッションエラーや空ファイルで無言クラッシュする。with open(fn) as f: / except (IOError, OSError)でラップし、空文字列の場合は明示的なエラーメッセージを出力するよう修正する。
    ↗
  3. fetch_haneda.py call()関数内でurllib.request.urlopen(req, timeout=30)のHTTPエラー(403/429/5xx)をurllib.error.HTTPErrorでキャッチしていない(truncatedのため全文未確認だが、表示範囲にtry/exceptが存在しない)。HTTPError・URLErrorをキャッチして具体的なエラーメッセージとリトライロジックを追加し、非公開APIの仕様変更時にサイレント失敗しないようにする。
    ↗
🔍 検出された問題 (6件)
🟥 Critical 📄 server.py
/api/updateエンドポイントがlocalhostに未バインド
server.pyはsocketserver.TCPServerをデフォルト(0.0.0.0)でバインドしており、同一ネットワーク上の任意ホストからPOST /api/updateを送信できる。これにより第三者が羽田公式APIへのリクエストを強制実行でき、IPブロックや利用規約違反を引き起こす危険がある。
🟧 Warning 📄 fetch_haneda.py
fetch_haneda.pyのcall()関数にHTTPエラーハンドリングが欠如
表示範囲内のcall()関数にurllib.error.HTTPError/URLErrorのキャッチが見当たらない。羽田公式の非公開APIが403や429を返した場合、例外がスタックトレースとして出力されるだけでflights_data.jsが更新されず、ユーザーには何が起きたか不明なまま古いデータが表示され続ける。(ファイルがtruncatedのため全文未確認)
🟧 Warning 📄 fetch_haneda.py
非公開APIエンドポイントへの依存
fetch_haneda.pyがtokyo-haneda.comの非公開内部API(/app/api/v2/flight/search)を使用しており、ブラウザ風UAやOriginヘッダを偽装してアクセスしている。サイト側の仕様変更・利用規約変更・IPブロックで予告なく全機能が停止するリスクがあり、代替手段がない場合アプリ全体が機能不全になる。
🟧 Warning 📄 fetch_aircraft.py
fetch_aircraft.pyのAPIキーファイル読み込みにエラーハンドリングなし
get_key()内でopen(fn, encoding='utf-8').read().strip()を直接呼んでおり、ファイルのパーミッションエラー・読み取り失敗時にIOErrorが未キャッチのまま伝播する。また空ファイルの場合は空文字列を返してmain()のif not key:チェックに到達するが、その経路のテストが存在しない。
🟨 Suggestion 📄 fetch_aircraft.py
flights_data.jsへの正規表現パースが脆弱
fetch_aircraft.pyのload_data()がre.search(r'window\.HND_FLIGHTS\s*=\s*(\{.*\});?\s*$', txt, re.S)でJSファイルをパースしている。fetch_haneda.pyの出力フォーマットが微妙に変わった場合(末尾改行・コメント追加等)にマッチ失敗してsys.exit()が呼ばれ、機材情報が全件失われる。JSONファイルとして分離するか、より堅牢なパース方法を採用すべき。
🟨 Suggestion 📄 index.html
index.htmlに全ロジックが内蔵されており保守性が低い
READMEに「単一HTML・全ロジック内蔵」と明記されており、滑走路予測ロジック・UI・データ処理が1ファイルに混在していると推定される。機能追加・バグ修正時の影響範囲が特定しにくく、テストも書けない構造になっている。(ファイルは今回の分析対象外)
✅ 良い点
  • tests/test_units.pyのTestConvertクラスがconvert()関数のnullフィールド・空レコード・コードシェア便名など境界ケースを網羅しており、非公開APIの仕様変更によるサイレント破壊を早期検知できる設計になっている
  • server.pyの_lockとUPDATE_INTERVALによるレート制限実装が、threading.Lockで同時実行を防ぎつつ429レスポンスで適切に拒否する二重防護になっており、外部APIへの過負荷を防いでいる
  • fetch_haneda.pyのconvert()関数がAPIレスポンスの各フィールドをor ''パターンで防御的に取得しており、Noneや欠損キーによるKeyError/TypeErrorを抑制している(test_null_fields_from_apiで検証済み)

作り切ることが第一歩。改善を続けることがエンジニアリング。

🔧 リファクタ提案
  • fetch_haneda.pyのcall()関数をurllib.error.HTTPError/URLErrorのtry/exceptでラップし、ステータスコード別のエラーメッセージ(403=ヘッダ不足疑い、429=レート超過)とリトライ待機(time.sleep + exponential backoff)を実装する
  • flights_data.jsをwindow.HND_FLIGHTS埋め込みJSではなく純粋なJSONファイル(flights_data.json)として出力し、fetch_aircraft.pyのload_data()をjson.load()で単純化する。index.htmlはfetch()でJSONを読み込む形に変更する
  • server.pyのTCPServerバインドアドレスを('127.0.0.1', PORT)に変更してlocalhostのみに制限し、run_update()をasyncio.create_subprocess_exec等で非同期化してHTTPリクエストのブロッキングを解消する
🔒 セキュリティ注意点
  • server.pyがデフォルトで0.0.0.0にバインドするため、同一LAN上の他ホストからPOST /api/updateを実行できる。('127.0.0.1', PORT)へのバインド変更、またはdo_POST()冒頭でself.client_address[0] == '127.0.0.1'チェックを追加することで緩和できる
  • fetch_aircraft.pyのAPIキーをaerodatabox_key.txt / key.txtのファイルから読み込む設計は、そのファイルが誤ってgit管理下に入るリスクがある。.gitignoreにaerodatabox_key.txt・key.txtが追加されているか確認し、.env.exampleパターンへの移行を検討すること
📤 PRコメント出力

このレビューをGitHub PRコメントとして貼り付けられるMarkdown形式で出力します。