Skip to content

Commit 90cb86a

Browse files
authored
Merge commit from fork
Mask values of subcommand option arguments
2 parents 2f3d60f + b35a63b commit 90cb86a

4 files changed

Lines changed: 35 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ and this project tries to adhere to [Semantic Versioning](https://semver.org/spe
3131

3232
- Update poetry to more recent version. (#347)
3333

34+
### Security
35+
36+
- Patch raw logging of '-O' values that could have included arbitrary secrets. (https://github.com/softwarepub/hermes/security/advisories/GHSA-jm5j-jfrm-hm23)
37+
3438
## [0.9.0] - 2025-02-26
3539

3640
### Added

src/hermes/commands/cli.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
HermesHarvestCommand, HermesProcessCommand, HermesCurateCommand,
1717
HermesDepositCommand, HermesPostprocessCommand, HermesInitCommand)
1818
from hermes.commands.base import HermesCommand
19+
from hermes.utils import mask_options_values
1920

2021

2122
def main() -> None:
@@ -63,7 +64,7 @@ def main() -> None:
6364

6465
logger.init_logging()
6566
log = logger.getLogger("hermes.cli")
66-
log.debug("Running hermes with the following command line arguments: %s", args)
67+
log.debug("Running hermes with the following command line arguments: %s", mask_options_values(args))
6768

6869
try:
6970
log.debug("Loading settings...")

src/hermes/utils.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from importlib.metadata import metadata
99
from mimetypes import guess_type
1010
from pathlib import Path
11+
import argparse
1112

1213

1314
def retrieve_project_urls(metadata_urls: list[str]) -> dict[str, str]:
@@ -80,3 +81,25 @@ def guess_file_type(path: Path):
8081

8182
# use non-strict mode to cover more file types
8283
return guess_type(path, strict=False)
84+
85+
def mask_options_values(args: argparse.Namespace) -> argparse.Namespace:
86+
"""Masks potentially sensitive values in the 'options' argument
87+
in the passed argparse.Namespace.
88+
89+
The main use case for this is preventing potentially sensitive
90+
data/secrets being included in raw args logging.
91+
92+
:param args: The argparse.Namespace to mask.
93+
:return: A copy of the namespace with masked sensitive values.
94+
"""
95+
import copy
96+
97+
masked_args = copy.copy(args)
98+
99+
# Mask the values for 'options' if they exist
100+
if hasattr(masked_args, "options") and masked_args.options:
101+
masked_args.options = [
102+
(key, "***REDACTED***") for key, value in masked_args.options
103+
]
104+
105+
return masked_args

test/hermes_test/test_utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import toml
77
from pathlib import Path
8+
from argparse import Namespace
89

910
pyproject = toml.load(Path(__file__).parent.parent.parent / "pyproject.toml")
1011
expected_name = pyproject["project"]["name"]
@@ -22,3 +23,8 @@ def test_hermes_user_agent():
2223
assert (
2324
hermes_user_agent == f"{expected_name}/{expected_version} ({expected_homepage})"
2425
)
26+
27+
def test_mask_values_options():
28+
from hermes.utils import mask_options_values
29+
ns = Namespace(foo="bar", options=[("foo", "bar"), ("bar", "foo")])
30+
assert mask_options_values(ns) == Namespace(foo="bar", options=[("foo", "***REDACTED***"), ("bar", "***REDACTED***")])

0 commit comments

Comments
 (0)