find_node_by_name endpoint does not enforce MAX_ITEMS_PER_PAGE, allowing unbounded pagination queries`

オープン 初心者向け
#1,149 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@Jeffy123-zhu がすでに取り組んでいます。

2026年10月17日 から。

  • #1150 @vishalmore90 による — オープン

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
88/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
python
領域
api, backend

調査の方向性

application/web/web_main.py から始めてください。find_node_by_name は request.args から items_per_page を読み取り (261 行目付近)、database.get_nodes_with_pagination に渡しています (272 行目付近)。all_cres ハンドラと比較してください。こちらは 1538 行目付近で min(per_page, MAX_ITEMS_PER_PAGE) を使って値を上限で制限しています。同じ上限を追加し、application/tests/web_main_test.py の test_find_node_by_name の隣に回帰テストを追加してください。items_per_page が大きい値のリクエストで、結果が最大 MAX_ITEMS_PER_PAGE 件に収まれば完了です。

索引モデルが issue の本文から書いたものです。

説明

What is the issue?

MAX_ITEMS_PER_PAGE (value: 100) is defined in
application/web/web_main.py line 57
but is never enforced on the find_node_by_name endpoint
(GET /rest/v1/<ntype>/<name> and all its route aliases).

The endpoint reads items_per_page directly from the query-string and passes
the raw integer to database.get_nodes_with_pagination() with no upper-bound
check:

# web_main.py  line 261
items_per_page = request.args.get("items_per_page") or ITEMS_PER_PAGE

# …passed straight in at line 272 with no min/max guard:
total_pages, nodes, _ = database.get_nodes_with_pagination(
    …
    items_per_page=int(items_per_page),
    …
)

By contrast, the all_cres endpoint correctly caps the value:

# web_main.py  line 1538
per_page = min(per_page, MAX_ITEMS_PER_PAGE)

find_node_by_name is the primary browsing API used by the SPA for every
standard/tool/code lookup. A caller can request an arbitrarily large page
(e.g. ?items_per_page=999999), causing the ORM to execute an unbounded
SELECT … LIMIT 999999 OFFSET … against the SQLite/Postgres database.


Expected Behaviour

GET /rest/v1/standard/OWASP%20Top%2010?items_per_page=999999 should behave
identically to ?items_per_page=100 — returning at most MAX_ITEMS_PER_PAGE
results, with total_pages calculated accordingly.


Actual Behaviour

The server honours any positive integer for items_per_page and issues an
unbounded paginate query. For large enough values (or on databases with many
sections per standard) this can:

  1. Degrade server response time — the ORM materialises the full result set
    into Python objects before serialising to JSON.
  2. Cause excessive memory pressure — every matched Node + all its Links
    are loaded into memory.
  3. Allow resource-exhaustion abuse — any unauthenticated caller can trigger
    it, because find_node_by_name requires no auth.

Steps to reproduce
  1. Start a local instance with a populated database (e.g. make dev after
    make import-all).
  2. Run:
    curl -s "http://127.0.0.1:5000/rest/v1/standard/OWASP%20Top%2010?items_per_page=100000" | python -m json.tool | head -5
    
  3. Observe: the server responds with all matching rows without any limit error.

Alternatively, confirm in code:

  • web_main.py L57: MAX_ITEMS_PER_PAGE = 100 (defined but unused on this route)
  • web_main.py L261: items_per_page = request.args.get("items_per_page") or ITEMS_PER_PAGE (no cap applied)
  • web_main.py L272: items_per_page=int(items_per_page) (raw value forwarded to DB)
  • Compare with web_main.py L1538: per_page = min(per_page, MAX_ITEMS_PER_PAGE) (correct guard on all_cres)

Proposed Fix

In find_node_by_name, apply the same guard used by all_cres:

# web_main.py  ~line 261
items_per_page = int(request.args.get("items_per_page") or ITEMS_PER_PAGE)
items_per_page = min(items_per_page, MAX_ITEMS_PER_PAGE)   # ← add this line

A regression test should be added alongside test_find_node_by_name in
application/tests/web_main_test.py (currently only all_cres has a test
for this cap — see line 1523).

主要言語
Python
スター
210
フォーク
167
平均マージ
4日 12時間
マージ済み PR(30日)
28

環境構築

Codespaces で開く

このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

OWASP/OpenCRE のほかの issue

OWASP/OpenCRE の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。