add patch tracker scripts response modifier
This commit is contained in:
99
proxychain/responsemodifers/patch_tracker_scripts.go
Normal file
99
proxychain/responsemodifers/patch_tracker_scripts.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package responsemodifers
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"ladder/proxychain"
|
||||
"log"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
//go:embed vendor/ddg-tracker-surrogates/mapping.json
|
||||
var mappingJSON []byte
|
||||
|
||||
//go:embed vendor/ddg-tracker-surrogates/surrogates/*
|
||||
var surrogateFS embed.FS
|
||||
|
||||
var rules domainRules
|
||||
|
||||
func init() {
|
||||
err := json.Unmarshal([]byte(mappingJSON), &rules)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR]: PatchTrackerScripts: failed to deserialize ladder/proxychain/responsemodifers/vendor/ddg-tracker-surrogates/mapping.json")
|
||||
}
|
||||
}
|
||||
|
||||
// mapping.json schema
|
||||
type rule struct {
|
||||
RegexRule *regexp.Regexp `json:"regexRule"`
|
||||
Surrogate string `json:"surrogate"`
|
||||
Action string `json:"action,omitempty"`
|
||||
}
|
||||
|
||||
type domainRules map[string][]rule
|
||||
|
||||
func (r *rule) UnmarshalJSON(data []byte) error {
|
||||
type Tmp struct {
|
||||
RegexRule string `json:"regexRule"`
|
||||
Surrogate string `json:"surrogate"`
|
||||
Action string `json:"action,omitempty"`
|
||||
}
|
||||
|
||||
var tmp Tmp
|
||||
if err := json.Unmarshal(data, &tmp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
regex := regexp.MustCompile(tmp.RegexRule)
|
||||
|
||||
r.RegexRule = regex
|
||||
r.Surrogate = tmp.Surrogate
|
||||
r.Action = tmp.Action
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PatchTrackerScripts replaces any request to tracker scripts such as google analytics
|
||||
// with a no-op stub that mocks the API structure of the original scripts they replace.
|
||||
// Some pages depend on the existence of these structures for proper loading, so this may fix
|
||||
// some broken elements.
|
||||
// Surrogate script code borrowed from: DuckDuckGo Privacy Essentials browser extension for Firefox, Chrome. (Apache 2.0 license)
|
||||
func PatchTrackerScripts() proxychain.ResponseModification {
|
||||
|
||||
return func(chain *proxychain.ProxyChain) error {
|
||||
|
||||
// preflight checks
|
||||
reqURL := chain.Request.URL.String()
|
||||
isTracker := false
|
||||
|
||||
var surrogateScript io.ReadCloser
|
||||
for domain, domainRules := range rules {
|
||||
for _, rule := range domainRules {
|
||||
if !rule.RegexRule.MatchString(reqURL) {
|
||||
continue
|
||||
}
|
||||
|
||||
// found tracker script, replacing response body with nop stub from
|
||||
// ./vendor/ddg-tracker-surrogates/surrogates/{{rule.Surrogate}}
|
||||
isTracker = true
|
||||
script, err := surrogateFS.Open("vendor/ddg-tracker-surrogates/surrogates/" + rule.Surrogate)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
surrogateScript = io.NopCloser(script)
|
||||
log.Printf("INFO: PatchTrackerScripts :: injecting surrogate for '%s' => 'surrogates/%s'\n", domain, rule.Surrogate)
|
||||
break
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if !isTracker {
|
||||
return nil
|
||||
}
|
||||
|
||||
chain.Response.Body = surrogateScript
|
||||
chain.Context.Set("content-type", "text/javascript")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user