Appearance
Trusted admin content (XSS)
ExchangePro includes CMS-style features: admins can publish HTML and scripts that the frontend renders on the public site. This is intentional so you can style legal pages, blog posts, and SEO snippets — but it means only trusted people should have admin access.
Trusted administrators only
Anyone with admin panel access can change site-wide HTML, CSS, and scripts. Treat admin accounts like root access to your brand and your visitors’ browsers.
Where raw HTML / scripts are used
| Feature | Admin location | How it appears on the site |
|---|---|---|
| Legal pages | Settings → Legal pages | Page body rendered with v-html at /{slug} |
| Blog posts | Blog → create/edit post | Article body rendered with v-html on /blog/{slug} |
| Blog head script | Blog → “Schema / custom head script” | Injected via useHead (e.g. JSON-LD, analytics) |
| Custom CSS | Settings → Custom CSS | Injected globally in <style> via useHead |
| Subscriber emails | Subscribers → broadcast | HTML email body (admin-only send) |
Customer-submitted content (support tickets, contact form, exchange proof files) is not rendered as arbitrary HTML on public pages in the same way.
Security model
- Admin-only write — Only users with
role = admincan create or edit this content (API middleware + admin routes). - No public HTML editor — Regular customers cannot post raw HTML to the marketing site or blog.
- Buyer responsibility — You choose who gets admin access, use strong passwords, HTTPS, and disable public registration when appropriate.
This product does not ship a full HTML sanitizer (e.g. DOMPurify) on legal/blog bodies by default. Sanitizing rich CMS HTML often breaks legitimate formatting; ExchangePro assumes you trust your admins.
Recommendations
| Practice | Why |
|---|---|
| Limit admin accounts | Fewer people who can inject scripts |
| Use strong passwords + HTTPS | Protect admin sessions |
| Turn off public registration after launch | Stops strangers from becoming admin (first signup rule) |
| Review legal/blog content before publish | Catch copy-paste from untrusted sources |
| Do not paste unknown HTML from the web | Pasted markup can include hidden scripts |
| Prefer blog “head script” for JSON-LD only | Avoid arbitrary JavaScript unless you understand it |
Optional hardening (customization)
If your threat model requires sanitization, you can extend the frontend, for example:
- Run legal page and blog HTML through DOMPurify (or similar) before
v-html. - Allow only a safe tag whitelist (
p,a,ul,strong, etc.). - Strip
<script>,on*event attributes, andjavascript:URLs.
That is a custom code change — not included in the default package. Test thoroughly after adding sanitization (editors and embeds may break).
Custom CSS and blog head scripts cannot be fully “sanitized” without losing their purpose; keep those fields admin-only and empty unless you need them.
First registrant becomes admin
Until an admin exists, the first successful signup receives role = admin. That is a bootstrap feature, not a bug — but it is a serious risk if /signup is public before you register.
See First admin account for the production checklist (register first, then disable registration).
Related docs
- First admin account — bootstrap and lock-down
- Admin panel — where CMS content is managed
- Troubleshooting — login and API issues