# Validation

What a receiver checks in an incoming entity, and what it answers when a check fails.

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](/federation/http#status-codes).

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](#html) 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](/json#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](/signatures#where-signatures-are-required).

- The **author** of each entity, as described [below](#authors-and-signers).

- 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](/json#numbers) (`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](/structures/collection)'s `items`.

An instance **MUST** [reject](#rejecting-entities) 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](/extensions#naming), **MUST** be answered with a `2xx` status code and dropped.
- Any other type is a core type, and **MUST** be [rejected](#rejecting-entities). 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](/structures/rich-text#other-elements-and-attributes) 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.
