feat: referer spoof

This commit is contained in:
SouthFox 2024-07-23 16:08:18 +08:00
parent b683756d8e
commit e74309bcec
6 changed files with 26 additions and 9 deletions

View file

@ -16,8 +16,12 @@ import (
type urlProxyRewriter func(router *mux.Router, url string) string type urlProxyRewriter func(router *mux.Router, url string) string
func RewriteDocumentWithRelativeProxyURL(router *mux.Router, htmlDocument string) string { func RewriteDocumentWithRelativeProxyURL(router *mux.Router, htmlDocument string, feedSiteURL ...string) string {
return genericProxyRewriter(router, ProxifyRelativeURL, htmlDocument) 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 { func RewriteDocumentWithAbsoluteProxyURL(router *mux.Router, host, htmlDocument string) string {

View file

@ -18,7 +18,7 @@ import (
"miniflux.app/v2/internal/config" "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 == "" { if mediaURL == "" {
return "" return ""
} }
@ -30,10 +30,16 @@ func ProxifyRelativeURL(router *mux.Router, mediaURL string) string {
mac := hmac.New(sha256.New, config.Opts.MediaProxyPrivateKey()) mac := hmac.New(sha256.New, config.Opts.MediaProxyPrivateKey())
mac.Write([]byte(mediaURL)) mac.Write([]byte(mediaURL))
digest := mac.Sum(nil) 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))) 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 == "" { if mediaURL == "" {
return "" return ""
} }
@ -42,7 +48,7 @@ func ProxifyAbsoluteURL(router *mux.Router, host, mediaURL string) string {
return proxifyURLWithCustomProxy(mediaURL, customProxyURL) return proxifyURLWithCustomProxy(mediaURL, customProxyURL)
} }
proxifiedUrl := ProxifyRelativeURL(router, mediaURL) proxifiedUrl := ProxifyRelativeURL(router, mediaURL, feedSiteURL...)
scheme := "http" scheme := "http"
if config.Opts.HTTPS { if config.Opts.HTTPS {
scheme = "https" scheme = "https"

View file

@ -57,8 +57,8 @@ func (f *funcMap) Map() template.FuncMap {
"noescape": func(str string) template.HTML { "noescape": func(str string) template.HTML {
return template.HTML(str) return template.HTML(str)
}, },
"proxyFilter": func(data string) string { "proxyFilter": func(data string, feedSiteURL ...string) string {
return mediaproxy.RewriteDocumentWithRelativeProxyURL(f.router, data) return mediaproxy.RewriteDocumentWithRelativeProxyURL(f.router, data, feedSiteURL...)
}, },
"proxyURL": func(link string) string { "proxyURL": func(link string) string {
mediaProxyMode := config.Opts.MediaProxyMode() mediaProxyMode := config.Opts.MediaProxyMode()

View file

@ -205,7 +205,7 @@
{{ end }} {{ end }}
{{end}} {{end}}
{{ if .user }} {{ if .user }}
{{ noescape (proxyFilter .entry.Content) }} {{ noescape (proxyFilter .entry.Content .entry.Feed.SiteURL) }}
{{ else }} {{ else }}
{{ noescape .entry.Content }} {{ noescape .entry.Content }}
{{ end }} {{ end }}

View file

@ -29,6 +29,7 @@ func (h *handler) mediaProxy(w http.ResponseWriter, r *http.Request) {
encodedDigest := request.RouteStringParam(r, "encodedDigest") encodedDigest := request.RouteStringParam(r, "encodedDigest")
encodedURL := request.RouteStringParam(r, "encodedURL") encodedURL := request.RouteStringParam(r, "encodedURL")
encodedReferer := request.RouteStringParam(r, "encodedReferer")
if encodedURL == "" { if encodedURL == "" {
html.BadRequest(w, r, errors.New("no URL provided")) html.BadRequest(w, r, errors.New("no URL provided"))
return return
@ -46,6 +47,8 @@ func (h *handler) mediaProxy(w http.ResponseWriter, r *http.Request) {
return return
} }
decodeReferer, _ := base64.URLEncoding.DecodeString(encodedReferer)
mac := hmac.New(sha256.New, config.Opts.MediaProxyPrivateKey()) mac := hmac.New(sha256.New, config.Opts.MediaProxyPrivateKey())
mac.Write(decodedURL) mac.Write(decodedURL)
expectedMAC := mac.Sum(nil) expectedMAC := mac.Sum(nil)
@ -87,6 +90,10 @@ func (h *handler) mediaProxy(w http.ResponseWriter, r *http.Request) {
return 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. // Note: User-Agent HTTP header is omitted to avoid being blocked by bot protection mechanisms.
req.Header.Add("Connection", "close") req.Header.Add("Connection", "close")

View file

@ -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/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/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("/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) uiRouter.HandleFunc("/entry/bookmark/{entryID}", handler.toggleBookmark).Name("toggleBookmark").Methods(http.MethodPost)
// Share pages. // Share pages.