SEC2-038: seed_demo --password takes a password on the command line #980
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#980
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found on 2026-10-16 in a read-only security review of
postuloat56fc9d531, 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 passPGPASSWORDthrough 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, inpson 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_PASSWORDin the environment or from standard input, ascreatesuperuserdoes, and keep--passwordonly 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 throughenv:.scripts/screenshots.pycalls 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.