fixed critical security issues
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user