|
31 | 31 | from tox.tox_env.installer import Installer
|
32 | 32 |
|
33 | 33 | LOGGER = logging.getLogger(__name__)
|
| 34 | +SECRET_ENV_VAR_REGEX = re.compile( |
| 35 | + r"""(?ix) # case-insensitive, verbose mode |
| 36 | + ^\s* # optional leading whitespace |
| 37 | + (?P<key> # capture group: key |
| 38 | + (?:\w*(_)?) |
| 39 | + (?: |
| 40 | + (SECRET|TOKEN|KEY|PASSWORD|PWD|CRED|PRIVATE|AUTH|API) |
| 41 | + ) |
| 42 | + (?:\w*) # allow variable prefixes/suffixes |
| 43 | + )\s*=\s* # equal sign with optional spaces |
| 44 | + (?P<value> # capture group: value |
| 45 | + (['"])? # optional opening quote |
| 46 | + ([A-Za-z0-9\-_]{12,}) # suspicious value (long, alphanumeric) |
| 47 | + \1? # optional closing quote matching opening |
| 48 | + ) |
| 49 | + """ |
| 50 | +) |
| 51 | + |
| 52 | + |
| 53 | +def redact_value(name: str, value: str) -> str: |
| 54 | + """Returns a redacted text if the key name looks like a secret.""" |
| 55 | + if SECRET_ENV_VAR_REGEX.match(name): |
| 56 | + return "*" * len(value) |
| 57 | + return value |
34 | 58 |
|
35 | 59 |
|
36 | 60 | class ToxEnvCreateArgs(NamedTuple):
|
@@ -461,8 +485,8 @@ def _write_execute_log(env_name: str, log_file: Path, request: ExecuteRequest, s
|
461 | 485 | with log_file.open("wt", encoding="utf-8") as file:
|
462 | 486 | file.write(f"name: {env_name}\n")
|
463 | 487 | file.write(f"run_id: {request.run_id}\n")
|
464 |
| - for env_key, env_value in request.env.items(): |
465 |
| - file.write(f"env {env_key}: {env_value}\n") |
| 488 | + for env_key, env_value in sorted(request.env.items()): |
| 489 | + file.write(f"env {env_key}: {redact_value(name=env_key, value=env_value)}\n") |
466 | 490 | for meta_key, meta_value in status.metadata.items():
|
467 | 491 | file.write(f"metadata {meta_key}: {meta_value}\n")
|
468 | 492 | file.write(f"cwd: {request.cwd}\n")
|
|
0 commit comments