Merge pull request #978 from Molecule-AI/fix/security-discord-config-limitreader

fix(security): cap Discord webhook + config PATCH bodies (H3/H4)
This commit is contained in:
Hongming Wang 2026-04-19 01:28:46 -07:00 committed by GitHub
commit bf08a7edd9
2 changed files with 11 additions and 2 deletions

View File

@ -106,7 +106,11 @@ func (d *DiscordAdapter) SendMessage(ctx context.Context, config map[string]inte
// Returns nil, nil for PING payloads — the handler layer must respond with `{"type":1}` to pass
// Discord's endpoint verification. Returns an InboundMessage for APPLICATION_COMMAND payloads.
func (d *DiscordAdapter) ParseWebhook(c *gin.Context, _ map[string]interface{}) (*InboundMessage, error) {
body, err := io.ReadAll(c.Request.Body)
// Cap incoming webhook bodies at 1 MiB. Discord's Interactions API
// payloads are well under 10 KiB in practice; the cap is a DoS
// guard, not a functional limit.
const maxDiscordWebhook = 1 << 20
body, err := io.ReadAll(io.LimitReader(c.Request.Body, maxDiscordWebhook))
if err != nil {
return nil, fmt.Errorf("discord: read body: %w", err)
}

View File

@ -42,9 +42,14 @@ func (h *ConfigHandler) Get(c *gin.Context) {
func (h *ConfigHandler) Patch(c *gin.Context) {
workspaceID := c.Param("id")
// 256 KiB cap: Postgres jsonb comfortably handles this and real
// configs are <10 KiB. The cap blocks naive memory-exhaustion DoS
// — a caller streaming a gigabyte of JSON would OOM the instance.
const maxConfigBody = 256 << 10
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, maxConfigBody)
body, err := io.ReadAll(c.Request.Body)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "failed to read body"})
c.JSON(http.StatusRequestEntityTooLarge, gin.H{"error": "body too large or unreadable"})
return
}