Skip to content

[BUG]Sandbox container hangs in an infinite certutil password-retry loop when restarted #1498

Open

Description

@J0kkeR

Summary

The sandbox container's entrypoint (containers/docker-entrypoint.sh) hangs forever after the container is restarted. On restart, certutil -N runs against an already-initialized NSS database and tries to prompt for the database password, but a detached container has no TTY. The failed read is treated as an invalid password, so NSS retries in a tight loop, producing endless log spam and ~100% CPU on one core. The script never proceeds past this point, so the CA trust import (certutil -A) is skipped and the container is left half-initialized.

Environment

  • STRIX version: 1.3.0 (sandbox image ghcr.io/usestrix/strix-sandbox:1.3.0)
  • OS: Windows 10 (Docker Desktop, desktop-linux context)
  • Docker Engine: 29.8.2
  • Also verified that main (containers/docker-entrypoint.sh) still has the same unguarded certutil -N call.

Steps to reproduce

  1. Start a STRIX session so the sandbox container is created and initialized. The first run succeeds: certutil -N -d sql:/home/pentester/.pki/nssdb --empty-password creates a fresh, empty-password NSS DB.
  2. Stop the sandbox container (e.g. docker stop, restarting Docker Desktop, or a host reboot).
  3. Start the same container again (docker start / Docker Desktop UI).
  4. The entrypoint re-runs and hangs at the certutil -N step.

Expected behavior

The entrypoint should be idempotent: restarting the container should reuse the existing NSS DB and finish initialization.

Actual behavior

docker logs fills with this pair of lines (hundreds of times per second, indefinitely):

Error opening input terminal for read
Invalid password.  Try again.
Error opening input terminal for read
Invalid password.  Try again.
...

docker top shows the stuck process, running for the entire container uptime:

root       sudo -u pentester certutil -N -d sql:/home/pentester/.pki/nssdb --empty-password
pentester  certutil -N -d sql:/home/pentester/.pki/nssdb --empty-password

docker stats shows ~102% CPU. Because the script is set -e and certutil never exits, everything after this line never runs on restart, including:

sudo -u pentester certutil -A -n "Testing Root CA" -t "C,," -i /app/certs/ca.crt -d sql:/home/pentester/.pki/nssdb

So the sandbox comes up with Caido running but without the testing CA in the browser trust store, which breaks HTTPS interception for any session that reuses it.

Root cause

NSS certutil -N only short-circuits the password prompt (via --empty-password) when it creates a fresh database. When cert9.db/key4.db already exist, certutil -N instead asks for the existing DB password through the NSS password callback. With no controlling terminal, the read fails ("Error opening input terminal for read"), the empty input is treated as a wrong password, and the callback retries forever.

This is a known NSS pitfall — mkcert hit the identical loop and worked around it by checking for the DB's existence before calling certutil -N: FiloSottile/mkcert#558

Suggested fix

Guard the initialization with an existence check, mirroring mkcert's approach:

sudo -u pentester mkdir -p /home/pentester/.pki/nssdb
if [ ! -f /home/pentester/.pki/nssdb/cert9.db ]; then
  sudo -u pentester certutil -N -d sql:/home/pentester/.pki/nssdb --empty-password
fi
sudo -u pentester certutil -A -n "Testing Root CA" -t "C,," -i /app/certs/ca.crt -d sql:/home/pentester/.pki/nssdb

(The certutil -A re-import is safe to repeat — it overwrites the entry with the same nickname.)

Workaround

Remove and recreate the sandbox instead of restarting it:

docker rm -f <sandbox-container>

The next STRIX session creates a fresh sandbox whose first-run initialization succeeds.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions