Files
AmirReza Jamali 3e5e135b47 feat(security): Add XSS protection with DOMPurify sanitization
- Add sanitize.ts utility module with sanitizeText(), sanitizeUrl(), and sanitizeHtml() functions
- Implement server-side HTML entity escaping and client-side DOMPurify sanitization
- Add comprehensive test suite for sanitization functions in lib/__tests__/sanitize.test.ts
- Secure marketing pages by sanitizing all CMS data (hero, features, challenges, advantages, footer)
- Secure inquiries form by sanitizing field labels, placeholders, and button text
- Add SECURITY.md documentation outlining XSS protection measures and best practices
- Add USAGE_EXAMPLES.md with detailed examples of sanitization function usage
- Add XSS_PROTECTION_SUMMARY.md with implementation overview
- Update package.json to include dompurify (^3.3.0) dependency
- Protects against common XSS attack vectors including script injection, event handlers, and malicious URLs
2025-11-30 11:14:42 +03:30

104 lines
3.2 KiB
Markdown

# Security - XSS Protection
This document outlines the XSS (Cross-Site Scripting) protection measures implemented in this application.
## Overview
All external data from the CMS API is sanitized using DOMPurify before being rendered to prevent XSS attacks.
## Sanitization Functions
Located in `lib/sanitize.ts`:
### `sanitizeText()`
Strips all HTML tags from text. Use this for plain text content that should never contain HTML.
```typescript
import { sanitizeText } from "@/lib/sanitize";
// Example usage
<h1>{sanitizeText(cmsData?.title)}</h1>;
```
### `sanitizeHtml()`
Allows specific HTML tags while removing dangerous content. Use this when you need to render formatted text.
```typescript
import { sanitizeHtml } from "@/lib/sanitize";
// Example usage with default allowed tags (b, i, em, strong, a, br, p)
<div dangerouslySetInnerHTML={{ __html: sanitizeHtml(cmsData?.content) }} />
// Example with custom allowed tags
<div dangerouslySetInnerHTML={{ __html: sanitizeHtml(cmsData?.content, ["p", "br"]) }} />
```
### `sanitizeUrl()`
Sanitizes URLs to prevent javascript:, data:, and vbscript: URI attacks.
```typescript
import { sanitizeUrl } from "@/lib/sanitize";
// Example usage
<Link href={sanitizeUrl(cmsData?.link) || "#"}>Click here</Link>
<Image src={sanitizeUrl(cmsData?.imageUrl) || "/fallback.svg"} />
```
## Protected Areas
The following components have been secured:
1. **Marketing Pages** (`app/marketing/[id]/page.tsx`)
- Hero section (title, description, button text, links)
- Features section (titles, descriptions, icons)
- Challenges section (titles, descriptions, icons)
- Advantages section (titles, descriptions, icons)
- Footer (email, phone, location, tagline, copyright)
2. **Inquiries Form** (`app/_inquires/form.tsx`, `app/_inquires/page.tsx`)
- Form field labels and placeholders
- Submit button text
- Section titles and descriptions
## Best Practices
1. **Always sanitize external data** - Any data from APIs, databases, or user input should be sanitized
2. **Use the right function** - Use `sanitizeText()` for plain text, `sanitizeUrl()` for URLs, and `sanitizeHtml()` for formatted content
3. **Validate on the server** - While client-side sanitization helps, always validate and sanitize on the server as well
4. **Keep DOMPurify updated** - Regularly update the DOMPurify package to get the latest security fixes
## Server-Side Rendering
The sanitization functions work in both client and server environments:
- **Server-side**: Uses HTML entity escaping to prevent XSS attacks
- **Client-side**: Uses DOMPurify for advanced HTML sanitization
This hybrid approach ensures:
1. Fast server-side rendering without heavy dependencies
2. Robust client-side protection with DOMPurify
3. No build issues with Node.js-specific modules
## Dependencies
- `dompurify` (^3.3.0) - HTML sanitization library (client-side only)
## Testing XSS Protection
To verify XSS protection is working, try injecting malicious content through the CMS:
```javascript
// These should be sanitized and rendered harmless:
<script>alert('XSS')</script>
<img src=x onerror=alert('XSS')>
javascript:alert('XSS')
<iframe src="javascript:alert('XSS')"></iframe>
```
All of these should be stripped or neutralized by the sanitization functions.