Summary
When APPMAP_DISPLAY_PARAMS=true is set, the Python agent uses repr() to serialize parameter and return values. For strings, this wraps the value in single quotes — e.g. a function returning my-api-key is recorded as 'my-api-key'.
The AppMap scanner's secret-in-log rule uses substring matching to detect when a secret-labeled function's return value appears inside a log-labeled function's parameters. Because repr() adds quotes around the secret return value, but the secret appears unquoted when interpolated into a larger f-string log message, the substring match fails.
Reproduction
Given:
from _appmap.labels import labels
@labels("secret")
def signoz_api_key() -> str:
return os.environ.get("SIGNOZ_API_KEY", "")
@labels("log")
def log(message: str, *, level: str = "info"):
print(f"[{level}] {message}", file=sys.stderr)
def init():
api_key = signoz_api_key()
log(f"SigNoz configured: api_key={api_key}") # secret leaked into log
With APPMAP_DISPLAY_PARAMS=true, the recorded events contain:
- Secret return value:
'snz-k8v2xQ9mP4wR7jL1nT6y' (with repr quotes)
- Log parameter:
'SigNoz configured: api_key=snz-k8v2xQ9mP4wR7jL1nT6y' (with outer repr quotes)
The scanner checks logParam.includes(secretReturnValue):
"'SigNoz configured: api_key=snz-k8v2xQ9mP4wR7jL1nT6y'".includes("'snz-k8v2xQ9mP4wR7jL1nT6y'")
// → false, because the leading quote of the secret doesn't match (preceded by `=` not `'`)
Expected behavior
The scanner should detect that the secret value snz-k8v2xQ9mP4wR7jL1nT6y appears in the log message, regardless of repr() quoting.
Suggested fix
Strip surrounding quotes from string values before recording them as secrets or before the substring comparison. In _appmap/event.py, the display_string() function could strip the repr() quotes for string types, or the agent could record a separate raw_value field without repr() wrapping for use by downstream tools.
Alternatively, this could be addressed in the scanner (recordSecrets.ts / secretInLog.ts) by stripping quotes from the parsed secret values before comparison.
Environment
- appmap-python: latest (tested via pip install)
- appmap-scanner: 1.89.1
- Python: 3.13
APPMAP_DISPLAY_PARAMS=true required to reproduce (without it, values are opaque object references and no detection is possible at all)
Summary
When
APPMAP_DISPLAY_PARAMS=trueis set, the Python agent usesrepr()to serialize parameter and return values. For strings, this wraps the value in single quotes — e.g. a function returningmy-api-keyis recorded as'my-api-key'.The AppMap scanner's
secret-in-logrule uses substring matching to detect when asecret-labeled function's return value appears inside alog-labeled function's parameters. Becauserepr()adds quotes around the secret return value, but the secret appears unquoted when interpolated into a larger f-string log message, the substring match fails.Reproduction
Given:
With
APPMAP_DISPLAY_PARAMS=true, the recorded events contain:'snz-k8v2xQ9mP4wR7jL1nT6y'(with repr quotes)'SigNoz configured: api_key=snz-k8v2xQ9mP4wR7jL1nT6y'(with outer repr quotes)The scanner checks
logParam.includes(secretReturnValue):Expected behavior
The scanner should detect that the secret value
snz-k8v2xQ9mP4wR7jL1nT6yappears in the log message, regardless ofrepr()quoting.Suggested fix
Strip surrounding quotes from string values before recording them as secrets or before the substring comparison. In
_appmap/event.py, thedisplay_string()function could strip therepr()quotes for string types, or the agent could record a separateraw_valuefield withoutrepr()wrapping for use by downstream tools.Alternatively, this could be addressed in the scanner (
recordSecrets.ts/secretInLog.ts) by stripping quotes from the parsed secret values before comparison.Environment
APPMAP_DISPLAY_PARAMS=truerequired to reproduce (without it, values are opaque object references and no detection is possible at all)