fixed critical security issues

This commit is contained in:
Mazyar
2026-05-25 13:23:49 +03:30
parent 51defd9438
commit da2d50bd70
4 changed files with 34 additions and 14 deletions
+2
View File
@@ -248,6 +248,8 @@ func main() {
// Initialize HTTP server // Initialize HTTP server
e := bootstrap.InitHTTPServer(conf, logger) e := bootstrap.InitHTTPServer(conf, logger)
router.SetupCSPSecurity(e)
// Register routes // Register routes
router.RegisterAdminRoutes(e, userHandler, companyHandler, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, inquiryHandler, categoryHandler, flagHandler, notificationHandler, contactHandler, cmsHandler, kanbanHandler, fileStoreHandler, dashboardHandler, xssPolicy) router.RegisterAdminRoutes(e, userHandler, companyHandler, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, inquiryHandler, categoryHandler, flagHandler, notificationHandler, contactHandler, cmsHandler, kanbanHandler, fileStoreHandler, dashboardHandler, xssPolicy)
router.RegisterPublicRoutes(e, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, companyHandler, inquiryHandler, categoryHandler, flagHandler, notificationHandler, contactHandler, cmsHandler, fileStoreHandler, xssPolicy) router.RegisterPublicRoutes(e, customerHandler, tenderHandler, feedbackHandler, tenderApprovalHandler, companyHandler, inquiryHandler, categoryHandler, flagHandler, notificationHandler, contactHandler, cmsHandler, fileStoreHandler, xssPolicy)
+9 -13
View File
@@ -22,17 +22,20 @@ import (
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler *company.Handler, customerHandler *customer.Handler, tenderHandler *tender.TenderHandler, feedbackHandler *feedback.Handler, tenderApprovalHandler *tender_approval.Handler, inquiryHandler *inquiry.Handler, categoryHandler *company_category.Handler, flagHandler *assets.Handler, notificationHandler *notification.NotificationHandler, contactHandler *contact.Handler, cmsHandler *cms.Handler, kanbanHandler *kanban.Handler, fileStoreHandler *filestore.Handler, dashboardHandler *dashboard.Handler, xssPolicy *security.XSSPolicy) { // SetupCSPSecurity registers global CSP middleware and the CSP report endpoint once.
adminV1 := e.Group("/admin/v1") func SetupCSPSecurity(e *echo.Echo) {
// Add CSP middleware to admin routes (stricter policy)
adminCSPConfig := security.DefaultCSPConfig() adminCSPConfig := security.DefaultCSPConfig()
adminCSPConfig.ScriptSrc = []string{"'self'"} // No unsafe-inline for admin adminCSPConfig.ScriptSrc = []string{"'self'"} // No unsafe-inline for admin
adminCSPConfig.StyleSrc = []string{"'self'"} // No unsafe-inline for admin adminCSPConfig.StyleSrc = []string{"'self'"} // No unsafe-inline for admin
e.Use(security.CSPMiddleware(adminCSPConfig))
// Add CSP report endpoint publicCSPConfig := security.DefaultCSPConfig()
e.Use(security.CSPMiddlewareForPaths("/admin", adminCSPConfig, "/api/v1", publicCSPConfig))
e.POST("/api/v1/csp-report", security.CSPReportHandler) e.POST("/api/v1/csp-report", security.CSPReportHandler)
}
func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler *company.Handler, customerHandler *customer.Handler, tenderHandler *tender.TenderHandler, feedbackHandler *feedback.Handler, tenderApprovalHandler *tender_approval.Handler, inquiryHandler *inquiry.Handler, categoryHandler *company_category.Handler, flagHandler *assets.Handler, notificationHandler *notification.NotificationHandler, contactHandler *contact.Handler, cmsHandler *cms.Handler, kanbanHandler *kanban.Handler, fileStoreHandler *filestore.Handler, dashboardHandler *dashboard.Handler, xssPolicy *security.XSSPolicy) {
adminV1 := e.Group("/admin/v1")
// Admin Users Routes // Admin Users Routes
adminUsersGP := adminV1.Group("/users") adminUsersGP := adminV1.Group("/users")
@@ -221,13 +224,6 @@ func RegisterAdminRoutes(e *echo.Echo, userHandler *user.Handler, companyHandler
func RegisterPublicRoutes(e *echo.Echo, customerHandler *customer.Handler, tenderHandler *tender.TenderHandler, feedbackHandler *feedback.Handler, tenderApprovalHandler *tender_approval.Handler, companyHandler *company.Handler, inquiryHandler *inquiry.Handler, categoryHandler *company_category.Handler, flagHandler *assets.Handler, notificationHandler *notification.NotificationHandler, contactHandler *contact.Handler, cmsHandler *cms.Handler, fileStoreHandler *filestore.Handler, xssPolicy *security.XSSPolicy) { func RegisterPublicRoutes(e *echo.Echo, customerHandler *customer.Handler, tenderHandler *tender.TenderHandler, feedbackHandler *feedback.Handler, tenderApprovalHandler *tender_approval.Handler, companyHandler *company.Handler, inquiryHandler *inquiry.Handler, categoryHandler *company_category.Handler, flagHandler *assets.Handler, notificationHandler *notification.NotificationHandler, contactHandler *contact.Handler, cmsHandler *cms.Handler, fileStoreHandler *filestore.Handler, xssPolicy *security.XSSPolicy) {
v1 := e.Group("/api/v1") v1 := e.Group("/api/v1")
// Add CSP middleware to public routes
cspConfig := security.DefaultCSPConfig()
e.Use(security.CSPMiddleware(cspConfig))
// Add CSP report endpoint
e.POST("/api/v1/csp-report", security.CSPReportHandler)
customerGP := v1.Group("/profile") customerGP := v1.Group("/profile")
{ {
customerGP.POST("/login", customerHandler.Login) customerGP.POST("/login", customerHandler.Login)
+2 -1
View File
@@ -1,6 +1,7 @@
package document_scraper package document_scraper
import ( import (
"crypto/subtle"
"strings" "strings"
"tm/pkg/response" "tm/pkg/response"
@@ -25,7 +26,7 @@ func APIKeyMiddleware(apiKey string) echo.MiddlewareFunc {
return response.Unauthorized(c, "API key required. Use X-API-Key header or Authorization: ApiKey <key>") return response.Unauthorized(c, "API key required. Use X-API-Key header or Authorization: ApiKey <key>")
} }
if apiKeyHeader != apiKey { if subtle.ConstantTimeCompare([]byte(apiKeyHeader), []byte(apiKey)) != 1 {
return response.Unauthorized(c, "Invalid API key") return response.Unauthorized(c, "Invalid API key")
} }
+21
View File
@@ -108,6 +108,27 @@ func CSPMiddleware(config *CSPConfig) echo.MiddlewareFunc {
} }
} }
// CSPMiddlewareForPaths applies CSP middleware based on request path prefix.
// Requests matching no prefix proceed without a CSP header.
func CSPMiddlewareForPaths(adminPrefix string, adminConfig *CSPConfig, publicPrefix string, publicConfig *CSPConfig) echo.MiddlewareFunc {
adminMW := CSPMiddleware(adminConfig)
publicMW := CSPMiddleware(publicConfig)
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
path := c.Request().URL.Path
switch {
case strings.HasPrefix(path, adminPrefix):
return adminMW(next)(c)
case strings.HasPrefix(path, publicPrefix):
return publicMW(next)(c)
default:
return next(c)
}
}
}
}
// CSPReportHandler handles CSP violation reports // CSPReportHandler handles CSP violation reports
func CSPReportHandler(c echo.Context) error { func CSPReportHandler(c echo.Context) error {
var report struct { var report struct {