Skip to content

fix(envd): use constant-time comparison for signature validation#3145

Merged
arkamar merged 4 commits into
e2b-dev:mainfrom
AdaAibaby:fix/envd-auth-timing-attack
Jul 9, 2026
Merged

fix(envd): use constant-time comparison for signature validation#3145
arkamar merged 4 commits into
e2b-dev:mainfrom
AdaAibaby:fix/envd-auth-timing-attack

Conversation

@AdaAibaby

Copy link
Copy Markdown
Contributor

Replace string inequality operator (!=) with crypto/subtle.ConstantTimeCompare for signature validation in auth.go. The previous implementation was vulnerable to timing attacks, where an attacker could potentially determine the correct signature byte-by-byte by measuring response times.

This is a standard security best practice for comparing cryptographic values such as HMAC signatures, tokens, and hashes.

/cc @jakubno @dobrac @ValentaTomas Would appreciate your review on this change, thanks!

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

tiago-mitralab added a commit to mitralab-dev/e2b-infra that referenced this pull request Jul 9, 2026
…0.6.8

e2b-dev#3146 as-is would panic at boot on our host (default route has non-nil Dst=0.0.0.0/0); accept both netlink representations. Bump envd to 0.6.8 for the behavior changes in cherry-picked e2b-dev#3099/e2b-dev#3145 (version bumps dropped in cherry-pick).
tiago-mitralab added a commit to mitralab-dev/e2b-infra that referenced this pull request Jul 9, 2026
…0.6.9

e2b-dev#3146 as-is panics at boot on our host (default route has non-nil Dst=0.0.0.0/0). Bump envd for cherry-picked e2b-dev#3099/e2b-dev#3145 envd changes.
adababys added 2 commits July 9, 2026 09:04
Replace string inequality operator (!=) with crypto/subtle.ConstantTimeCompare
for signature validation in auth.go. The previous implementation was vulnerable
to timing attacks, where an attacker could potentially determine the correct
signature byte-by-byte by measuring response times.

This is a standard security best practice for comparing cryptographic values
such as HMAC signatures, tokens, and hashes.
Add 6 test cases covering validateSigning:
- Accepts correct signature with expiration
- Rejects wrong signature
- Rejects expired signature
- Rejects missing signature parameter
- Accepts valid access token from header
- Rejects invalid access token from header

