CVE-2026-75926 Overview
CVE-2026-75926 is a permission model bypass in Hugo, the static site generator written in Go. Hugo 0.162.0 added tailwindcss to the AllowChildProcess default list in config/security/securityConfig.go. The change caused nodePermissionArgs in common/hexec/exec.go to append --allow-child-process whenever tailwindcss was launched. Because TailwindCSS loads tailwind.config.js through require at startup, top-level JavaScript in that file runs inside the permitted Node.js process and can call child_process to spawn a shell. The spawned process inherits none of the Node.js permission flags. Building a site whose theme, module, or starter template supplies the Tailwind configuration therefore yields arbitrary command execution.
Critical Impact
Building an untrusted Hugo site with default configuration on Hugo 0.162.0 through 0.164.x executes arbitrary shell commands with the privileges of the account performing the build.
Affected Products
- Hugo 0.162.0 through 0.164.x with default security.exec.allow configuration
- Hugo sites using TailwindCSS via themes, modules, or starter templates
- Build environments and CI/CD pipelines running Hugo against untrusted content sources
Discovery Timeline
- 2026-08-18 - CVE-2026-75926 published to NVD
- 2026-08-20 - Last updated in NVD database
Technical Details for CVE-2026-75926
Vulnerability Analysis
Hugo 0.161.0 placed Node asset pipelines behind the Node.js permission model. PostCSS, Babel, and TailwindCSS ran with restricted file system access confined to the project directory. The design goal was to prevent hostile JavaScript in a downloaded theme or module from reaching secrets, credentials, or files outside the site tree.
Hugo 0.162.0 broke this containment. The default security.exec.allow whitelist added tailwindcss, and the executor logic in common/hexec/exec.go appended the --allow-child-process flag to any process matching that name. TailwindCSS invokes require("./tailwind.config.js") at startup, so arbitrary JavaScript at the top of that config file executes inside the granted Node.js context. A single require("child_process").execSync("...") call spawns a non-Node process that runs without any permission model constraints, yielding full command execution as the build user. This is a case of insecure default configuration [CWE-1188].
Root Cause
The root cause is the addition of tailwindcss to the default AllowChildProcess list without accounting for the fact that Tailwind evaluates its configuration file as executable JavaScript. Granting --allow-child-process to a process that loads untrusted code effectively removes the sandbox.
Attack Vector
An attacker publishes a Hugo theme, module, or starter template containing a malicious tailwind.config.js. When a victim runs hugo or hugo server against the project, TailwindCSS loads the config and spawns commands under the victim's account. User interaction is required in the form of building the site.
var DefaultConfig = Config{
Exec: Exec{
Allow: MustNewWhitelist(
- "^(dart-)?sass(-embedded)?$", // sass, dart-sass, dart-sass-embedded.
- "^go$", // for Go Modules
- "^git$", // For Git info
- "^node$", // Used as the runtime for Node tools.
+ "^(dart-)?sass$", // sass, dart-sass
+ "^go$", // for Go Modules
+ "^git$", // For Git info
+ "^node$", // Used as the runtime for Node tools.
"^postcss$",
- "^tailwindcss$",
),
Source: Hugo commit 8a55df7. The patch removes tailwindcss from the default security.exec.allow list so the tool is no longer launched under default configuration.
Detection Methods for CVE-2026-75926
Indicators of Compromise
- Unexpected child processes spawned by node or tailwindcss during hugo or hugo server builds
- Presence of require("child_process"), execSync, spawn, or shell metacharacters in a project's tailwind.config.js
- Outbound network connections initiated from a Hugo build host during static site generation
- Newly created files, scheduled tasks, or credential access events correlated with a Hugo build window
Detection Strategies
- Inspect tailwind.config.js in all themes, Hugo modules, and starter templates for executable code beyond configuration exports
- Alert on process trees where hugo is the ancestor of shells such as sh, bash, cmd.exe, or powershell.exe
- Monitor CI/CD build agents for anomalous outbound connections during Hugo runs
Monitoring Recommendations
- Log the installed Hugo version across developer workstations and build infrastructure and flag versions 0.162.0 through 0.164.x
- Capture command-line arguments for all Node.js invocations and review those launched with --allow-child-process
- Enable EDR process telemetry on build servers to reconstruct static site generation activity
How to Mitigate CVE-2026-75926
Immediate Actions Required
- Upgrade Hugo to 0.165.0 or later, which removes tailwindcss from the default security.exec.allow list
- Audit repositories, themes, and modules for malicious code inside tailwind.config.js before the next build
- Restrict Hugo build environments to accounts with least privilege and no access to production credentials
Patch Information
Hugo 0.165.0 removes tailwindcss from the default security.exec.allow list, so the tool is no longer launched under the default configuration. Refer to the Hugo commit reference, the Hugo issue discussion, and the VulnCheck advisory for full details.
Workarounds
- On affected Hugo versions, override security.exec.allow in hugo.toml or config.toml to exclude tailwindcss
- Run hugo builds inside a container or sandbox with no network egress and read-only mounts outside the project directory
- Vet third-party themes and Hugo modules before pinning them into a project, treating tailwind.config.js as executable code
# hugo.toml - restrict allowed executables to exclude tailwindcss
[security.exec]
allow = ['^(dart-)?sass$', '^go$', '^git$', '^node$', '^postcss$']
osEnv = ['(?i)^((HTTPS?|NO)_PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM)$']
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

