Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Limit body size for all requests

オープン
#950 コメント 5 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
50/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
静か
技術スタック
go
領域
api, backend, security

調査の方向性

api/plugin.go の UpdateConfig から始め、router/router.go を通じたリクエスト処理を追跡します。また、影響を受けるアクセスパスについて api/user.go、auth/authentication.go、plugin/manager.go も確認します。関連するサーバーテストを実行し、/message および /plugin/{id}/config を含むリクエストに対して、設定可能なデフォルトのボディサイズ制限が適用され、有効なペイロードが拒否されないことを確認できたら作業完了とします。

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

説明

a:bug

We should limit the body size for all requests. It's currently possible to send big messages to /message or big yaml configs to /plugin/{id}/config.

I guess a good default could be something like 10MB, but it should be configurable.

Email Report

Summary

Gotify Server's plugin configuration update feature accepts
attacker-controlled YAML bodies at POST /plugin/{id}/config.
Confirmed in v2.9.1, when registration=true and at least one
installed plugin supports Configurer, an unauthenticated remote
attacker can self-register and submit an oversized configuration body to
trigger severe memory pressure and persistent configuration storage
growth.

Details

UpdateConfig verifies plugin ownership and Configurer support, but
then immediately calls io.ReadAll(ctx.Request.Body) with no size
limit. The full request body is buffered before YAML parsing or
plugin-side validation, so any reachable caller can force memory
allocation proportional to the submitted body size. After validation,
the handler stores the original bytes in conf.Config, which turns the
same endpoint into a persistence amplifier rather than only a transient
parse-time sink.

conf, err := c.DB.GetPluginConfByID(id)
...
if aborted := supportOrAbort(ctx, instance, compat.Configurer); aborted { return }
newconfBytes, err := io.ReadAll(ctx.Request.Body)
...
if err := yaml.Unmarshal(newconfBytes, newConf); err != nil { ... }
if err := instance.ValidateAndSetConfig(newConf); err != nil { ... }
conf.Config = newconfBytes

When registration=true, POST /user is reachable under
authentication.Optional() and allows unauthenticated non-admin
account creation. User creation triggers fireUserAdded, which
initializes per-user instances for all installed plugins, and
RequireClient accepts Basic Auth directly. The attacker can then call
GET /plugin to enumerate a plugin instance whose capabilities
include configurer, fetch the current YAML from
GET /plugin/{id}/config, and reuse that id against
POST /plugin/{id}/config.

Because the handler stores raw YAML bytes rather than a normalized
representation, the attacker can append large YAML comment blocks to an
otherwise valid configuration. yaml.Unmarshal ignores comments, but
the oversized original document is still persisted as
PluginConf.Config. I verified the unbounded body read and raw-byte
persistence in api/plugin.go, and the self-registration plus Basic
Auth reachability in api/user.go, router/router.go,
auth/authentication.go, and plugin/manager.go. I did not identify
a fixed version from the current materials.

PoC

  1. Ensure the target runs Gotify Server v2.9.1 with
    registration=true and at least one installed plugin whose
    /plugin entry lists configurer in capabilities.

  2. Create a normal account:

POST /user
Content-Type: application/json

{"name":"pocuser","pass":"PocPassw0rd!"}
  1. Use Basic Auth for that account to call GET /plugin, select an
    entry whose capabilities array contains configurer, then fetch
    its current YAML from GET /plugin/{id}/config.

  2. Append a large number of YAML comment lines to the returned document
    and submit it back:

POST /plugin/{id}/config
Authorization: Basic <base64(pocuser:PocPassw0rd!)>
Content-Type: application/x-yaml

<original valid YAML>
# padding 000001
# padding 000002
...
  1. Observe high memory pressure during the request. If the YAML remains
    otherwise valid, a subsequent GET /plugin/{id}/config returns the
    enlarged document, confirming that the oversized raw body was
    persisted.

Impact

Observed impact is a conditional unauthenticated network denial of
service in deployments that allow self-registration and have at least
one installed Configurer plugin: a remote attacker can consume
process memory with a single oversized request and can repeatedly
enlarge persisted plugin configuration data. Where registration is
disabled, the same bug remains reachable to a low-privilege
authenticated user. I did not confirm confidentiality or integrity
impact from current evidence.

主要言語
Go
スター
16k
フォーク
878
平均マージ
2日 15時間
マージ済み PR(30日)
5

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

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

gotify/server のほかの issue

gotify/server の issue をすべて見る

似ている issue

Go の issue をもっと見る

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

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