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

未关闭 适合新手
#1,149 1 条评论 0 个 reaction 已指派 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 小时
30 天内合并 PR
28

环境准备

在 Codespaces 中打开

在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。

  • 提供 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

OWASP/OpenCRE 的其他 Issue

查看 OWASP/OpenCRE 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。