Skip to content
moxon home

6.2.0

API

API v6.2.0 — Security release: abusive inputs are bounded on every version, /cron dates fixed in some timezones.

Security

  • This is a security release: the issues found by an audit of the whole API are fixed, endpoint by endpoint. No endpoint is added or removed. A legitimate request gets exactly the same response as before; only abusive inputs are now refused, with the usual 400 error, or bounded. Two changes are visible: /cron on v5 and v6, whose dates were wrong in some timezones (missing or repeated dates east of UTC, and a schedule at local midnight skipped right after a daylight-saving change) and are now correct, and /chat, which now keeps only the last 200 messages of a room.
  • Exceptionally, v4 and v5 receive these fixes too, although they are otherwise frozen: the same limits and refusals apply to every version that has the endpoint, and v6 follows v5. Each item below says which versions it concerns, and the page of each endpoint gives the exact limits and error messages.

Endpoints

  • /captcha (v4, v5 and v6): the text parameter is capped at 32 characters. On v5 and v6, the signed token of a challenge can no longer be forged or exchanged for a token of another kind: a /pow token no longer verifies as a captcha token, nor the reverse. A token is burnt after 5 wrong answers and then answers used. POST /captcha also accepts an optional minLength: a right answer to a captcha generated shorter than that is refused with the reason weak. Without minLength, nothing changes.
  • /barcode (v4, v5 and v6): the data of the variable-length formats, code128 and code39, is capped at 128 characters (Data cannot exceed 128 characters). The fixed-length formats ean13, ean8 and upca are not concerned.
  • /regex (v4, v5 and v6): the evaluation of a pattern is interrupted after 25 ms and answers 400 with Pattern took too long to evaluate, so a catastrophic pattern can no longer block the server. A pattern or text key repeated in the query is refused like a missing one. A pattern that finishes in time returns the same matches as before.
  • /cron: on v5 and v6, dates were missing or repeated in timezones east of UTC, and a schedule at local midnight could be skipped right after a daylight-saving change; the results are now correct. v4 keeps its previous results. On all three versions, a cron expression that can never match, such as 0 0 31 2 *, ends at once with an empty list instead of running until its limit, and a search is bounded in time (250 ms on v5 and v6, 1 s on v4): the dates found until then are returned.
  • /chat and /tic-tac-toe (v4, v5 and v6): their inputs are bounded, a username to 100 characters (1000 for the fetch action of /chat, which is keyed by the reader's IP address), a message to 1000 and a session, game or private chat identifier to 256 (Message cannot exceed 1000 characters). Names such as __proto__ or constructor are now ordinary values. /chat keeps the last 200 messages of the public room and of each private chat, allows at most 1000 private chats at a time (Too many active private chats), and replaces a client timestamp that cannot be stored as sent, an object or a text over 128 characters, with the server date.
  • /qrcode (the icon parameter) and /hyperplanning (v4, v5 and v6) fetch remote files through a guarded fetch: internal addresses are refused after name resolution and on every redirect, and redirects are capped at 10. A calendar stops at 1 MB and 5000 events, an icon at 2 MB and 16 megapixels (Icon must be under 16 megapixels). Deprecated
  • POST /asymmetric (v5 and v6): RSA key pairs are now generated off the main thread, two at a time, so a large key no longer freezes the server for the other requests. The response is the same.

Server

  • The rate limiter counts against the instance-wide limit only the requests it admits, so a client being refused can no longer use up the budget of the others. An IPv6 client is counted by its /64 block, an IPv4-mapped IPv6 address by its IPv4 form, and each /48 network is capped at four times the hourly quota of one client (Too many requests from your network., 429). A forwarded address that is not an IP address counts as the connecting peer.
  • The security headers are now sent first, so every response carries them, and request bodies, still capped at 10 kB, are parsed after the rate limiter, so malformed bodies are counted too.
  • When TRUSTED_PROXIES is unset, the server keeps assuming exactly one reverse proxy and now logs a warning at startup. That default is right behind a single proxy such as nginx or Caddy; exposed directly, callers can forge the X-Forwarded-For header and pick their own address, and behind several hops every caller is counted as the nearest proxy. The README explains when to set the variable.

Package

  • New asymmetricAsync export, available from @moxon/api, @moxon/api/v5 and @moxon/api/v6: it takes the same arguments and returns the same result as asymmetric, as a promise, and generates RSA key pairs on the thread pool, at most two at a time. POST /asymmetric uses it.
  • The experimental Manifest export is not touched by this release: it still lists only hash, and describing the other endpoints as contracts is planned for a later release. Experimental
  • Dependencies are updated: body-parser goes to 2.4.0, with the qs (6.16.1) and iconv-lite (0.7.3) it uses. These versions are pinned in the repository's package-lock.json: they protect clones and deployments done with npm ci.

Documentation

  • The page of each endpoint touched by the release states its new limits: the parameters, the exact error messages and a note on what is bounded. POST /captcha documents its new minLength parameter. Exceptionally, the pages of v4 and v5 are updated too, for these limits and refusals only.
  • The Authentication page explains how requests are counted, per /64 block and per /48 network for IPv6, and the list of 429 errors of the home includes Too many requests from your network..
  • The Instance page lists TRUSTED_PROXIES and GLOBAL_LIMIT among the settings of an instance you run, with a warning on matching the proxy chain.