Skip to content

Security

Lists only show what the user may see and only accept what the collection declares.

  • The query of the resource: tenant scope, scopeQuery() and the view permission of the resource.
  • Lists, related lists and exports leave out records a policy does not let the user view. Rows that should never be listed belong into scopeQuery() as well: the total and the pages count the rows of the query, so a page may show fewer rows than its size.
  • Filters and the search run after these restrictions and can only narrow the list.
  • All values are escaped; columns cannot output HTML from the database.
  • Foreign keys are shown as titles of records the user may see (Relationships), users by username only. Internal ids are not shown.
  • Counts of related records only count what the user could open (CountColumn).
  • Links go to the detail pages of records the user may view, or to configured systems (Links); arbitrary URLs cannot be linked.

Only declared columns can be searched, sorted or filtered, and only with declared values: page size, sort column and direction, view, hidden columns and every filter input have validation rules. Requests with other values are rejected (HTTP 422). In the search, % and _ are matched literally; only * is a wildcard.

All list requests go through the component endpoint: signed component tokens, CSRF protection and the permission checks of every action.

SelectColumn, ToggleColumn, CheckboxColumn and TextInputColumn require <slug>.update and pass the policies of the record, locked workflow states and the rules of the field in the form. Each column has its own action, nothing else can be written.

Selecting and deleting records requires <slug>.delete, checked per record including policies. Deleting a selection is all or nothing.