fix: backend error interceptor
This commit is contained in:
@@ -30,7 +30,7 @@ func (blockList AccessListMiddleware) AccessMiddleware(next http.Handler) http.H
|
|||||||
for _, block := range blockList.List {
|
for _, block := range blockList.List {
|
||||||
if isPathBlocked(r.URL.Path, util.ParseURLPath(blockList.Path+block)) {
|
if isPathBlocked(r.URL.Path, util.ParseURLPath(blockList.Path+block)) {
|
||||||
logger.Error("%s: %s access forbidden", getRealIP(r), r.URL.Path)
|
logger.Error("%s: %s access forbidden", getRealIP(r), r.URL.Path)
|
||||||
RespondWithError(w, http.StatusForbidden, fmt.Sprintf("%d you do not have permission to access this resource"))
|
RespondWithError(w, http.StatusForbidden, fmt.Sprintf("%d you do not have permission to access this resource", http.StatusForbidden))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,18 +19,13 @@ package middleware
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
errorinterceptor "github.com/jkaninda/goma-gateway/pkg/errorinterceptor"
|
|
||||||
"github.com/jkaninda/goma-gateway/pkg/logger"
|
"github.com/jkaninda/goma-gateway/pkg/logger"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BlockCommon struct {
|
|
||||||
ErrorInterceptor errorinterceptor.ErrorInterceptor
|
|
||||||
}
|
|
||||||
|
|
||||||
// BlockExploitsMiddleware Middleware to block common exploits
|
// BlockExploitsMiddleware Middleware to block common exploits
|
||||||
func (blockCommon BlockCommon) BlockExploitsMiddleware(next http.Handler) http.Handler {
|
func BlockExploitsMiddleware(next http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
// Patterns to detect SQL injection attempts
|
// Patterns to detect SQL injection attempts
|
||||||
sqlInjectionPattern := regexp.MustCompile(sqlPatterns)
|
sqlInjectionPattern := regexp.MustCompile(sqlPatterns)
|
||||||
|
|||||||
@@ -45,15 +45,12 @@ func (intercept InterceptErrors) ErrorInterceptor(next http.Handler) http.Handle
|
|||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
rec := newResponseRecorder(w)
|
rec := newResponseRecorder(w)
|
||||||
next.ServeHTTP(rec, r)
|
next.ServeHTTP(rec, r)
|
||||||
|
w.Header().Set("Proxied-By", "Goma Gateway")
|
||||||
|
w.Header().Del("Server") //Delete server name
|
||||||
if canIntercept(rec.statusCode, intercept.Errors) {
|
if canIntercept(rec.statusCode, intercept.Errors) {
|
||||||
logger.Debug("Backend error")
|
logger.Debug("An error occurred in the backend, %d", rec.statusCode)
|
||||||
logger.Error("An error occurred from the backend with the status code: %d", rec.statusCode)
|
logger.Error("Backend error: %d", rec.statusCode)
|
||||||
//Update Origin Cors Headers
|
|
||||||
if allowedOrigin(intercept.Origins, r.Header.Get("Origin")) {
|
|
||||||
w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin"))
|
|
||||||
}
|
|
||||||
RespondWithError(w, rec.statusCode, http.StatusText(rec.statusCode))
|
RespondWithError(w, rec.statusCode, http.StatusText(rec.statusCode))
|
||||||
return
|
|
||||||
} else {
|
} else {
|
||||||
// No error: write buffered response to client
|
// No error: write buffered response to client
|
||||||
w.WriteHeader(rec.statusCode)
|
w.WriteHeader(rec.statusCode)
|
||||||
@@ -61,7 +58,6 @@ func (intercept InterceptErrors) ErrorInterceptor(next http.Handler) http.Handle
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,5 @@ func RespondWithError(w http.ResponseWriter, statusCode int, logMessage string)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import (
|
|||||||
// RateLimiter defines requests limit properties.
|
// RateLimiter defines requests limit properties.
|
||||||
type RateLimiter struct {
|
type RateLimiter struct {
|
||||||
requests int
|
requests int
|
||||||
id int
|
id string
|
||||||
window time.Duration
|
window time.Duration
|
||||||
clientMap map[string]*Client
|
clientMap map[string]*Client
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
@@ -42,7 +42,7 @@ type Client struct {
|
|||||||
ExpiresAt time.Time
|
ExpiresAt time.Time
|
||||||
}
|
}
|
||||||
type RateLimit struct {
|
type RateLimit struct {
|
||||||
Id int
|
Id string
|
||||||
Requests int
|
Requests int
|
||||||
Window time.Duration
|
Window time.Duration
|
||||||
Origins []string
|
Origins []string
|
||||||
|
|||||||
@@ -62,13 +62,12 @@ func (gatewayServer GatewayServer) Initialize() *mux.Router {
|
|||||||
// Enable common exploits
|
// Enable common exploits
|
||||||
if gateway.BlockCommonExploits {
|
if gateway.BlockCommonExploits {
|
||||||
logger.Info("Block common exploits enabled")
|
logger.Info("Block common exploits enabled")
|
||||||
blockCommon := middleware.BlockCommon{}
|
r.Use(middleware.BlockExploitsMiddleware)
|
||||||
r.Use(blockCommon.BlockExploitsMiddleware)
|
|
||||||
}
|
}
|
||||||
if gateway.RateLimit > 0 {
|
if gateway.RateLimit > 0 {
|
||||||
// Add rate limit middleware to all routes, if defined
|
// Add rate limit middleware to all routes, if defined
|
||||||
rateLimit := middleware.RateLimit{
|
rateLimit := middleware.RateLimit{
|
||||||
Id: 1,
|
Id: "global_rate", //Generate a unique ID for routes
|
||||||
Requests: gateway.RateLimit,
|
Requests: gateway.RateLimit,
|
||||||
Window: time.Minute, // requests per minute
|
Window: time.Minute, // requests per minute
|
||||||
Origins: gateway.Cors.Origins,
|
Origins: gateway.Cors.Origins,
|
||||||
@@ -232,16 +231,13 @@ func (gatewayServer GatewayServer) Initialize() *mux.Router {
|
|||||||
// Apply common exploits to the route
|
// Apply common exploits to the route
|
||||||
// Enable common exploits
|
// Enable common exploits
|
||||||
if route.BlockCommonExploits {
|
if route.BlockCommonExploits {
|
||||||
blockCommon := middleware.BlockCommon{
|
|
||||||
ErrorInterceptor: route.ErrorInterceptor,
|
|
||||||
}
|
|
||||||
logger.Info("Block common exploits enabled")
|
logger.Info("Block common exploits enabled")
|
||||||
router.Use(blockCommon.BlockExploitsMiddleware)
|
router.Use(middleware.BlockExploitsMiddleware)
|
||||||
}
|
}
|
||||||
// Apply route rate limit
|
// Apply route rate limit
|
||||||
if route.RateLimit > 0 {
|
if route.RateLimit > 0 {
|
||||||
rateLimit := middleware.RateLimit{
|
rateLimit := middleware.RateLimit{
|
||||||
Id: rIndex,
|
Id: string(rune(rIndex)), // Use route index as ID
|
||||||
Requests: route.RateLimit,
|
Requests: route.RateLimit,
|
||||||
Window: time.Minute, // requests per minute
|
Window: time.Minute, // requests per minute
|
||||||
Origins: route.Cors.Origins,
|
Origins: route.Cors.Origins,
|
||||||
|
|||||||
Reference in New Issue
Block a user