Help mij mijn React-app te beveiligen tegen veelvoorkomende kwetsbaarheden
description
Met deze prompt ontvang je gerichte adviezen om je React-applicatie effectief te beveiligen tegen veelvoorkomende aanvallen. Je leert best practices voor veilige code, wat helpt om datalekken en misbruik te voorkomen. Dit is essentieel voor betrouwbare en professionele webapps.
prompt
Help mij mijn React-applicatie te beveiligen tegen veelvoorkomende beveiligingsproblemen zoals XSS, CSRF, en onveilige data handling. Beschrijf best practices en imp ...
try_prompt
generate_helper
disclaimerOnPageApi
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier zijn enkele best practices en voorbeelden om je React-applicatie verder te beveiligen tegen XSS, CSRF en onveilige data handling, naast je bestaande maatregelen zoals JWT en regex-validatie.
1. Beveiliging tegen XSS (Cross-Site Scripting):
Best Practices:
- Escape alle dynamische inhoud voordat je deze in de DOM plaatst.
- Gebruik React's JSX, dat standaard escaping toepast.
- Vermijd het gebruik van `dangerouslySetInnerHTML` tenzij strikt noodzakelijk, en dan alleen met gezuiverde inhoud.
- Gebruik beveiligde libraries voor sanitatie van invoer, zoals DOMPurify.
Voorbeeld:
```jsx
import DOMPurify from 'dompurify';
function SafeContent({ html }) {
const cleanHtml = DOMPurify.sanitize(html);
return <div dangerouslySetInnerHTML={{ __html: cleanHtml }} />;
}
```
2. Beveiliging tegen CSRF (Cross-Site Request Forgery):
Best Practices:
- Gebruik CSRF-tokens. Als je backend dit ondersteunt, voeg deze tokens toe aan elke POST/PUT/DELETE verzoeken.
- Bij API's die JWT gebruiken, is CSRF minder een probleem als je JWT in de Authorization-header opslaat, omdat dit niet automatisch meegestuurd wordt met cross-origin requests.
- Overweeg het gebruik van SameSite cookies (bijvoorbeeld `SameSite=Strict` of `Lax`) voor sessiebeheer.
Voorbeeld (bij gebruik van cookies):
```js
// Bij instellen van cookies op server zijde
Set-Cookie: sessionId=abc123; SameSite=Strict; Secure; HttpOnly
```
3. Veilige Data Handling:
- Validatie:
- Gebruik niet alleen regex, maar ook uitgebreide validatie bibliotheken zoals Yup of Joi voor schema-validatie.
- Controleer gegevens zowel client-side (voor gebruiksvriendelijkheid) als server-side (voor veiligheid).
- Authenticatie en Autorisatie:
- JWT gebruiken is goed, maar controleer tokens op serverzijde voor verval en geldigheid.
- Implementeer Role-Based Access Control (RBAC) om gebruikersrechten te beheren.
Voorbeeld van role-based autorisatie:
```jsx
function ProtectedComponent({ userRole }) {
if (userRole !== 'admin') {
return <div>Geen toegang</div>;
}
return <div>Geheime inhoud voor admins</div>;
}
```
4. Additional Security Tips:
- HTTPS:
- Zorg dat je applicatie altijd via HTTPS bereikbaar is om data te versleutelen.
- Content Security Policy (CSP):
- Stel een CSP in via headers om XSS te beperken.
```http
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none';
```
- Secure Headers:
- Voeg beveiligingsheaders toe zoals `X-Content-Type-Options: nosniff`, `X-Frame-Options: DENY`, etc.
Samengevat:
- Gebruik React's JSX voor escaping.
- Sanitize invoer met DOMPurify.
- Beveilig API-verzoeken met CSRF-tokens en SameSite cookies.
- Valideer data uitgebreid met validation libraries.
- Beheer rollen en rechten voor autorisatie.
- Implementeer HTTPS en beveiligingsheaders.
Wil je dat ik een specifiek voorbeeld voor jouw app opstel of hulp bij een bepaald beveiligingsaspect?
provider: deepseek
model: deepseek-chat
Zeker, hier een uitgebreid overzicht van best practices voor het beveiligen van je React-applicatie:
## 1. XSS (Cross-Site Scripting) Preventie
### Input Sanitizatie
```jsx
// Gebruik DOMPurify voor input sanitizatie
import DOMPurify from 'dompurify';
const SafeComponent = ({ userInput }) => {
const cleanInput = DOMPurify.sanitize(userInput);
return <div dangerouslySetInnerHTML={{ __html: cleanInput }} />;
};
// Of beter: vermijd dangerouslySetInnerHTML helemaal
const SafeTextComponent = ({ text }) => {
return <div>{text}</div>; // React escapt automatisch
};
```
### Content Security Policy (CSP)
```html
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'">
```
## 2. Verbeterde Input Validatie
### Gebruik bibliotheken voor validatie
```jsx
import * as yup from 'yup';
import { useFormik } from 'formik';
const validationSchema = yup.object({
email: yup.string().email('Ongeldig email').required('Verplicht'),
password: yup.string()
.min(8, 'Minimaal 8 karakters')
.matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/,
'Moet hoofdletter, kleine letter en nummer bevatten'),
username: yup.string()
.matches(/^[a-zA-Z0-9_]+$/, 'Alleen letters, nummers en underscores')
});
const LoginForm = () => {
const formik = useFormik({
initialValues: { email: '', password: '' },
validationSchema,
onSubmit: values => { /* handle submit */ }
});
return (
<form onSubmit={formik.handleSubmit}>
<input
name="email"
value={formik.values.email}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
{formik.touched.email && formik.errors.email && (
<div className="error">{formik.errors.email}</div>
)}
</form>
);
};
```
## 3. Veilige JWT Implementatie
### Secure Token Handling
```jsx
// authService.js
class AuthService {
constructor() {
this.tokenKey = 'auth_token';
}
// Token opslaan in httpOnly cookie (via backend) of secure storage
setToken(token) {
// Voor client-side: gebruik secure storage
if (typeof window !== 'undefined') {
localStorage.setItem(this.tokenKey, token);
// Of beter: sessionStorage voor betere beveiliging
}
}
getToken() {
if (typeof window !== 'undefined') {
return localStorage.getItem(this.tokenKey);
}
return null;
}
removeToken() {
if (typeof window !== 'undefined') {
localStorage.removeItem(this.tokenKey);
}
}
// Token validatie
isTokenValid() {
const token = this.getToken();
if (!token) return false;
try {
const payload = JSON.parse(atob(token.split('.')[1]));
return payload.exp * 1000 > Date.now();
} catch {
return false;
}
}
}
```
### Axios Interceptor voor Authenticatie
```jsx
// apiClient.js
import axios from 'axios';
const apiClient = axios.create({
baseURL: process.env.REACT_APP_API_URL,
});
apiClient.interceptors.request.use((config) => {
const token = localStorage.getItem('auth_token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
apiClient.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
// Token is ongeldig, redirect naar login
localStorage.removeItem('auth_token');
window.location.href = '/login';
}
return Promise.reject(error);
}
);
```
## 4. CSRF Bescherming
### Anti-CSRF Token Implementatie
```jsx
// CSRF token management
const getCSRFToken = () => {
return document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
};
// Voeg CSRF token toe aan requests
apiClient.interceptors.request.use((config) => {
const csrfToken = getCSRFToken();
if (csrfToken && ['post', 'put', 'patch', 'delete'].includes(config.method?.toLowerCase())) {
config.headers['X-CSRF-Token'] = csrfToken;
}
return config;
});
```
## 5. Autorizatie Implementatie
### Role-Based Access Control (RBAC)
```jsx
// hooks/useAuth.js
import { useState, useEffect } from 'react';
export const useAuth = () => {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const checkAuth = async () => {
const token = localStorage.getItem('auth_token');
if (token && isTokenValid(token)) {
try {
const userData = await apiClient.get('/user/profile');
setUser(userData);
} catch (error) {
localStorage.removeItem('auth_token');
}
}
setLoading(false);
};
checkAuth();
}, []);
const hasPermission = (permission) => {
return user?.permissions?.includes(permission);
};
const hasRole = (role) => {
return user?.roles?.includes(role);
};
return { user, loading, hasPermission, hasRole };
};
// Protected Route Component
const ProtectedRoute = ({ children, requiredPermission }) => {
const { user, loading, hasPermission } = useAuth();
if (loading) return <div>Loading...</div>;
if (!user) return <Navigate to="/login" replace />;
if (requiredPermission && !hasPermission(requiredPermission)) {
return <div>Geen toegang</div>;
}
return children;
};
```
## 6. Veilige Data Handling
### API Response Sanitizatie
```jsx
// safeDataHandler.js
export const sanitizeUserInput = (data) => {
if (typeof data === 'string') {
return DOMPurify.sanitize(data);
}
if (Array.isArray(data)) {
return data.map(item => sanitizeUserInput(item));
}
if (typeof data === 'object' && data !== null) {
return Object.keys(data).reduce((acc, key) => {
acc[key] = sanitizeUserInput(data[key]);
return acc;
}, {});
}
return data;
};
// Gebruik in component
const UserProfile = ({ userData }) => {
const safeData = sanitizeUserInput(userData);
return (
<div>
<h1>{safeData.name}</h1>
<p>{safeData.bio}</p>
</div>
);
};
```
## 7. Environment Variabelen en Configuratie
```jsx
// .env.example
REACT_APP_API_URL=https://api.jedomein.nl
REACT_APP_DEBUG=false
REACT_APP_VERSION=1.0.0
// config.js
export const config = {
apiUrl: process.env.REACT_APP_API_URL,
isDebug: process.env.REACT_APP_DEBUG === 'true',
version: process.env.REACT_APP_VERSION,
// Security config
maxLoginAttempts: 5,
sessionTimeout: 30 * 60 * 1000, // 30 minuten
};
```
## 8. Additional Security Headers
Voeg deze headers toe aan je server response:
```
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
```
## Belangrijkste Aanbevelingen:
1. **Gebruik altijd HTTPS** in productie
2. **Implementeer rate limiting** op de backend
3. **Gebruik HttpOnly cookies** voor JWT opslag waar mogelijk
4. **Houd dependencies up-to-date** met `npm audit`
5. **Voer regelmatig security scans** uit
6. **Implementeer logging** voor verdachte activiteiten
Deze maatregelen samen zullen je applicatie aanzienlijk beter beveiligen tegen veelvoorkomende aanvallen.