SEC2-038: seed_demo --password takes a password on the command line #980

Closed
opened 2026-10-17 10:39:08 +00:00 by tiagoagueda · 0 comments
Owner

Found on 2026-10-16 in a read-only security review of postulo at 56fc9d531, checked by a second, independent pass.

Severity: Informational · Category: Configuration · Reference: CWE-214 (Invocation of Process Using Visible Sensitive Information); OWASP A05:2021 (Security Misconfiguration)

Location:

  • src/postulo/core/management/commands/seed_demo.py:322 (parser.add_argument("--password", ...))
  • src/postulo/core/management/commands/seed_demo.py:331 (used as the created account's password)

Issue

It is the only management command in the core that reads a secret from argv (the backup tools pass PGPASSWORD through the environment, the catalogue signer reads its key from the environment or a file "never from an argument, where it would be in the shell's history"). A password given here is in the operator's shell history, in ps on the host for the length of the run, and in any container log that echoes the command. The command is for demonstrations, but it creates a real, verified account on whatever instance it is run against, and the help text invites a chosen password.

Impact

A demo account's password on a shared or long-lived instance can be read by anyone with the operator's shell history or process list; minor, since the account is a demo and the default is a random token_urlsafe(24).

Fix

Read the password from POSTULO_SEED_PASSWORD in the environment or from standard input, as createsuperuser does, and keep --password only as a flag meaning "prompt" (so it must not be used non-interactively); update the two CI invocations in .forgejo/workflows/ci.yml (PostgreSQL job) to pass it through env:. scripts/screenshots.py calls the command with a keyword argument and needs no change. Done when: a test calls the command with the variable set and no argument and gets an account with that password.

Found on 2026-10-16 in a read-only security review of `postulo` at `56fc9d531`, checked by a second, independent pass. **Severity:** Informational · **Category:** Configuration · **Reference:** CWE-214 (Invocation of Process Using Visible Sensitive Information); OWASP A05:2021 (Security Misconfiguration) **Location:** - `src/postulo/core/management/commands/seed_demo.py:322` (`parser.add_argument("--password", ...)`) - `src/postulo/core/management/commands/seed_demo.py:331` (used as the created account's password) ## Issue It is the only management command in the core that reads a secret from `argv` (the backup tools pass `PGPASSWORD` through the environment, the catalogue signer reads its key from the environment or a file "never from an argument, where it would be in the shell's history"). A password given here is in the operator's shell history, in `ps` on the host for the length of the run, and in any container log that echoes the command. The command is for demonstrations, but it creates a real, verified account on whatever instance it is run against, and the help text invites a chosen password. ## Impact A demo account's password on a shared or long-lived instance can be read by anyone with the operator's shell history or process list; minor, since the account is a demo and the default is a random `token_urlsafe(24)`. ## Fix Read the password from `POSTULO_SEED_PASSWORD` in the environment or from standard input, as `createsuperuser` does, and keep `--password` only as a flag meaning "prompt" (so it must not be used non-interactively); update the two CI invocations in `.forgejo/workflows/ci.yml` (PostgreSQL job) to pass it through `env:`. `scripts/screenshots.py` calls the command with a keyword argument and needs no change. Done when: a test calls the command with the variable set and no argument and gets an account with that password.
tiagoagueda added this to the 1.0.0 milestone 2026-10-17 10:39:09 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#980
No description provided.