Skip to main content
Glama
orneryd

M.I.M.I.R - Multi-agent Intelligent Memory & Insight Repository

by orneryd
security_integration_test.go5.52 kB
// Package server provides HTTP REST API server tests. package server import ( "net/http/httptest" "os" "testing" ) // TestSecurityMiddleware_Integration verifies security middleware blocks attacks at server level func TestSecurityMiddleware_Integration(t *testing.T) { server, authenticator := setupTestServer(t) handler := server.buildRouter() // Get valid token for authenticated endpoints (uses existing helper) validToken := getAuthToken(t, authenticator, "admin") tests := []struct { name string method string path string headers map[string]string expectedStatus int description string }{ { name: "valid request", method: "GET", path: "/health", headers: map[string]string{ "User-Agent": "NornicDB-Client/1.0", }, expectedStatus: 200, description: "Normal requests should pass through", }, { name: "CRLF injection in header", method: "GET", path: "/health", headers: map[string]string{ "User-Agent": "Evil\r\nX-Malicious: injected", }, expectedStatus: 400, description: "CRLF injection should be blocked", }, { name: "XSS in authorization token", method: "GET", path: "/status", headers: map[string]string{ "Authorization": "Bearer <script>alert('xss')</script>", }, expectedStatus: 401, // Invalid token returns 401 (security middleware validates THEN auth middleware rejects) description: "XSS in token should be blocked", }, { name: "protocol smuggling in callback URL", method: "GET", path: "/auth/token?callback=file:///etc/passwd", headers: map[string]string{ "Authorization": "Bearer " + validToken, }, expectedStatus: 400, description: "Protocol smuggling should be blocked", }, { name: "SSRF to private IP", method: "GET", path: "/auth/token?redirect_uri=http://192.168.1.1/steal", headers: map[string]string{ "Authorization": "Bearer " + validToken, }, expectedStatus: 400, description: "SSRF to private IPs should be blocked", }, { name: "SSRF to metadata service", method: "GET", path: "/auth/token?webhook=http://169.254.169.254/latest/meta-data/", headers: map[string]string{ "Authorization": "Bearer " + validToken, }, expectedStatus: 400, description: "SSRF to cloud metadata should be blocked", }, { name: "null byte in header", method: "GET", path: "/health", headers: map[string]string{ "User-Agent": "Valid\x00Evil", }, expectedStatus: 400, description: "Null bytes should be blocked", }, { name: "data URI injection", method: "GET", path: "/auth/token?url=data:text/html,<script>alert('xss')</script>", headers: map[string]string{ "Authorization": "Bearer " + validToken, }, expectedStatus: 400, description: "Data URI injection should be blocked", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { req := httptest.NewRequest(tt.method, tt.path, nil) // Add headers for key, value := range tt.headers { req.Header.Set(key, value) } w := httptest.NewRecorder() handler.ServeHTTP(w, req) if w.Code != tt.expectedStatus { t.Errorf("%s: got status %d, want %d\nResponse: %s", tt.description, w.Code, tt.expectedStatus, w.Body.String()) } }) } } // TestSecurityMiddleware_DevelopmentMode verifies localhost is allowed in development func TestSecurityMiddleware_DevelopmentMode(t *testing.T) { // Set development environment oldEnv := os.Getenv("NORNICDB_ENV") os.Setenv("NORNICDB_ENV", "development") defer os.Setenv("NORNICDB_ENV", oldEnv) server, authenticator := setupTestServer(t) handler := server.buildRouter() validToken := getAuthToken(t, authenticator, "admin") tests := []struct { name string path string expectedStatus int description string }{ { name: "localhost allowed in dev", path: "/auth/token?callback=http://localhost:3000/callback", expectedStatus: 405, // Endpoint requires POST, but middleware passes (no 400) description: "Localhost should be allowed in development mode", }, { name: "127.0.0.1 allowed in dev", path: "/auth/token?redirect_uri=http://127.0.0.1:8080/redirect", expectedStatus: 405, // Endpoint requires POST, but middleware passes (no 400) description: "127.0.0.1 should be allowed in development mode", }, { name: "private IP still blocked in dev", path: "/auth/token?callback=http://192.168.1.1/steal", expectedStatus: 400, // Middleware blocks BEFORE route handler (SSRF protection) description: "Other private IPs should still be blocked", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { req := httptest.NewRequest("GET", tt.path, nil) req.Header.Set("Authorization", "Bearer "+validToken) w := httptest.NewRecorder() handler.ServeHTTP(w, req) if w.Code != tt.expectedStatus { t.Errorf("%s: got status %d, want %d\nResponse: %s", tt.description, w.Code, tt.expectedStatus, w.Body.String()) } }) } } // TestSecurityMiddleware_Performance benchmarks overhead func BenchmarkSecurityMiddleware(b *testing.B) { server, _ := setupTestServer(&testing.T{}) handler := server.buildRouter() req := httptest.NewRequest("GET", "/health", nil) req.Header.Set("User-Agent", "Benchmark") b.ResetTimer() for i := 0; i < b.N; i++ { w := httptest.NewRecorder() handler.ServeHTTP(w, req) } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/orneryd/Mimir'

If you have feedback or need assistance with the MCP directory API, please join our Discord server