diff options
Diffstat (limited to 'internal/scope/scope.go')
| -rw-r--r-- | internal/scope/scope.go | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/internal/scope/scope.go b/internal/scope/scope.go new file mode 100644 index 0000000..d8d2e80 --- /dev/null +++ b/internal/scope/scope.go @@ -0,0 +1,61 @@ +// Package scope filters which captured traffic gets recorded to +// history - a target scope, in Burp's sense: out-of-scope requests +// still proxy through completely normally (nothing is blocked), they +// just aren't stored, so unrelated CDN/analytics/tracker noise doesn't +// pollute history and search on a real engagement. Deliberately not an +// access-control mechanism; that would be a materially different, +// riskier feature (breaking a workflow by silently blocking traffic is +// a much worse failure mode than a noisier history). +package scope + +import ( + "regexp" + "strings" +) + +// Rule is one scope entry. A non-regex Pattern matches by substring +// containment against the host (case-insensitive) - "example.com" +// matches "example.com", "www.example.com", and "api.example.com" +// alike, covering the common "this domain and its subdomains" case +// without inventing a separate wildcard syntax. IsRegex switches to a +// full regex match against the host, mirroring the same toggle +// match-and-replace rules already use, for the same reason: one +// consistent mental model across both rule types in this tool. +type Rule struct { + ID int64 + Enabled bool + Pattern string + IsRegex bool +} + +// InScope reports whether host should be recorded, given rules. +// An empty rule set (or one with nothing enabled) means "no scope +// configured" - everything is in scope, matching this tool's behavior +// before scope existed at all, so a fresh install or a user who never +// opens the scope view keeps recording everything, not silently +// nothing. Once at least one rule is enabled, only a host matching one +// of them is in scope. +func InScope(rules []Rule, host string) bool { + anyEnabled := false + for _, r := range rules { + if !r.Enabled { + continue + } + anyEnabled = true + if ruleMatches(r, host) { + return true + } + } + return !anyEnabled +} + +func ruleMatches(r Rule, host string) bool { + if r.IsRegex { + re, err := regexp.Compile(r.Pattern) + if err != nil { + return false + } + return re.MatchString(host) + } + return strings.Contains(strings.ToLower(host), strings.ToLower(r.Pattern)) +} |