From 9a42efab0045ab395bba842392a71aff495c34d5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 11 Jan 2026 14:09:17 +0000 Subject: [PATCH 1/3] Initial plan From 17bcfd5a080864cb200c5726e848f1f60a98f0d0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 11 Jan 2026 14:12:02 +0000 Subject: [PATCH 2/3] Add comprehensive edge case tests for NoSQL operator detection Co-authored-by: hyp3rd <62474964+hyp3rd@users.noreply.github.com> --- pkg/sanitize/nosql_detect_test.go | 167 ++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) diff --git a/pkg/sanitize/nosql_detect_test.go b/pkg/sanitize/nosql_detect_test.go index 28c6bd0..e451966 100644 --- a/pkg/sanitize/nosql_detect_test.go +++ b/pkg/sanitize/nosql_detect_test.go @@ -35,3 +35,170 @@ func TestNoSQLInjectionDetectorCustomOperators(t *testing.T) { t.Fatalf("expected ErrNoSQLInjectionDetected, got %v", err) } } + +func TestNoSQLInjectionDetectorEdgeCases(t *testing.T) { + detector, err := NewNoSQLInjectionDetector() + if err != nil { + t.Fatalf("expected detector, got %v", err) + } + + tests := []struct { + name string + input string + wantError bool + }{ + // Dollar sign at end of string + { + name: "dollar at end of string", + input: "price$", + wantError: false, + }, + { + name: "dollar at end after text", + input: "total_usd$", + wantError: false, + }, + // Dollar sign followed by non-alphabetic characters + { + name: "dollar followed by digit", + input: "$123", + wantError: false, + }, + { + name: "dollar followed by special char", + input: "$@#%", + wantError: false, + }, + { + name: "dollar followed by space", + input: "$ ", + wantError: false, + }, + { + name: "dollar followed by underscore", + input: "$_test", + wantError: false, + }, + // Dollar sign followed by valid characters but not matching any operator + { + name: "dollar with unknown operator", + input: "$unknown", + wantError: false, + }, + { + name: "dollar with non-operator word", + input: "$hello", + wantError: false, + }, + { + name: "dollar with random letters", + input: "$xyz", + wantError: false, + }, + // Operators at start of string + { + name: "operator at start", + input: "$ne", + wantError: true, + }, + { + name: "operator at start with value", + input: "$where:true", + wantError: true, + }, + // Operators after various delimiters + { + name: "operator after open brace", + input: "{$ne:null}", + wantError: true, + }, + { + name: "operator after open bracket", + input: "[$in:[1,2]]", + wantError: true, + }, + { + name: "operator after comma", + input: "a,$gt:5", + wantError: true, + }, + { + name: "operator after colon", + input: "field:$lt:10", + wantError: true, + }, + { + name: "operator after double quote", + input: `"$regex":"pattern"`, + wantError: true, + }, + { + name: "operator after single quote", + input: `'$exists':true`, + wantError: true, + }, + { + name: "operator after open paren", + input: "($or:[a,b])", + wantError: true, + }, + { + name: "operator after whitespace", + input: " $and", + wantError: true, + }, + { + name: "operator after newline", + input: "\n$nor", + wantError: true, + }, + { + name: "operator after tab", + input: "\t$not", + wantError: true, + }, + // Mixed cases - dollar not at boundary + { + name: "dollar in middle of word", + input: "price$value", + wantError: false, + }, + { + name: "dollar after letter no boundary", + input: "a$ne", + wantError: false, + }, + // Multiple operators + { + name: "multiple operators", + input: `{"$ne":1,"$gt":2}`, + wantError: true, + }, + // Case sensitivity checks + { + name: "operator uppercase", + input: "$NE", + wantError: true, + }, + { + name: "operator mixed case", + input: "$Ne", + wantError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := detector.Detect(tt.input) + if tt.wantError { + if err != ErrNoSQLInjectionDetected { + t.Errorf("expected ErrNoSQLInjectionDetected for input %q, got %v", tt.input, err) + } + } else { + if err != nil { + t.Errorf("expected no error for input %q, got %v", tt.input, err) + } + } + }) + } +} From e91a4f75c60954431cdf4dc2e5362bd577a525dd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 11 Jan 2026 14:13:26 +0000 Subject: [PATCH 3/3] Fix case sensitivity test comments - operators are normalized to lowercase Co-authored-by: hyp3rd <62474964+hyp3rd@users.noreply.github.com> --- pkg/sanitize/nosql_detect_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/sanitize/nosql_detect_test.go b/pkg/sanitize/nosql_detect_test.go index e451966..55475ef 100644 --- a/pkg/sanitize/nosql_detect_test.go +++ b/pkg/sanitize/nosql_detect_test.go @@ -174,14 +174,14 @@ func TestNoSQLInjectionDetectorEdgeCases(t *testing.T) { input: `{"$ne":1,"$gt":2}`, wantError: true, }, - // Case sensitivity checks + // Case sensitivity checks - operators are normalized to lowercase { - name: "operator uppercase", + name: "operator uppercase detected", input: "$NE", wantError: true, }, { - name: "operator mixed case", + name: "operator mixed case detected", input: "$Ne", wantError: true, },