Development:
- Dashboard enabled by default
- Accessible at
/_crashless - No authentication required
Production:
- Dashboard disabled by default (
NODE_ENV=production) - Must be explicitly enabled
- Should always use authentication
❌ Bad:
// Dashboard accessible to anyone
app.use(crashless({
enableDashboard: true
}));✅ Good:
// Dashboard behind authentication
app.use(crashless({
enableDashboard: true,
dashboardAuth: (req) => {
return req.ip === '127.0.0.1';
}
}));# Set allowed IPs via environment variable
export DASHBOARD_ALLOWED_IPS="127.0.0.1,10.0.0.1,192.168.1.100"// Automatically uses DASHBOARD_ALLOWED_IPS
app.use(crashless());// Use Express middleware for full control
const requireAuth = (req, res, next) => {
const token = req.headers['authorization'];
if (token !== process.env.DASHBOARD_TOKEN) {
return res.status(403).json({ error: 'Forbidden' });
}
next();
};
app.use('/_crashless', requireAuth, crashlessMiddleware);# Nginx configuration
location /_crashless {
allow 10.0.0.0/8; # Internal network
deny all;
proxy_pass http://localhost:3000;
}Automatic masking:
- Sensitive error messages hidden
- Stack traces not exposed
- Generic error messages shown
// Production mode (NODE_ENV=production)
app.use(crashless({
maskMessages: true // Automatically true
}));
// User sees:
// {
// "success": false,
// "message": "Internal server error",
// "code": "ERR_500"
// }Full details:
- Error messages visible
- Stack traces exposed
- Detailed debugging info
// Development mode
app.use(crashless({
maskMessages: false // Automatically false
}));
// Developer sees:
// {
// "success": false,
// "message": "Database connection failed: postgres://...",
// "code": "DB_ERROR",
// "stack": "Error: Database connection..."
// }If accessed:
- Internal API structure (routes, paths)
- Error patterns and frequencies
- Performance bottlenecks
- Request/response patterns
- Stack traces (if enabled)
- Disable dashboard in production
- Use authentication
- Restrict network access
- Use metrics export instead
app.use(crashless({
dashboardAuth: (req) => {
const ip = req.ip || req.connection?.remoteAddress;
const allowedIPs = ['127.0.0.1', '10.0.0.1'];
return allowedIPs.includes(ip);
}
}));app.use(crashless({
dashboardAuth: (req) => {
const token = req.headers['x-dashboard-token'];
return token === process.env.DASHBOARD_SECRET;
}
}));app.use(crashless({
dashboardAuth: (req) => {
// Check IP
const ip = req.ip || req.connection?.remoteAddress;
if (ip === '127.0.0.1' || ip === '::1') return true;
// Check token
const token = req.headers['x-dashboard-token'];
if (token === process.env.DASHBOARD_SECRET) return true;
// Deny by default
return false;
}
}));- Dashboard enabled is fine
- No authentication needed
- Full error details helpful
- Use IP whitelist
- Restrict to internal network
- Monitor access
- Disable dashboard by default
- Use metrics export endpoints
- If dashboard needed, use strong authentication
- Consider reverse proxy authentication
Security is a critical concern. Always secure dashboard access in production environments.