Skip to content

fix(security): remove silent gradlew RCE, stop leaking VCS token and JWT, validate ARTEMIS_URL - #203

Open
Mtze wants to merge 1 commit into
feat/env-var-passthroughfrom
security/no-auto-gradlew
Open

Mtze wants to merge 1 commit into
feat/env-var-passthroughfrom
security/no-auto-gradlew

Conversation

@Mtze

@Mtze Mtze commented Oct 10, 2026

Copy link
Copy Markdown
Member

Summary

Fixes four issues from the security audit of the feat/env-var-passthrough work. The audited code (auto-gradlew prewarm, token-in-clone-URL, Theia Bearer injection, StompJs frame logging) exists only on feat/env-var-passthrough, not on main, so this PR targets that branch. Basing it on main would not touch the vulnerable code.

Changes are minimal and preserve normal UX for legitimate exercises.

1. HIGH - silent RCE via auto-executed ./gradlew

warmupGradleDaemon no longer runs the cloned repo's ./gradlew wrapper automatically. The student must explicitly confirm (non-modal prompt) before any repository-controlled Gradle build runs, and confirmation defaults to no - if ignored, nothing executes.

Choice: I went with explicit confirmation rather than a "trusted pinned Gradle" because any Gradle invocation against the repo (wrapper jar and build.gradle/settings.gradle) evaluates repository-controlled code, so a pinned binary would not remove the RCE. Confirmation is the least-disruptive option that is actually safe; prewarm stays available as opt-in.

2. MEDIUM - token in clone URL .git/config and argv

  • The VCS token is no longer embedded as user:token@host in the clone URL (Artemis path now uses an HTTP Basic header), so it is out of the clone URL and the stored remote.
  • The auth header is injected into the git process via GIT_CONFIG_COUNT/GIT_CONFIG_KEY_0/GIT_CONFIG_VALUE_0 env vars (git >= 2.31) instead of -c on the command line, so the token never appears in process arguments (ps).
  • Removed the now-unused addVcsTokenToUrl helper.
  • Residual risk (documented): to keep in-IDE fetch/push working (submitCurrentWorkspace().push()), the auth header is still persisted into .git/config after clone. A full move to an on-demand credential helper / GIT_ASKPASS with no on-disk token is deferred (see below).

3. MEDIUM - JWT logged

StompJs debug is now a no-op, so the CONNECT frame (which carries the Authorization Bearer JWT) is never written to the debug console.

4. INFERRED - unvalidated ARTEMIS_URL env override

ARTEMIS_URL is validated against the configured Artemis origin (scheme + host + port) before it is used as the API base. A mismatching value is rejected with an error message, so the Bearer token cannot be redirected to an untrusted host.

Tests

Added unit tests: clone auth handling (no token in argv, header via env, persisted to .git/config), the gradle confirmation gate (no build without explicit confirm), and ARTEMIS_URL validation. npm run build, eslint src and tsc --noEmit are green.

Deferred / product decisions

  • No-on-disk-token credential flow (item 2): fully removing the token from .git/config requires reworking push/fetch to re-inject credentials on demand (e.g. GIT_ASKPASS or a credential helper). Larger change, deferred; current PR removes the URL and argv exposure.
  • ARTEMIS_URL allowlist source (item 4): the allowlist is the configured scorpio.artemis.apiBaseUrl origin (packaged default https://artemis.cit.tum.de). Self-hosted deployments that point ARTEMIS_URL at a different host must ship a matching apiBaseUrl default, otherwise the override is rejected. Flagging in case a broader allowlist is wanted.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 313277a4-a371-4d59-8d39-6d7071f20276

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

… validate ARTEMIS_URL

Addresses four findings from the security audit of the env-var-passthrough work:

- Gradle prewarm no longer auto-executes the cloned repo's ./gradlew wrapper. The
  student must explicitly confirm before any repository-controlled Gradle build runs,
  and confirmation defaults to "no". This removes a silent remote-code-execution path
  from tampered exercise templates while keeping prewarm available as an opt-in.
- The VCS/Git token is no longer embedded in the clone URL or passed on the git command
  line. It is injected into the git process via GIT_CONFIG_* environment variables during
  clone and persisted only into .git/config for later in-IDE fetch/push. The unused
  addVcsTokenToUrl helper is removed. Residual: the short-lived token is still written to
  .git/config so push/fetch keep working.
- STOMP/WebSocket frame logging is disabled so the Artemis JWT in the CONNECT frame is
  never written to the debug console.
- The ARTEMIS_URL environment override is validated against the configured Artemis origin
  (scheme + host + port) before being used as the API base, preventing the Bearer token
  from being sent to an untrusted host.

Adds unit tests for the clone auth handling, the gradle confirmation gate and the
ARTEMIS_URL validation.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@Mtze
Mtze force-pushed the security/no-auto-gradlew branch from 4f3ebef to 17874c2 Compare October 10, 2026 21:15

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant