Escaping, sanitization and capabilities

Requirements for code that extends POM Events. Attendee data makes this stricter than a typical WordPress integration.

Capabilities

Check the capability that matches the action, not a role name:

Action Capability
Reading or writing an event edit_post for that event
Managing events generally edit_posts
Reading attendee data edit_post for the event that owns it
Changing the settings screen manage_options
Managing user accounts created by registration edit_users

Attendee data belongs to the event. Anyone who can edit the event can see it — so an integration must not widen that, for example by exposing attendee data on a screen with a lower requirement.

Nonces

Verify a nonce on every state-changing request you add — an admin form, an AJAX endpoint, a link that performs an action.

Never rely on the presence of a parameter as authorization. For endpoints of your own, verify the nonce and the capability, in that order, before touching data.

Sanitizing input

Value Function
Free text sanitize_text_field()
Multi-line text sanitize_textarea_field()
Email sanitize_email()
URL esc_url_raw()
Integer absint()
Key or slug sanitize_key()
Date Validate the format before storing

Sanitize on the way in. Never store what arrived from a request unprocessed.

Escaping output

Context Function
HTML text esc_html()
Attribute esc_attr()
URL esc_url()
Textarea esc_textarea()
Rich text you intend to allow wp_kses_post()

Attendee-supplied values — names, comments, telephones, countries — are visitor input rendered in the administration. Escape every one of them, in the attendee table and anywhere else you print them.

Export values are not HTML

Exports are written to a file, not into a page. Do not HTML-escape values there; sanitize them as text.

Be aware that the export uses semicolons as separators, so a value containing one affects the file. Free-text comments are the realistic risk.

Personal data

Attendee records contain names, email addresses, telephone numbers, countries and free-text comments that frequently include health, accessibility and dietary information.

Rules for integrations:

  1. Do not expose attendee data publicly. Not in a REST response, not in a shortcode, not in a page.
  2. Do not add event_assistants to a public REST route. It is deliberately not registered for REST.
  3. Do not log it. Debug output persists in places nobody audits.
  4. Do not send it to an external service without a lawful basis and a decision by the site owner.
  5. Restrict any screen you build to the same capability as the event editor.
  6. Consider what your integration adds to exports, since those files circulate.

Emails you send

If you implement the confirmation email the plugin does not send:

  • send it to the address on the registration and nowhere else;
  • do not include other attendees' data;
  • do not add people to marketing lists on the basis of an event registration unless your consent text covers it;
  • escape the content, and remember an email body is not a safe place for unfiltered visitor input.

AJAX endpoints

If you add one:

  • verify a nonce;
  • verify the capability;
  • sanitize every parameter;
  • return only what the caller is entitled to see;
  • keep attendee data out of any unauthenticated endpoint.

Multisite

Events, attendees and settings are per site. An integration that queries across a network must switch sites explicitly and re-check capabilities in each one.

A short review checklist

  • [ ] Every state-changing request checks a nonce and a capability.
  • [ ] Every input is sanitized with the right function.
  • [ ] Every output is escaped for its context.
  • [ ] Attendee data is never rendered publicly.
  • [ ] Nothing personal is written to logs.
  • [ ] Exports you extend contain only what is intended.
  • [ ] The integration is guarded with post_type_exists( 'event' ).