Refusing it unconditionally was security theatre: --insecure also sets
InsecureSkipVerify, so an attacker in position to intercept can already
serve anything over the https leg with a self-signed certificate. It also
broke an internal server that redirects and works today.
--insecure now means one thing everywhere: the transport guarantees are
waived.
The same policy — keep TaskfileNotSecureError, make everything else a
generic download failure — was spelled out at each of the three call
sites, where copies of a security rule tend to drift apart.
The scheme was only checked on the URL the user wrote. A server answering
an https URL with a redirect to http was followed by the client without
any further check, so both the HEAD probe and the download travelled in
the clear, and a network attacker could substitute the Taskfile that is
about to be executed.
CheckRedirect now refuses an https to http hop. --insecure does not
loosen it: requesting an http entrypoint is the user's decision, being
sent to one is the server's. Setting CheckRedirect also replaces Go's
default cap, so the ten-hop limit is kept explicitly.
The three call sites turned almost every client error into a generic
download failure, which would have hidden the reason; TaskfileNotSecureError
is now passed through, with wording of its own for the redirect case since
--insecure is not a way out of it.
Add //nolint:gosec annotations for intentional code patterns
that are safe in context (path traversal in release tool,
uintptr conversion for terminals, weak rand in tests,
TLS skip verify for user-configured insecure mode).
Assisted-by: Kimi-K2.5 via Crush <crush@charm.land>
* Fixed check for an existing Taskfile: look for all possibilities, and
not only `Taskfile.yml` specifically.
* Added a description (`desc`) to the `default` task. Important to at
least `task --list` work by default (a core feature).
* Changed top comment to YAML language server comment.
* feat: redact credentials in remote urls
* chore: improve function naming
* fix: TaskfileNotSecureError should use redacted URI
* feat: unexport all node implementation fields
* fix: unexport HTTPNode.url