From e74309bcec653a7d0f6d34322f29f5125a93561d Mon Sep 17 00:00:00 2001 From: SouthFox Date: Tue, 23 Jul 2024 16:08:18 +0800 Subject: [PATCH] feat: referer spoof --- internal/mediaproxy/rewriter.go | 8 ++++++-- internal/mediaproxy/url.go | 12 +++++++++--- internal/template/functions.go | 4 ++-- internal/template/templates/views/entry.html | 2 +- internal/ui/proxy.go | 7 +++++++ internal/ui/ui.go | 2 +- 6 files changed, 26 insertions(+), 9 deletions(-) diff --git a/internal/mediaproxy/rewriter.go b/internal/mediaproxy/rewriter.go index b77be654..e94b32c9 100644 --- a/internal/mediaproxy/rewriter.go +++ b/internal/mediaproxy/rewriter.go @@ -16,8 +16,12 @@ import ( type urlProxyRewriter func(router *mux.Router, url string) string -func RewriteDocumentWithRelativeProxyURL(router *mux.Router, htmlDocument string) string { - return genericProxyRewriter(router, ProxifyRelativeURL, htmlDocument) +func RewriteDocumentWithRelativeProxyURL(router *mux.Router, htmlDocument string, feedSiteURL ...string) string { + proxifyFunction := func(router *mux.Router, mediaURL string) string { + return ProxifyRelativeURL(router, mediaURL, feedSiteURL...) + } + + return genericProxyRewriter(router, proxifyFunction, htmlDocument) } func RewriteDocumentWithAbsoluteProxyURL(router *mux.Router, host, htmlDocument string) string { diff --git a/internal/mediaproxy/url.go b/internal/mediaproxy/url.go index c3a9a953..5efce1e4 100644 --- a/internal/mediaproxy/url.go +++ b/internal/mediaproxy/url.go @@ -18,7 +18,7 @@ import ( "miniflux.app/v2/internal/config" ) -func ProxifyRelativeURL(router *mux.Router, mediaURL string) string { +func ProxifyRelativeURL(router *mux.Router, mediaURL string, feedSiteURL ...string) string { if mediaURL == "" { return "" } @@ -30,10 +30,16 @@ func ProxifyRelativeURL(router *mux.Router, mediaURL string) string { mac := hmac.New(sha256.New, config.Opts.MediaProxyPrivateKey()) mac.Write([]byte(mediaURL)) digest := mac.Sum(nil) + + if len(feedSiteURL) >0 { + referer := feedSiteURL[0] + return route.Path(router, "proxy", "encodedDigest", base64.URLEncoding.EncodeToString(digest), "encodedURL", base64.URLEncoding.EncodeToString([]byte(mediaURL)), "encodedReferer", base64.URLEncoding.EncodeToString([]byte(referer))) + } + return route.Path(router, "proxy", "encodedDigest", base64.URLEncoding.EncodeToString(digest), "encodedURL", base64.URLEncoding.EncodeToString([]byte(mediaURL))) } -func ProxifyAbsoluteURL(router *mux.Router, host, mediaURL string) string { +func ProxifyAbsoluteURL(router *mux.Router, host, mediaURL string, feedSiteURL ...string) string { if mediaURL == "" { return "" } @@ -42,7 +48,7 @@ func ProxifyAbsoluteURL(router *mux.Router, host, mediaURL string) string { return proxifyURLWithCustomProxy(mediaURL, customProxyURL) } - proxifiedUrl := ProxifyRelativeURL(router, mediaURL) + proxifiedUrl := ProxifyRelativeURL(router, mediaURL, feedSiteURL...) scheme := "http" if config.Opts.HTTPS { scheme = "https" diff --git a/internal/template/functions.go b/internal/template/functions.go index cfbfc53d..9c1018e9 100644 --- a/internal/template/functions.go +++ b/internal/template/functions.go @@ -57,8 +57,8 @@ func (f *funcMap) Map() template.FuncMap { "noescape": func(str string) template.HTML { return template.HTML(str) }, - "proxyFilter": func(data string) string { - return mediaproxy.RewriteDocumentWithRelativeProxyURL(f.router, data) + "proxyFilter": func(data string, feedSiteURL ...string) string { + return mediaproxy.RewriteDocumentWithRelativeProxyURL(f.router, data, feedSiteURL...) }, "proxyURL": func(link string) string { mediaProxyMode := config.Opts.MediaProxyMode() diff --git a/internal/template/templates/views/entry.html b/internal/template/templates/views/entry.html index 85618954..037bec3b 100644 --- a/internal/template/templates/views/entry.html +++ b/internal/template/templates/views/entry.html @@ -205,7 +205,7 @@ {{ end }} {{end}} {{ if .user }} - {{ noescape (proxyFilter .entry.Content) }} + {{ noescape (proxyFilter .entry.Content .entry.Feed.SiteURL) }} {{ else }} {{ noescape .entry.Content }} {{ end }} diff --git a/internal/ui/proxy.go b/internal/ui/proxy.go index 34965275..311b3f53 100644 --- a/internal/ui/proxy.go +++ b/internal/ui/proxy.go @@ -29,6 +29,7 @@ func (h *handler) mediaProxy(w http.ResponseWriter, r *http.Request) { encodedDigest := request.RouteStringParam(r, "encodedDigest") encodedURL := request.RouteStringParam(r, "encodedURL") + encodedReferer := request.RouteStringParam(r, "encodedReferer") if encodedURL == "" { html.BadRequest(w, r, errors.New("no URL provided")) return @@ -46,6 +47,8 @@ func (h *handler) mediaProxy(w http.ResponseWriter, r *http.Request) { return } + decodeReferer, _ := base64.URLEncoding.DecodeString(encodedReferer) + mac := hmac.New(sha256.New, config.Opts.MediaProxyPrivateKey()) mac.Write(decodedURL) expectedMAC := mac.Sum(nil) @@ -87,6 +90,10 @@ func (h *handler) mediaProxy(w http.ResponseWriter, r *http.Request) { return } + if decodeReferer != nil { + req.Header.Add("Referer", string(decodeReferer)) + } + // Note: User-Agent HTTP header is omitted to avoid being blocked by bot protection mechanisms. req.Header.Add("Connection", "close") diff --git a/internal/ui/ui.go b/internal/ui/ui.go index d6641c01..80f94c08 100644 --- a/internal/ui/ui.go +++ b/internal/ui/ui.go @@ -102,7 +102,7 @@ func Serve(router *mux.Router, store *storage.Storage, pool *worker.Pool) { uiRouter.HandleFunc("/entry/save/{entryID}", handler.saveEntry).Name("saveEntry").Methods(http.MethodPost) uiRouter.HandleFunc("/entry/enclosure/{enclosureID}/save-progression", handler.saveEnclosureProgression).Name("saveEnclosureProgression").Methods(http.MethodPost) uiRouter.HandleFunc("/entry/download/{entryID}", handler.fetchContent).Name("fetchContent").Methods(http.MethodPost) - uiRouter.HandleFunc("/proxy/{encodedDigest}/{encodedURL}", handler.mediaProxy).Name("proxy").Methods(http.MethodGet) + uiRouter.HandleFunc("/proxy/{encodedDigest}/{encodedURL}/{encodedReferer}", handler.mediaProxy).Name("proxy").Methods(http.MethodGet) uiRouter.HandleFunc("/entry/bookmark/{entryID}", handler.toggleBookmark).Name("toggleBookmark").Methods(http.MethodPost) // Share pages.