PRC008 — Unbounded input or output
| Severity | low |
| OWASP API Security Top 10 | API4:2023 Unrestricted Resource Consumption |
What it catches
Places where the spec lets one request send or receive an unbounded amount of data:
- a request string without
maxLength: the whole body, a property, or the items of a list. Not reported: strings with anenum, and formats whose length is fixed (date,date-time,time,uuid,ipv4,ipv6).byte(base64) is reported: it can be any size; - a request array without
maxItems, including a body that is a list; - a number that sets how much work a request makes without
maximum(or 3.1's numericexclusiveMaximum), in a request body or a query parameter (the operation's, or its path's unless the operation redefines it): a name withlimit,count,repeat,retry/retries,attempt,iteration,per page,page size,batch size,max results(Portuguese:limite,repeticao,tentativa,por pagina,tamanho pagina), in any spelling (pageSize,page_size,pagesize,number_of_repeats). In a query parameter, alsotop,take,depthandsize(?size=is a page size; a body'ssizeusually is not). Not reported: anenum; a word that makes it a value rather than an amount of work, after it (limitPrice,retryAfter,repeatEvery,depthMeters) or before it (creditLimit,rateLimit,stockCount,viewCount). Header parameters and numbers with notypeare not checked. A paging parameter without a maximum makes paging useless:?limit=10000000; - a
GETreturning an array with no paging query parameter (limit,page,per_page,page_size,size,cursor,offset,first,after,starting_after,take,top,skip,page_token, and OData's$top/$skip), on the operation or its path.
OpenAPI 3.1 nullable types count: type: [string, "null"] is a string.
Read-only fields are skipped: the client cannot send them.
It is low: it does not fail the build with the default --fail-on high.
Why it matters
Limits are the first defence against requests built to exhaust the server:
a 50 MB "name", a list of ten million IDs, or one GET that reads every row
of a table. Declaring them in the spec also lets gateways and generated
servers reject oversized requests before your code runs.
How to fix it
name:
type: string
maxLength: 200
ids:
type: array
maxItems: 100
number_of_repeats:
type: integer
maximum: 5
For lists, add paging parameters with a maximum page size:
parameters:
- name: limit
in: query
schema:
type: integer
maximum: 100
- name: cursor
in: query
schema:
type: string
maxLength: 200
How to ignore it
If the finding is fine on purpose, write an x-procyon-ignore on the operation,
with the reason. The finding is still reported, under Ignored, and no
longer fails the run. See ignoring a finding.
/reports/{id}:
get:
x-procyon-ignore:
- rule: PRC008
reason: "Report size is capped by the database view"
Examples
Reported, twice: the list has no paging parameter and note has no
maxLength.
/orders:
get:
responses:
"200":
content:
application/json:
schema:
type: array
items:
type: object
post:
requestBody:
content:
application/json:
schema:
properties:
note:
type: string
Not reported: the same operations with a limit query parameter that has a
maximum, and note with maxLength: 500.