mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-03 18:22:57 +00:00
9.4 KiB
9.4 KiB
Implementation Guide for Security & Performance Improvements
This guide provides step-by-step instructions for implementing the critical fixes identified in the audit.
1. SEO: Sitemap Generation
Implementation Steps
- Add Sitemap Controller Routes to
internal/routes/routes.go:
// In SetupRootRoutes function
func SetupRootRoutes(r *gin.Engine, db *gorm.DB) {
sitemapCtrl := &controllers.SitemapController{DB: db}
// Sitemap routes
r.GET("/sitemap.xml", sitemapCtrl.GetSitemap)
r.GET("/robots.txt", sitemapCtrl.GetRobotsTxt)
// ... existing routes
}
- Update Settings Model to include
EnableIndexingfield if not present:
// In internal/models/settings.go
type Settings struct {
// ... existing fields
EnableIndexing bool `json:"enable_indexing" gorm:"default:true"`
}
- Test the sitemap:
- Visit
http://localhost:8080/sitemap.xml - Visit
http://localhost:8080/robots.txt - Verify XML structure is valid
- Visit
2. Security: CSRF Protection
Implementation Steps
- Add CSRF Token Endpoint to routes:
// In internal/routes/routes.go
import "fotbal-club/internal/middleware"
func SetupRoutes(api *gin.RouterGroup, db *gorm.DB) {
// Public CSRF token endpoint
api.GET("/csrf-token", middleware.GetCSRFToken)
// Apply CSRF protection to state-changing routes
protected := api.Group("")
protected.Use(middleware.CSRFProtection())
{
// All POST, PUT, PATCH, DELETE routes here
protected.POST("/articles", baseCtrl.CreateArticle)
protected.PUT("/articles/:id", baseCtrl.UpdateArticle)
// ... etc
}
}
- Update Frontend API Service to fetch and include CSRF token:
// In frontend/src/services/api.ts
let csrfToken: string | null = null;
// Fetch CSRF token on app init
export const initCSRF = async () => {
try {
const response = await axios.get(`${API_URL}/csrf-token`);
csrfToken = response.data.csrf_token;
} catch (error) {
console.error('Failed to fetch CSRF token:', error);
}
};
// Add CSRF token to requests
api.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
// Existing auth token logic...
// Add CSRF token for state-changing requests
if (['post', 'put', 'patch', 'delete'].includes(config.method?.toLowerCase() || '')) {
if (csrfToken) {
config.headers = config.headers || {};
(config.headers as any)['X-CSRF-Token'] = csrfToken;
}
}
return config;
},
(error) => Promise.reject(error)
);
- Initialize CSRF in App:
// In frontend/src/index.tsx
import { initCSRF } from './services/api';
// After root.render()
initCSRF();
3. Security: Improved Content-Security-Policy
Implementation Steps
- Update CSP in main.go:
// Replace the existing CSP in main.go middleware
csp := "default-src 'self'; " +
"script-src 'self' https://fonts.googleapis.com https://umami.tdvorak.dev; " +
"style-src 'self' https://fonts.googleapis.com 'unsafe-inline'; " +
"font-src 'self' https://fonts.gstatic.com data:; " +
"img-src 'self' data: https: blob:; " +
"connect-src 'self' https://umami.tdvorak.dev https://zonerama.tdvorak.dev; " +
"frame-src 'self' https://www.youtube.com https://www.youtube-nocookie.com; " +
"object-src 'none'; " +
"base-uri 'self'; " +
"form-action 'self'; " +
"frame-ancestors 'none';"
c.Writer.Header().Set("Content-Security-Policy", csp)
- Handle CSP violations (optional):
// Add CSP report endpoint
r.POST("/api/v1/csp-report", func(c *gin.Context) {
var report map[string]interface{}
if err := c.ShouldBindJSON(&report); err == nil {
logger.Warn("CSP Violation: %+v", report)
}
c.Status(http.StatusNoContent)
})
- Update CSP to include report-uri:
csp += " report-uri /api/v1/csp-report;"
4. Security: Remove Dev Bypass from Production
Implementation Steps
- Update DevBypass middleware in
internal/middleware/auth.go:
func DevBypass() gin.HandlerFunc {
return func(c *gin.Context) {
// ONLY allow in development
if config.AppConfig != nil && config.AppConfig.AppEnv == "development" {
if strings.ToLower(c.GetHeader("X-Dev-Admin")) == "true" {
logger.Warn("Dev bypass used - this should never happen in production!")
c.Set("userRole", "admin")
c.Set("user", &models.User{Role: "admin"})
c.Next()
return
}
}
c.Next()
}
}
- Remove X-Dev-Admin header from frontend in production:
// In frontend/src/services/api.ts
export const api: AxiosInstance = axios.create({
baseURL: API_URL,
headers: {
// Only include dev headers in development
...(process.env.NODE_ENV === 'development'
? { 'X-Dev-Admin': 'true' }
: {}),
},
withCredentials: true,
timeout: 20000,
});
5. Security: HTML Sanitization
Implementation Steps
- Use sanitization in controllers:
// In internal/controllers/base_controller.go
import "fotbal-club/pkg/utils"
func (bc *BaseController) CreateArticle(c *gin.Context) {
// ... existing code ...
// Sanitize HTML content
body.Content = utils.SanitizeHTML(body.Content)
body.Title = utils.RemoveNullBytes(strings.TrimSpace(body.Title))
// ... rest of function
}
- Add frontend sanitization for rich text editor:
cd frontend
npm install dompurify @types/dompurify
// In frontend/src/utils/sanitize.ts
import DOMPurify from 'dompurify';
export const sanitizeHTML = (dirty: string): string => {
return DOMPurify.sanitize(dirty, {
ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'u', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li', 'a', 'img', 'blockquote', 'code', 'pre'],
ALLOWED_ATTR: ['href', 'src', 'alt', 'title', 'target', 'rel'],
});
};
6. Performance: Code Splitting
Implementation Steps
- Use the lazy-loaded App component:
// Update frontend/src/index.tsx
import AppLazy from './App.lazy';
// Replace <App /> with <AppLazy />
root.render(
<React.StrictMode>
<ErrorBoundary>
<HelmetProvider>
<ColorModeScript initialColorMode={theme.config.initialColorMode} />
<AppLazy />
</HelmetProvider>
</ErrorBoundary>
</React.StrictMode>
);
- Verify bundle splitting:
cd frontend
npm run build
Check the build output - you should see multiple chunk files.
7. Performance: Add Bundle Analysis
Implementation Steps
- Install webpack-bundle-analyzer:
cd frontend
npm install --save-dev webpack-bundle-analyzer
npm install --save-dev @craco/craco
- Create craco config if not exists (
frontend/craco.config.js):
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
webpack: {
plugins: {
add: [
process.env.ANALYZE && new BundleAnalyzerPlugin(),
].filter(Boolean),
},
},
};
- Add analysis script to
frontend/package.json:
{
"scripts": {
"analyze": "ANALYZE=true npm run build"
}
}
- Run analysis:
npm run analyze
8. Security: Add Request Size Limits
Implementation Steps
- Add middleware in main.go:
// Add after router initialization
r.Use(func(c *gin.Context) {
// Limit request body size to 10MB (except for upload endpoints)
if !strings.HasPrefix(c.Request.URL.Path, "/api/v1/upload") {
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, 10*1024*1024)
}
c.Next()
})
Testing Checklist
After implementing these changes:
Security Tests
- CSRF token is required for POST/PUT/DELETE requests
- Dev bypass doesn't work in production environment
- CSP blocks inline scripts
- HTML sanitization removes
<script>tags - Request size limit rejects large payloads
SEO Tests
/sitemap.xmlreturns valid XML/robots.txtincludes sitemap reference- Meta descriptions are properly set
- Structured data validates on Google's testing tool
Performance Tests
- Multiple JS chunks are generated on build
- Initial bundle size is reduced
- Pages load incrementally
- Bundle analyzer shows size breakdown
Deployment Notes
-
Environment Variables - Ensure production
.envhas:APP_ENV=production JWT_SECRET=<strong-random-secret> CONTENT_SECURITY_POLICY=<strict-policy> -
Database Migration - Add
EnableIndexingcolumn:ALTER TABLE settings ADD COLUMN enable_indexing BOOLEAN DEFAULT true; -
Frontend Build - Use production build:
cd frontend npm run build -
Testing - Test all critical paths after deployment
Rollback Plan
If issues arise:
- CSRF Issues: Remove
CSRFProtection()middleware temporarily - CSP Issues: Set to
report-onlymode first - Code Splitting Issues: Use original
App.tsxinstead ofApp.lazy.tsx - Sitemap Issues: Comment out sitemap routes
Support
For questions or issues during implementation:
- Check the
COMPREHENSIVE_AUDIT_REPORT.md - Review error logs in
logs/directory - Test in development environment first