Also refactor existing tests to use a shared helper.
@tvi
tvi force-pushed the fix/envd-auth-timing-attack branch from 69cc233 to 19f58f6 Compare July 9, 2026 07:05
tiago-mitralab added a commit to mitralab-dev/e2b-infra that referenced this pull request Jul 9, 2026
…dening) (#3)

* fix(orchestrator): prevent nil panic when finding default gateway

In Linux, the default route (0.0.0.0/0) has a nil Dst field in the
netlink.Route struct. The previous code called route.Dst.String() without
a nil check, which would panic on systems where the default route's Dst
is nil.

Fix by checking route.Dst == nil directly, which is the canonical way to
identify the default route.

(cherry picked from commit a2304dc)

* fix(envd): use constant-time comparison for signature validation

Replace string inequality operator (!=) with crypto/subtle.ConstantTimeCompare
for signature validation in auth.go. The previous implementation was vulnerable
to timing attacks, where an attacker could potentially determine the correct
signature byte-by-byte by measuring response times.

This is a standard security best practice for comparing cryptographic values
such as HMAC signatures, tokens, and hashes.

(cherry picked from commit 85cce6c)

* test(envd): add validateSigning tests for signature validation

Add 6 test cases covering validateSigning:
- Accepts correct signature with expiration
- Rejects wrong signature
- Rejects expired signature
- Rejects missing signature parameter
- Accepts valid access token from header
- Rejects invalid access token from header

Also refactor existing tests to use a shared helper.

(cherry picked from commit 69cc233)

* fix(uffd): log error and remove stale TODO on handle failure

The UFFD handle goroutine had a TODO comment stating that the sandbox
should be killed when handle() fails. In fact, this is already
implemented: u.exit.SetError() triggers the sandbox exit watcher in
sandbox.go (line ~1093) which calls sbx.Stop().

- Remove the stale TODO comment
- Add error logging when handle() fails for better observability
- Add unit tests covering handle failure behavior (exit error
  propagation, readyCh closure, handler error state, initial state,
  socket creation)

(cherry picked from commit 3e30b03)

* fix(orchestrator): fix typo in TODO comment (to to → to)

(cherry picked from commit c87310c)

* fix: add t.Parallel() to all test functions (paralleltest)

(cherry picked from commit 7b54ed7)

* fix(orchestrator): fix race condition in Cleanup causing missed cleanup functions

There was a TOCTOU race between Add()/AddPriority() and run():

1. Add() checks hasRun (false) outside the lock
2. Add() blocks waiting for mu.Lock()
3. run() acquires lock, sets hasRun=true, executes all cleanups, unlocks
4. Add() acquires lock, appends f — but run() already finished

Result: f is never executed, potentially leaking resources (network
namespaces, cgroups, file descriptors, etc.).

Fix:
- Move hasRun.Store(true) inside the lock in run()
- Add double-checked locking in Add()/AddPriority(): re-check hasRun
  after acquiring the lock and execute f inline if cleanup already ran

Add race-condition tests that reliably reproduce the bug with -race.

(cherry picked from commit d7b2551)

* refactor: release lock before executing cleanup in double-check path

Avoid holding the mutex while executing cleanup functions in the
double-check branch. This prevents potential deadlocks if a cleanup
function performs blocking operations or re-enters the lock.

(cherry picked from commit 97336fd)

* fix: add t.Parallel() to all test functions (paralleltest)

(cherry picked from commit 619dd88)

* feat(orchestrator): add capacity limit and memory-pressure eviction to template mmap cache

(cherry picked from commit 1f1a5a1)

* fix: use MemAvailable instead of Freeram, evict one entry per tick, add unit tests

- Replace unix.Sysinfo Freeram with /proc/meminfo MemAvailable to get
  true available memory (includes reclaimable page cache)
- Evict only one LRU entry per 1s tick instead of looping until threshold
  is met; mmap.Unmap is not instantaneous so the OS stats lag behind
- Add 6 unit tests covering WithCapacity LRU eviction, MemAvailable
  parser correctness/error handling, and pressure-eviction logic

(cherry picked from commit cab034c)

* fix(orchestrator): enforce sandbox TTL on the node via WaitForExit

WaitForExit was defined but never called, leaving the API-layer evictor as
the sole mechanism to kill expired sandboxes.  If the API service restarts
the evictor goroutine stops and VMs accumulate indefinitely on nodes.

Two changes:

1. setupSandboxLifecycle (sandboxes.go): replace sbx.Wait with
   sbx.WaitForExit so the lifecycle goroutine races against the sandbox TTL.
   On timeout, Stop() is called explicitly before the normal Close/cleanup
   path runs.

2. WaitForExit (sandbox.go): replace the one-shot time.After with a
   time.NewTimer loop that re-checks endAt after each fire.  This means a
   KeepAlive that calls SetEndAt mid-flight correctly resets the node-side
   deadline instead of being silently ignored.

Fixes e2b-dev#3193

(cherry picked from commit 0a823f1)

* test(orchestrator): unit tests for WaitForExit TTL enforcement

5 cases covering the two code changes in the parent commit:

- AlreadyExpired: endAt in the past returns error immediately
- ExitBeforeTTL: clean FC exit before TTL returns nil
- ExitWithError: FC exits with error, error is wrapped and returned
- KeepAliveExtendsTTL: SetEndAt extension resets the timer loop;
  sandbox is NOT killed at the original deadline
- ContextCancelled: ctx cancel returns nil without killing

All pass with -race.

(cherry picked from commit 4826a8e)

* fix: propagate Docker image ENV vars to runtime sandbox processes

When creating a sandbox, merge the template metadata's Context.EnvVars
(which contains Docker image ENV directives) into the sandbox config's
Envd.Vars before sending them to envd via POST /init.

User-provided env vars from the SDK create() call take precedence over
template defaults. Per-command env vars from process.start() still
override both.

This fixes both the standard resume path and the filesystem-only cold
boot (reboot) path, where DefaultUser and DefaultWorkdir were already
restored from template metadata but EnvVars was not.

Closes e2b-dev#2268

(cherry picked from commit 5bfd55e)

* perf(orchestrator): replace ip-netns-exec with nsenter (cherry-pick e2b-dev#3037, process.go conflict resolved)

* fix(envd): correct tag-based process lookup (cherry-pick e2b-dev#3099, version bump deferred)

* fix(orchestrator): accept nil or 0.0.0.0/0 default route + bump envd 0.6.9

e2b-dev#3146 as-is panics at boot on our host (default route has non-nil Dst=0.0.0.0/0). Bump envd for cherry-picked e2b-dev#3099/e2b-dev#3145 envd changes.

---------

Co-authored-by: AdaAibaby <shaolila@buaa.edu.cn>
jakubno
jakubno previously requested changes Jul 9, 2026

@jakubno jakubno left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AdaAibaby , could you please fix the lint issue?

@AdaAibaby

AdaAibaby commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@AdaAibaby , could you please fix the lint issue?

Done. Does this look OK?

- Add blank line before return (nlreturn)
- Remove unnecessary int64() conversions (unconvert)
- Replace httptest.NewRequest with NewRequestWithContext (noctx)

@arkamar arkamar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please, also do the envd version bump.

@AdaAibaby

AdaAibaby commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

please, also do the envd version bump.

Done. Does this look OK?

@arkamar
arkamar enabled auto-merge (squash) July 9, 2026 14:35
@tvi
tvi requested a review from jakubno July 9, 2026 14:44
@arkamar
arkamar dismissed jakubno’s stale review July 9, 2026 14:45

issue was addressed and we need to move on.

@arkamar
arkamar merged commit fcf92fa into e2b-dev:main Jul 9, 2026
35 checks passed
tiago-mitralab added a commit to mitralab-dev/e2b-infra that referenced this pull request Jul 21, 2026
…0.6.9

e2b-dev#3146 as-is panics at boot on our host (default route has non-nil Dst=0.0.0.0/0). Bump envd for cherry-picked e2b-dev#3099/e2b-dev#3145 envd changes.
tiago-mitralab added a commit to mitralab-dev/e2b-infra that referenced this pull request Jul 24, 2026
…mote upstream e2b-dev#3145) (#6)

* fix(envd): use constant-time comparison for signature validation

Replace string inequality operator (!=) with crypto/subtle.ConstantTimeCompare
for signature validation in auth.go. The previous implementation was vulnerable
to timing attacks, where an attacker could potentially determine the correct
signature byte-by-byte by measuring response times.

This is a standard security best practice for comparing cryptographic values
such as HMAC signatures, tokens, and hashes.

(cherry picked from commit 85cce6c)

* test(envd): add validateSigning tests for signature validation

Add 6 test cases covering validateSigning:
- Accepts correct signature with expiration
- Rejects wrong signature
- Rejects expired signature
- Rejects missing signature parameter
- Accepts valid access token from header
- Rejects invalid access token from header

Also refactor existing tests to use a shared helper.

(cherry picked from commit 69cc233)

---------

Co-authored-by: AdaAibaby <shaolila@buaa.edu.cn>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants