Security defaults: http SSO callbacks in production, and secrets on the importer command line - #8
Merged
Merged
Conversation
`SOCIAL_AUTH_REDIRECT_IS_HTTPS` was False everywhere. SSO callback and redirect URLs are built from the request, and behind a TLS-terminating proxy the request this process sees is plain HTTP -- so the URL handed to the identity provider could come out as `http://`. Either the provider rejects it for not matching its registered redirect URI and SSO simply breaks, or the exchange completes over an unprotected scheme with an authorization code in it. True in the production profile, where TLS terminates in front of this process by definition. The development default stays False, since a dev server speaks plain HTTP and forcing https makes SSO untestable locally; that is now written down rather than implied. `SECURE_PROXY_SSL_HEADER` is deliberately *not* set alongside it. It makes Django believe any request carrying `X-Forwarded-Proto: https`, and `PROXY_IP_ALLOWED_LIST` is empty by default -- proxy headers trusted unconditionally -- so enabling it without a trusted proxy in front lets a client assert its own scheme. It belongs in a conf.d override once the proxy is the only route in, and the production settings now say so with the pairing spelled out.
`--token` and `--password` were the only direct options, and both put a secret in the process list, in shell history and in process accounting -- readable by every other user on the box for as long as the import runs, which is not brief. The environment variables helped, but a secret in the environment is still readable through /proc for the same duration and is inherited by every child. Adds `--token-file` and `--password-file`, and an interactive `getpass` prompt when a username is given without a password. Resolution order is file, environment, then the deprecated flag; the prompt only fires when stdin is a terminal, so a non-interactive run fails with a message instead of blocking on a read that never returns. Missing basic-auth credentials now fail with that message rather than reaching the API with none. `--token` and `--password` still work and are marked DEPRECATED in `--help` and in the runtime warning, with the removal named as the next breaking release -- taking them away now would break every existing automation that calls this.
krlex
force-pushed
the
fix/security-defaults
branch
from
August 19, 2026 21:17
6247ed0 to
2951e67
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes M7 and L2 from the 2026-08-19 Codex review. Two independent
defaults, both about a secret or a scheme leaving the process in a way nobody
chose.
M7 — SSO callbacks could be issued over http in production
SOCIAL_AUTH_REDIRECT_IS_HTTPSwas False everywhere. Callback and redirect URLsare built from the request, and behind a TLS-terminating proxy the request this
process sees is plain HTTP — so the URL handed to the identity provider could
come out as
http://. Either the provider rejects it for not matching itsregistered redirect URI and SSO breaks, or the exchange completes over an
unprotected scheme with an authorization code in it.
True in the production profile, where TLS terminates in front of this process by
definition. The development default stays False — a dev server speaks plain HTTP
and forcing https makes SSO untestable locally — and that is now written down
rather than implied.
SECURE_PROXY_SSL_HEADERis deliberately not set alongside it. It makesDjango believe any request carrying
X-Forwarded-Proto: https, andPROXY_IP_ALLOWED_LISTis empty by default, so proxy headers are trustedunconditionally — enabling it without a trusted proxy in front lets a client
assert its own scheme. It belongs in a conf.d override once the proxy is the only
route in; the production settings now spell out the pairing.
L2 —
import_from_awxhad no unexposed way to pass a secret--tokenand--passwordwere the only direct options, and both put a secret inthe process list, in shell history and in process accounting — readable by every
other user on the box for as long as the import runs, which is not brief. The
environment variables helped, but a secret in the environment is still readable
through
/procfor the same duration and is inherited by every child.Adds
--token-fileand--password-file, and an interactivegetpasspromptwhen a username is given without a password. Order is file, environment, then the
deprecated flag. The prompt only fires when stdin is a terminal, so a
non-interactive run fails with a usable message instead of blocking on a read
that never returns; missing basic-auth credentials now fail with that message
rather than reaching the API with none.
--tokenand--passwordstill work, marked DEPRECATED in--helpand in theruntime warning, with removal named as the next breaking release. Taking them
away now would break every automation that calls this — which is what the review
recommends too.
Verified
test_dynamic_survey_standalone.pyexcepted; itcannot be collected on
developat all, which forail-backend#6 fixes).develop— all pre-existing in inherited AWX code, none added here.