summaryrefslogtreecommitdiff
path: root/services/worker/internal/fetcher
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-07 01:44:12 -0800
committerFuwn <[email protected]>2026-02-07 01:44:12 -0800
commit504a0c1bed5b2086fec1e3b89027d328f9c09604 (patch)
tree3e92560239227426daef6a7d549bd7ea0ca14805 /services/worker/internal/fetcher
parentfeat: asa.news RSS reader with developer tier, REST API, and webhooks (diff)
downloadasa.news-504a0c1bed5b2086fec1e3b89027d328f9c09604.tar.xz
asa.news-504a0c1bed5b2086fec1e3b89027d328f9c09604.zip
style: format Go worker with iku
Diffstat (limited to 'services/worker/internal/fetcher')
-rw-r--r--services/worker/internal/fetcher/fetcher.go2
-rw-r--r--services/worker/internal/fetcher/ssrf_protection.go5
2 files changed, 7 insertions, 0 deletions
diff --git a/services/worker/internal/fetcher/fetcher.go b/services/worker/internal/fetcher/fetcher.go
index 019bd39..bbeb622 100644
--- a/services/worker/internal/fetcher/fetcher.go
+++ b/services/worker/internal/fetcher/fetcher.go
@@ -30,6 +30,7 @@ func NewFetcher(fetchTimeout time.Duration) *Fetcher {
}
redirectValidationError := ValidateRedirectTarget(request.URL.String())
+
if redirectValidationError != nil {
return fmt.Errorf("blocked redirect to reserved address: %w", redirectValidationError)
}
@@ -48,6 +49,7 @@ func (feedFetcher *Fetcher) Fetch(
authenticationConfig AuthenticationConfiguration,
) (*FetchResult, error) {
urlValidationError := ValidateFeedURL(feedURL)
+
if urlValidationError != nil {
return nil, fmt.Errorf("blocked request to disallowed URL: %w", urlValidationError)
}
diff --git a/services/worker/internal/fetcher/ssrf_protection.go b/services/worker/internal/fetcher/ssrf_protection.go
index 1887e78..e88c8d7 100644
--- a/services/worker/internal/fetcher/ssrf_protection.go
+++ b/services/worker/internal/fetcher/ssrf_protection.go
@@ -33,16 +33,19 @@ func isReservedAddress(ipAddress net.IP) bool {
func ValidateFeedURL(feedURL string) error {
parsedURL, parseError := url.Parse(feedURL)
+
if parseError != nil {
return fmt.Errorf("invalid URL: %w", parseError)
}
scheme := strings.ToLower(parsedURL.Scheme)
+
if scheme != "http" && scheme != "https" {
return fmt.Errorf("unsupported scheme %q: only http and https are allowed", parsedURL.Scheme)
}
hostname := parsedURL.Hostname()
+
if hostname == "" {
return fmt.Errorf("URL has no hostname")
}
@@ -56,9 +59,11 @@ func ValidateFeedURL(feedURL string) error {
}
resolverContext, cancelResolver := context.WithTimeout(context.Background(), 5*time.Second)
+
defer cancelResolver()
resolvedAddresses, lookupError := net.DefaultResolver.LookupIPAddr(resolverContext, hostname)
+
if lookupError != nil {
return fmt.Errorf("failed to resolve hostname %q: %w", hostname, lookupError)
}