diff --git a/internal/middleware/block-common-exploits.go b/internal/middleware/block-common-exploits.go new file mode 100644 index 0000000..8a82534 --- /dev/null +++ b/internal/middleware/block-common-exploits.go @@ -0,0 +1,85 @@ +/* + * Copyright 2024 Jonas Kaninda + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package middleware + +import ( + "encoding/json" + "fmt" + "github.com/jkaninda/goma-gateway/pkg/logger" + "net/http" + "regexp" +) + +// BlockExploitsMiddleware Middleware to block common exploits +func BlockExploitsMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Patterns to detect SQL injection attempts + sqlInjectionPattern := regexp.MustCompile(sqlPatterns) + + // Pattern to detect path traversal attempts + pathTraversalPattern := regexp.MustCompile(traversalPatterns) + + // Pattern to detect simple XSS attempts + xssPattern := regexp.MustCompile(xssPatterns) + + // Check query strings + if sqlInjectionPattern.MatchString(r.URL.RawQuery) || + pathTraversalPattern.MatchString(r.URL.Path) || + xssPattern.MatchString(r.URL.RawQuery) { + logger.Error("%s: %s Forbidden - Potential exploit detected", getRealIP(r), r.URL.Path) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusForbidden) + err := json.NewEncoder(w).Encode(ProxyResponseError{ + Success: false, + Code: http.StatusForbidden, + Message: fmt.Sprintf("Forbidden - Potential exploit detected"), + }) + if err != nil { + return + } + return + } + + // Check form data (for POST requests) + if r.Method == http.MethodPost { + if err := r.ParseForm(); err == nil { + for _, values := range r.Form { + for _, value := range values { + if sqlInjectionPattern.MatchString(value) || xssPattern.MatchString(value) { + logger.Error("%s: %s Forbidden - Potential exploit detected", getRealIP(r), r.URL.Path) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusForbidden) + err := json.NewEncoder(w).Encode(ProxyResponseError{ + Success: false, + Code: http.StatusForbidden, + Message: fmt.Sprintf("Forbidden - Potential exploit detected"), + }) + if err != nil { + return + } + return + } + } + } + } + } + + // Pass to the next handler if no exploit patterns were detected + next.ServeHTTP(w, r) + }) +} diff --git a/internal/middleware/middleware.go b/internal/middleware/middleware.go index a6c44f8..48863bc 100644 --- a/internal/middleware/middleware.go +++ b/internal/middleware/middleware.go @@ -34,7 +34,7 @@ func (jwtAuth JwtAuth) AuthMiddleware(next http.Handler) http.Handler { if r.Header.Get(header) == "" { logger.Error("Proxy error, missing %s header", header) w.Header().Set("Content-Type", "application/json") - //Update Origin Cors Headers + //check allowed origin if allowedOrigin(jwtAuth.Origins, r.Header.Get("Origin")) { w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin")) } diff --git a/internal/middleware/var.go b/internal/middleware/var.go new file mode 100644 index 0000000..4e8502c --- /dev/null +++ b/internal/middleware/var.go @@ -0,0 +1,23 @@ +/* + * Copyright 2024 Jonas Kaninda + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package middleware + +// sqlPatterns contains SQL injections patters +const sqlPatterns = `(?i)(union|select|drop|insert|delete|update|create|alter|exec|;|--)` +const traversalPatterns = `\.\./` +const xssPatterns = `(?i)