wip
This commit is contained in:
@@ -2,20 +2,76 @@ package requestmodifers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"ladder/proxychain"
|
"ladder/proxychain"
|
||||||
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BlockOutgoingCookies prevents ALL cookies from being sent from the client
|
// SetOutgoingCookie modifes a specific cookie name
|
||||||
// to the upstream proxy server.
|
// by modifying the request cookie headers going to the upstream server.
|
||||||
func BlockOutgoingCookies() proxychain.RequestModification {
|
// If the cookie name does not already exist, it is created.
|
||||||
|
func SetOutgoingCookie(name string, val string) proxychain.RequestModification {
|
||||||
|
return func(chain *proxychain.ProxyChain) error {
|
||||||
|
cookies := chain.Request.Cookies()
|
||||||
|
hasCookie := false
|
||||||
|
for _, cookie := range cookies {
|
||||||
|
if cookie.Name != name {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
hasCookie = true
|
||||||
|
cookie.Value = val
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasCookie {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
chain.Request.AddCookie(&http.Cookie{
|
||||||
|
Domain: chain.Request.URL.Host,
|
||||||
|
Name: name,
|
||||||
|
Value: val,
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOutgoingCookies modifies a client request's cookie header
|
||||||
|
// to a raw Cookie string, overwriting existing cookies
|
||||||
|
func SetOutgoingCookies(cookies string) proxychain.RequestModification {
|
||||||
|
return func(chain *proxychain.ProxyChain) error {
|
||||||
|
chain.Request.Header.Set("Cookies", cookies)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteOutgoingCookie modifies the http request's cookies header to
|
||||||
|
// delete a specific request cookie going to the upstream server.
|
||||||
|
// If the cookie does not exist, it does not do anything.
|
||||||
|
func DeleteOutgoingCookie(name string) proxychain.RequestModification {
|
||||||
|
return func(chain *proxychain.ProxyChain) error {
|
||||||
|
cookies := chain.Request.Cookies()
|
||||||
|
chain.Request.Header.Del("Cookies")
|
||||||
|
|
||||||
|
for _, cookie := range cookies {
|
||||||
|
if cookie.Name == name {
|
||||||
|
chain.Request.AddCookie(cookie)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteOutgoingCookies removes the cookie header entirely,
|
||||||
|
// preventing any cookies from reaching the upstream server.
|
||||||
|
func DeleteOutgoingCookies() proxychain.RequestModification {
|
||||||
return func(px *proxychain.ProxyChain) error {
|
return func(px *proxychain.ProxyChain) error {
|
||||||
px.Request.Header.Del("Cookie")
|
px.Request.Header.Del("Cookie")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockOutgoingCookiesExcept prevents non-whitelisted cookies from being sent from the client
|
// DeleteOutGoingCookiesExcept prevents non-whitelisted cookies from being sent from the client
|
||||||
// to the upstream proxy server. Cookies whose names are in the whitelist are not removed.
|
// to the upstream proxy server. Cookies whose names are in the whitelist are not removed.
|
||||||
func BlockOutgoingCookiesExcept(whitelist ...string) proxychain.RequestModification {
|
func DeleteOutgoingCookiesExcept(whitelist ...string) proxychain.RequestModification {
|
||||||
return func(px *proxychain.ProxyChain) error {
|
return func(px *proxychain.ProxyChain) error {
|
||||||
// Convert whitelist slice to a map for efficient lookups
|
// Convert whitelist slice to a map for efficient lookups
|
||||||
whitelistMap := make(map[string]struct{})
|
whitelistMap := make(map[string]struct{})
|
||||||
|
|||||||
@@ -50,18 +50,18 @@ func (r *HTMLResourceURLRewriter) Read(p []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
return 0, err // Actual error
|
return 0, err // Actual error
|
||||||
}
|
}
|
||||||
|
|
||||||
token := tokenizer.Token()
|
token := tokenizer.Token()
|
||||||
if tokenType == html.StartTagToken || tokenType == html.SelfClosingTagToken {
|
if tokenType == html.StartTagToken || tokenType == html.SelfClosingTagToken {
|
||||||
rewriteToken(&token, r.url)
|
rewriteToken(&token, r.proxyURL)
|
||||||
}
|
}
|
||||||
r.buffer.WriteString(token.String())
|
r.buffer.WriteString(token.String())
|
||||||
if r.buffer.Len() > 0 {
|
if r.buffer.Len() > 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return r.buffer.Read(p)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// RewriteHTMLResourceURLs updates src/href attributes in HTML content to route through the proxy.
|
// RewriteHTMLResourceURLs updates src/href attributes in HTML content to route through the proxy.
|
||||||
func RewriteHTMLResourceURLs() proxychain.ResponseModification {
|
func RewriteHTMLResourceURLs() proxychain.ResponseModification {
|
||||||
@@ -70,45 +70,8 @@ func RewriteHTMLResourceURLs() proxychain.ResponseModification {
|
|||||||
if ct != "text/html" {
|
if ct != "text/html" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// TODO: implement chaining rewriter chaining method
|
||||||
// parse dom
|
// so we can compose multiple body rewriters together
|
||||||
tokenizer := html.NewTokenizer(chain.Body)
|
|
||||||
var buffer bytes.Buffer
|
|
||||||
|
|
||||||
// traverse dom and proxify existing src/img resource links
|
|
||||||
for {
|
|
||||||
tokenType := tokenizer.Next()
|
|
||||||
switch tokenType {
|
|
||||||
case html.ErrorToken:
|
|
||||||
// End of the document, set the new body
|
|
||||||
chain.Body = io.ReaderFrom(buffer)
|
|
||||||
return nil
|
return nil
|
||||||
case html.StartTagToken, html.SelfClosingTagToken:
|
|
||||||
token := tokenizer.Token()
|
|
||||||
// Rewrite the necessary attributes
|
|
||||||
token = rewriteToken(token, u)
|
|
||||||
buffer.WriteString(token.String())
|
|
||||||
case html.TextToken, html.CommentToken, html.DoctypeToken, html.EndTagToken:
|
|
||||||
// Write the token to the buffer as is
|
|
||||||
buffer.WriteString(tokenizer.Token().String())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// rewriteToken rewrites the tokens with URLs to point to the proxy server.
|
|
||||||
func rewriteToken(token html.Token, u *url.URL) html.Token {
|
|
||||||
// Define attributes to rewrite, add more as needed such as "srcset"
|
|
||||||
rewriteAttrs := map[string]bool{"href": true, "src": true, "action": true, "srcset": true}
|
|
||||||
|
|
||||||
for i, attr := range token.Attr {
|
|
||||||
_, shouldRewrite := rewriteAttrs[attr.Key]
|
|
||||||
if shouldRewrite {
|
|
||||||
val := attr.Val
|
|
||||||
if strings.HasPrefix(val, "/") {
|
|
||||||
token.Attr[i].Val = "/https://" + u.Host + val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return token
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user