dutchcoders/transfer.sh · error
Not authorized
Error message
Not authorized
What it means
The auth middleware requires either a successful Basic Auth parse or prior authorization (e.g. IP filter allowlist). If the request has no valid Authorization header and the client IP is not pre-authorized, it responds 401 'Not authorized'.
Source
Thrown at server/handlers.go:1379
s.htpasswdFile = htpasswdFile
}
if s.authIPFilter == nil && s.authIPFilterOptions != nil {
s.authIPFilter = newIPFilter(s.authIPFilterOptions)
}
w.Header().Set("WWW-Authenticate", "Basic realm=\"Restricted\"")
var authorized bool
if s.authIPFilter != nil {
remoteIP := realip.FromRequest(r)
authorized = s.authIPFilter.Allowed(remoteIP)
}
username, password, authOK := r.BasicAuth()
if !authOK && !authorized {
http.Error(w, "Not authorized", http.StatusUnauthorized)
return
}
if !authorized && username == s.authUser && password == s.authPass {
authorized = true
}
if !authorized && s.htpasswdFile != nil {
authorized = s.htpasswdFile.Match(username, password)
}
if !authorized {
http.Error(w, "Not authorized", http.StatusUnauthorized)
return
}
h.ServeHTTP(w, r)
}View on GitHub (pinned to c37bfd9579)
Solutions
- Send Basic Auth credentials, e.g. curl -u user:pass https://linx/...
- For browsers, set fetch(url, {credentials:'include'}) so saved credentials are sent
- Check that no reverse proxy in front strips or rewrites the Authorization header
- If access should be IP-based, add the client IP to the configured IP filter allowlist
- Verify username/password spelling and that they match authUser/authPass or an htpasswd entry
Example fix
// before
fetch('https://linx/upload', {method:'POST', body:form})
// after
const auth = btoa('user:pass')
fetch('https://linx/upload', {method:'POST', body:form, headers:{Authorization:'Basic '+auth}}) Defensive patterns
Strategy: try-catch
Validate before calling
// client side: confirm credentials are being sent before the request
if (!authHeader) throw new Error('No Basic credentials configured');
fetch(url, {headers: {Authorization: authHeader}}) Type guard
null
Try / catch
try {
const res = await fetch(url, {headers: {Authorization: 'Basic ' + btoa(user + ':' + pass)}, credentials: 'include'});
if (res.status === 401) throw new Error('Not authorized: check credentials or IP allowlist');
} catch (err) {
// prompt for credentials or fall back to an allowed network/IP
} Prevention
- Always send the Authorization header on protected endpoints; use credentials:'include' for browser fetch
- Confirm no proxy strips Authorization headers
- Add client IPs to the allowlist when relying on IP-based authorization
- Handle 401 centrally to prompt for credentials
When it happens
Trigger: Request without an Authorization: Basic header (authOK false) while the remote IP was not already authorized by the IP filter, on a server configured with authUser/authPass or htpasswd protection.
Common situations: Client omitted credentials entirely; browser fetch() calls dropping credentials without credentials:'include'; API clients hitting a protected endpoint directly; reverse proxy stripping the Authorization header.
AI-assisted analysis of dutchcoders/transfer.sh@c37bfd9579 (2026-09-05).
Data as JSON: /api/errors/213d2987d8daed3c.
Report an issue: GitHub.