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

  1. Send Basic Auth credentials, e.g. curl -u user:pass https://linx/...
  2. For browsers, set fetch(url, {credentials:'include'}) so saved credentials are sent
  3. Check that no reverse proxy in front strips or rewrites the Authorization header
  4. If access should be IP-based, add the client IP to the configured IP filter allowlist
  5. 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

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.