add localstorage clearer, sessionstorage cleaer, and cachebuster modifiers
This commit is contained in:
@@ -32,25 +32,27 @@ func NewProxySiteHandler(opts *ProxyOptions) fiber.Handler {
|
|||||||
SetFiberCtx(c).
|
SetFiberCtx(c).
|
||||||
SetDebugLogging(opts.Verbose).
|
SetDebugLogging(opts.Verbose).
|
||||||
SetRequestModifications(
|
SetRequestModifications(
|
||||||
// rx.SpoofJA3fingerprint(ja3, "Googlebot"),
|
//rx.SpoofJA3fingerprint(ja3, "Googlebot"),
|
||||||
// rx.MasqueradeAsFacebookBot(),
|
rx.AddCacheBusterQuery(),
|
||||||
// rx.MasqueradeAsGoogleBot(),
|
rx.MasqueradeAsGoogleBot(),
|
||||||
rx.DeleteOutgoingCookies(),
|
|
||||||
rx.ForwardRequestHeaders(),
|
rx.ForwardRequestHeaders(),
|
||||||
// rx.SpoofReferrerFromGoogleSearch(),
|
rx.DeleteOutgoingCookies(),
|
||||||
rx.SpoofReferrerFromLinkedInPost(),
|
rx.SpoofReferrerFromRedditPost(),
|
||||||
// rx.RequestWaybackMachine(),
|
//rx.SpoofReferrerFromLinkedInPost(),
|
||||||
// rx.RequestArchiveIs(),
|
//rx.RequestWaybackMachine(),
|
||||||
|
//rx.RequestArchiveIs(),
|
||||||
).
|
).
|
||||||
AddResponseModifications(
|
AddResponseModifications(
|
||||||
tx.ForwardResponseHeaders(),
|
//tx.ForwardResponseHeaders(),
|
||||||
|
tx.DeleteIncomingCookies(),
|
||||||
|
tx.DeleteLocalStorageData(),
|
||||||
|
tx.DeleteSessionStorageData(),
|
||||||
tx.BypassCORS(),
|
tx.BypassCORS(),
|
||||||
tx.BypassContentSecurityPolicy(),
|
tx.BypassContentSecurityPolicy(),
|
||||||
// tx.DeleteIncomingCookies(),
|
|
||||||
tx.RewriteHTMLResourceURLs(),
|
tx.RewriteHTMLResourceURLs(),
|
||||||
tx.PatchTrackerScripts(),
|
tx.PatchTrackerScripts(),
|
||||||
tx.PatchDynamicResourceURLs(),
|
tx.PatchDynamicResourceURLs(),
|
||||||
tx.BlockElementRemoval(".article-content"),
|
//tx.BlockElementRemoval(".article-content"),
|
||||||
// tx.SetContentSecurityPolicy("default-src * 'unsafe-inline' 'unsafe-eval' data: blob:;"),
|
// tx.SetContentSecurityPolicy("default-src * 'unsafe-inline' 'unsafe-eval' data: blob:;"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
http "github.com/bogdanfinn/fhttp"
|
http "github.com/bogdanfinn/fhttp"
|
||||||
tls_client "github.com/bogdanfinn/tls-client"
|
tls_client "github.com/bogdanfinn/tls-client"
|
||||||
|
profiles "github.com/bogdanfinn/tls-client/profiles"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -192,15 +193,6 @@ func (chain *ProxyChain) _initializeRequest() (*http.Request, error) {
|
|||||||
return nil, fmt.Errorf("unsupported request method from client: '%s'", chain.Context.Method())
|
return nil, fmt.Errorf("unsupported request method from client: '%s'", chain.Context.Method())
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// copy client request headers to upstream request headers
|
|
||||||
forwardHeaders := func(key []byte, val []byte) {
|
|
||||||
req.Header.Set(string(key), string(val))
|
|
||||||
}
|
|
||||||
clientHeaders := &chain.Context.Request().Header
|
|
||||||
clientHeaders.VisitAll(forwardHeaders)
|
|
||||||
*/
|
|
||||||
|
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,9 +304,10 @@ func (chain *ProxyChain) SetFiberCtx(ctx *fiber.Ctx) *ProxyChain {
|
|||||||
url, err := chain.extractURL()
|
url, err := chain.extractURL()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
chain.abortErr = chain.abort(err)
|
chain.abortErr = chain.abort(err)
|
||||||
|
} else {
|
||||||
|
chain.Request.URL = url
|
||||||
|
fmt.Printf("extracted URL: %s\n", chain.Request.URL)
|
||||||
}
|
}
|
||||||
chain.Request.URL = url
|
|
||||||
fmt.Printf("extracted URL: %s\n", chain.Request.URL)
|
|
||||||
|
|
||||||
return chain
|
return chain
|
||||||
}
|
}
|
||||||
@@ -359,7 +352,12 @@ func (chain *ProxyChain) abort(err error) error {
|
|||||||
// defer chain._reset()
|
// defer chain._reset()
|
||||||
chain.abortErr = err
|
chain.abortErr = err
|
||||||
chain.Context.Response().SetStatusCode(500)
|
chain.Context.Response().SetStatusCode(500)
|
||||||
e := fmt.Errorf("ProxyChain error for '%s': %s", chain.Request.URL.String(), err.Error())
|
var e error
|
||||||
|
if chain.Request.URL != nil {
|
||||||
|
e = fmt.Errorf("ProxyChain error for '%s': %s", chain.Request.URL.String(), err.Error())
|
||||||
|
} else {
|
||||||
|
e = fmt.Errorf("ProxyChain error: '%s'", err.Error())
|
||||||
|
}
|
||||||
chain.Context.SendString(e.Error())
|
chain.Context.SendString(e.Error())
|
||||||
log.Println(e.Error())
|
log.Println(e.Error())
|
||||||
return e
|
return e
|
||||||
@@ -382,8 +380,8 @@ func NewProxyChain() *ProxyChain {
|
|||||||
|
|
||||||
options := []tls_client.HttpClientOption{
|
options := []tls_client.HttpClientOption{
|
||||||
tls_client.WithTimeoutSeconds(20),
|
tls_client.WithTimeoutSeconds(20),
|
||||||
tls_client.WithRandomTLSExtensionOrder(),
|
//tls_client.WithRandomTLSExtensionOrder(),
|
||||||
// tls_client.WithClientProfile(profiles.Chrome_117),
|
tls_client.WithClientProfile(profiles.Chrome_117),
|
||||||
// tls_client.WithNotFollowRedirects(),
|
// tls_client.WithNotFollowRedirects(),
|
||||||
// tls_client.WithCookieJar(jar), // create cookieJar instance and pass it as argument
|
// tls_client.WithCookieJar(jar), // create cookieJar instance and pass it as argument
|
||||||
}
|
}
|
||||||
|
|||||||
28
proxychain/requestmodifiers/add_cache_buster_query.go
Normal file
28
proxychain/requestmodifiers/add_cache_buster_query.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package requestmodifiers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ladder/proxychain"
|
||||||
|
"math/rand"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AddCacheBusterQuery modifies query params to add a random parameter key
|
||||||
|
// In order to get the upstream network stack to serve a fresh copy of the page.
|
||||||
|
func AddCacheBusterQuery() proxychain.RequestModification {
|
||||||
|
return func(chain *proxychain.ProxyChain) error {
|
||||||
|
chain.AddOnceRequestModifications(
|
||||||
|
ModifyQueryParams("ord", randomString(15)),
|
||||||
|
)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func randomString(length int) string {
|
||||||
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789."
|
||||||
|
|
||||||
|
b := make([]byte, length)
|
||||||
|
for i := range b {
|
||||||
|
b[i] = charset[rand.Intn(len(charset))]
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package requestmodifiers
|
package requestmodifiers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"ladder/proxychain"
|
"ladder/proxychain"
|
||||||
@@ -12,6 +13,7 @@ func ModifyQueryParams(key string, value string) proxychain.RequestModification
|
|||||||
return func(chain *proxychain.ProxyChain) error {
|
return func(chain *proxychain.ProxyChain) error {
|
||||||
q := chain.Request.URL.Query()
|
q := chain.Request.URL.Query()
|
||||||
chain.Request.URL.RawQuery = modifyQueryParams(key, value, q)
|
chain.Request.URL.RawQuery = modifyQueryParams(key, value, q)
|
||||||
|
fmt.Println(chain.Request.URL.String())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
proxychain/responsemodifiers/delete_localstorage_data.go
Normal file
28
proxychain/responsemodifiers/delete_localstorage_data.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package responsemodifiers
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"ladder/proxychain"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeleteLocalStorageData deletes localstorage cookies.
|
||||||
|
// If the page works once in a fresh incognito window, but fails
|
||||||
|
// for subsequent loads, try this response modifier alongside
|
||||||
|
// DeleteSessionStorageData and DeleteIncomingCookies
|
||||||
|
func DeleteLocalStorageData() proxychain.ResponseModification {
|
||||||
|
return func(chain *proxychain.ProxyChain) error {
|
||||||
|
// don't add rewriter if it's not even html
|
||||||
|
ct := chain.Response.Header.Get("content-type")
|
||||||
|
if !strings.HasPrefix(ct, "text/html") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
chain.AddOnceResponseModifications(
|
||||||
|
InjectScriptBeforeDOMContentLoaded(`window.sessionStorage.clear()`),
|
||||||
|
InjectScriptAfterDOMContentLoaded(`window.sessionStorage.clear()`),
|
||||||
|
)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
28
proxychain/responsemodifiers/delete_sessionstorage_data.go
Normal file
28
proxychain/responsemodifiers/delete_sessionstorage_data.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package responsemodifiers
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"ladder/proxychain"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeleteSessionStorageData deletes localstorage cookies.
|
||||||
|
// If the page works once in a fresh incognito window, but fails
|
||||||
|
// for subsequent loads, try this response modifier alongside
|
||||||
|
// DeleteLocalStorageData and DeleteIncomingCookies
|
||||||
|
func DeleteSessionStorageData() proxychain.ResponseModification {
|
||||||
|
return func(chain *proxychain.ProxyChain) error {
|
||||||
|
// don't add rewriter if it's not even html
|
||||||
|
ct := chain.Response.Header.Get("content-type")
|
||||||
|
if !strings.HasPrefix(ct, "text/html") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
chain.AddOnceResponseModifications(
|
||||||
|
InjectScriptBeforeDOMContentLoaded(`window.sessionStorage.clear()`),
|
||||||
|
InjectScriptAfterDOMContentLoaded(`window.sessionStorage.clear()`),
|
||||||
|
)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,8 +13,12 @@ import (
|
|||||||
// DeleteIncomingCookies prevents ALL cookies from being sent from the proxy server
|
// DeleteIncomingCookies prevents ALL cookies from being sent from the proxy server
|
||||||
// back down to the client.
|
// back down to the client.
|
||||||
func DeleteIncomingCookies(_ ...string) proxychain.ResponseModification {
|
func DeleteIncomingCookies(_ ...string) proxychain.ResponseModification {
|
||||||
return func(px *proxychain.ProxyChain) error {
|
return func(chain *proxychain.ProxyChain) error {
|
||||||
px.Response.Header.Del("Set-Cookie")
|
chain.Response.Header.Del("Set-Cookie")
|
||||||
|
chain.AddOnceResponseModifications(
|
||||||
|
InjectScriptBeforeDOMContentLoaded(`document.cookie = ""`),
|
||||||
|
InjectScriptAfterDOMContentLoaded(`document.cookie = ""`),
|
||||||
|
)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,11 @@ var rqmModMap map[string]RequestModifierFactory
|
|||||||
func init() {
|
func init() {
|
||||||
rqmModMap = make(map[string]RequestModifierFactory)
|
rqmModMap = make(map[string]RequestModifierFactory)
|
||||||
|
|
||||||
rqmModMap["ForwardRequestHeaders"] = func(_ ...string) proxychain.RequestModification {
|
rqmModMap["AddCacheBusterQuery"] = func(_ ...string) proxychain.RequestModification {
|
||||||
|
return rx.AddCacheBusterQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
rqmModMap["ForwardRequestHeaders"] = func(_ ...string) proxychain.RequestModification {
|
||||||
return rx.ForwardRequestHeaders()
|
return rx.ForwardRequestHeaders()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,14 @@ func init() {
|
|||||||
return tx.SetContentSecurityPolicy(params[0])
|
return tx.SetContentSecurityPolicy(params[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rsmModMap["DeleteLocalStorageData"] = func(_ ...string) proxychain.ResponseModification {
|
||||||
|
return tx.DeleteLocalStorageData()
|
||||||
|
}
|
||||||
|
|
||||||
|
rsmModMap["DeleteSessionStorageData"] = func(_ ...string) proxychain.ResponseModification {
|
||||||
|
return tx.DeleteSessionStorageData()
|
||||||
|
}
|
||||||
|
|
||||||
rsmModMap["ForwardResponseHeaders"] = func(_ ...string) proxychain.ResponseModification {
|
rsmModMap["ForwardResponseHeaders"] = func(_ ...string) proxychain.ResponseModification {
|
||||||
return tx.ForwardResponseHeaders()
|
return tx.ForwardResponseHeaders()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user