Skip to content

Validation

Implementations MUST strictly validate all incoming data to ensure that it is well-formed and adheres to the Versia Protocol. If a request is invalid, the instance MUST reject it with the matching status code.

An implementation may disallow or restrict some user input, but other implementations may not. It SHOULD NOT apply those restrictions to data coming from other instances.

For example, an implementation that disallows HTML in its own Notes does not strip HTML from Notes coming from other instances. It MAY choose to display them differently, but the data itself stays unchanged. Sanitizing HTML before rendering it does not change this: it applies to what is displayed, not to what is stored.

Things to validate include, but are not limited to:

  • The presence of all required fields. See Optional Fields.

  • The format of all fields (for example, integers are not strings and timestamps are in RFC 3339 format). Whether a well-formed date is plausible is up to the implementation.

  • The presence of all required headers.

  • The presence of a valid signature, where one is required.

  • The author of each entity, as described below.

  • The length of all fields. Strings and arrays may be empty, unless their field says otherwise (for example, the username field on a User entity).

    • Limits on fields from other instances SHOULD NOT copy the limits an implementation sets for its own users. For example, an implementation that limits its own users’ bio to 160 characters does not apply that limit to remote Users.
    • Any such limit SHOULD be generous and documented, and SHOULD let Users view the remote original, for example through a link. A limit of 100 000 characters for a bio field is acceptable, but a limit of 160 characters is not.
  • The type and range of all numeric fields.

    • For example, a size field on a Media structure is a non-negative integer, not a negative number or a fractional one.

    All numeric fields in these docs state their type (integer or float). As a rule of thumb, store them in types that hold the full range, such as a 64-bit integer and a double-precision float.

  • The validity of all URLs and URIs (run them through your favorite URL parser).

It is your implementation’s duty to reject data from other instances that does not follow this specification. Accepting invalid data harms your instance and the network as a whole.

Rejecting Entities

Where a rule links here, an instance rejects an entity as follows. If it checks before answering an inbox request, it MUST return a 422 Unprocessable Entity status code. If it processes the entity after answering, it MUST drop the entity.

Authors and Signers

An entity’s author MUST belong to the instance that signed the message carrying it, whether the entity was delivered to an inbox or fetched. This also applies to each entity in a Collection’s items.

An instance MUST reject an entity that breaks this rule.

Entities without an author field state which instance may send them on their own page.

Unknown Fields and Types

Receivers MUST ignore fields they do not recognize on entities and structures, and MUST NOT reject an entity for having them. They do not need to store them. This is what lets a 0.X.Y release add optional fields.

An entity whose type the receiver does not recognize is handled by what kind of type it is:

  • A namespaced type, which belongs to an extension, MUST be answered with a 2xx status code and dropped.
  • Any other type is a core type, and MUST be rejected. Core types only change between X versions, so an unknown one is an invalid entity.

Remote Content

Everything in an entity is written by another instance, and SHOULD be treated as untrusted.

HTML

This page asks implementations not to modify the content they store. They SHOULD sanitize remote HTML before rendering it or passing it to clients, removing at least scripts, event handlers and other active content, to prevent cross-site scripting. RichText lists the elements and attributes to keep.

Outbound Requests

Remote entities contain URLs and domains that an instance then fetches. A hostile entity could point them at the instance’s own network.

When fetching anything named by remote data, instances SHOULD NOT connect to loopback, link-local or private addresses. This SHOULD be checked after DNS resolution and on every redirect. Development setups may be exempted by local configuration.