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() |
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:
- Do not expose attendee data publicly. Not in a REST response, not in a shortcode, not in a page.
- Do not add
event_assistantsto a public REST route. It is deliberately not registered for REST. - Do not log it. Debug output persists in places nobody audits.
- Do not send it to an external service without a lawful basis and a decision by the site owner.
- Restrict any screen you build to the same capability as the event editor.
- 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' ).