> ## Documentation Index
> Fetch the complete documentation index at: https://vlyai-1c28d863.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# XSS and CSRF

> How vly handles cross-site scripting and cross-site request forgery. What you should still watch for.

## XSS (Cross-Site Scripting)

**Most XSS in React is automatic** — JSX escapes string interpolation by default. The dangerous patterns:

<CardGroup cols={2}>
  <Card title="❌ dangerouslySetInnerHTML on user input" icon="x-circle">
    Renders raw HTML. If the input is user-controlled, sanitize first.
  </Card>

  <Card title="❌ Unsanitized markdown with raw HTML enabled" icon="x-circle">
    Most markdown libraries disable raw HTML by default. Don't enable it for user input.
  </Card>

  <Card title="❌ Setting `href` from user input" icon="x-circle">
    `javascript:...` URLs execute on click. Validate and only allow `http://` / `https://` / `mailto:`.
  </Card>

  <Card title="✅ Plain JSX interpolation" icon="check-circle">
    `<div>{userText}</div>` — safe. Auto-escaped.
  </Card>
</CardGroup>

### Sanitizing

```typescript theme={null}
import DOMPurify from "dompurify";
const safeHtml = DOMPurify.sanitize(userHtml);
// then: <div dangerouslySetInnerHTML={{ __html: safeHtml }} />
```

For markdown, prefer [react-markdown](https://github.com/remarkjs/react-markdown) — safe by default.

## CSRF (Cross-Site Request Forgery)

vly's auth uses HTTP-only, SameSite=Lax cookies, which **prevents standard CSRF**. The cookie is sent only on same-site navigations and same-site fetches; cross-site `POST` requests don't include the auth cookie.

If you implement custom auth or accept requests from other origins (CORS), you'll need:

* CSRF tokens for state-changing requests.
* Origin / Referer header validation.
* SameSite=Strict for higher protection (with the UX tradeoff).

## Content Security Policy (CSP)

vly serves a default CSP that:

* Allows scripts only from the app's own origin.
* Allows images from the app + Convex storage CDN.
* Denies inline event handlers.

To add allowed hosts (e.g., your analytics provider), configure in `app/layout.tsx` or the Convex HTTP route.

## Tips

<Tip>
  **Treat all external input as hostile.** That includes URL params, form values, file uploads, and webhook payloads.
</Tip>

<Tip>
  **Use a Content Security Policy in production.** Prevents XSS even if a bug slips through.
</Tip>

## Related

<CardGroup cols={3}>
  <Card title="Input validation" icon="check-circle" href="/security/input-validation">
    First line of defense.
  </Card>

  <Card title="Auth best practices" icon="lock" href="/security/auth-best-practices">
    Auth-specific guidance.
  </Card>

  <Card title="Security overview" icon="shield" href="/security/overview">
    Broader model.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.