Skip to content

fix: prevent partial secret leak in sensitive_data redaction when secrets share substrings (#4609)#4628

Closed
passionworkeer wants to merge 1 commit intobrowser-use:mainfrom
passionworkeer:fix/sensitive-data-substring-leak
Closed

fix: prevent partial secret leak in sensitive_data redaction when secrets share substrings (#4609)#4628
passionworkeer wants to merge 1 commit intobrowser-use:mainfrom
passionworkeer:fix/sensitive-data-substring-leak

Conversation

@passionworkeer
Copy link
Copy Markdown

@passionworkeer passionworkeer commented Apr 7, 2026

Summary

The sensitive_data redaction in _filter_sensitive_data iterates over secrets in arbitrary order. When one secret is a substring of another (e.g. \�pi_key=abc123xyz\ and \key=abc123), the shorter secret may be replaced first, leaving a fragment of the longer secret in place.

Example:

  • Secrets: {'api_key': 'abc123xyz', 'key': 'abc123'}\
  • If \�bc123\ is replaced first → <secret>keyxyz\ (leaks \xyz\ from \�pi_key)

Fix: Sort secrets by length descending (longest first) before applying replacements.

Files Changed

  • \�rowser_use/agent/message_manager/service.py\ - sort sensitive_values by length (desc) before regex replacement

Closes #4609


Summary by cubic

Fix partial secret leaks in sensitive data redaction when secrets share substrings. Secret values are now sorted by length (longest first) before replacement to ensure longer secrets are fully masked.

Written for commit 78a93eb. Summary will update on new commits.

Copilot AI review requested due to automatic review settings April 7, 2026 09:19
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


TRIX Bot seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a sensitive-data redaction edge case in the message manager where replacing shorter secrets before longer ones could leave fragments of longer secrets unredacted (when secrets share substrings).

Changes:

  • Sort sensitive_values by descending value length before performing replacements in MessageManager._filter_sensitive_data.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +596 to 598
# Sort by length descending to avoid partial leaks when one secret is a substring of another
for key, val in sorted(sensitive_values.items(), key=lambda x: len(x[1]), reverse=True):
value = value.replace(val, f'<secret>{key}</secret>')
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regression coverage: this change fixes substring-overlap leaks by sorting sensitive values by length, but there’s no test asserting that when one secret is a substring of another the longer secret is fully redacted (and no suffix fragment remains). Please add a test case for this scenario (e.g., short='abc', long='abc-SECRET') so the bug can’t regress.

Copilot uses AI. Check for mistakes.
Comment on lines +596 to 598
# Sort by length descending to avoid partial leaks when one secret is a substring of another
for key, val in sorted(sensitive_values.items(), key=lambda x: len(x[1]), reverse=True):
value = value.replace(val, f'<secret>{key}</secret>')
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR fixes substring-order leaks in MessageManager._filter_sensitive_data, but the same replacement logic still exists in browser_use/agent/views.py (AgentHistory._filter_sensitive_data_from_string) without length-sorting and is used by AgentHistory.save_to_file(sensitive_data=...). That path can still partially leak secrets when values share substrings; consider applying the same ordering (or extracting a shared helper) so the fix is consistent across redaction entry points.

Copilot uses AI. Check for mistakes.
@laithrw
Copy link
Copy Markdown
Member

laithrw commented Apr 11, 2026

Thanks for the PR! Closing this in favor of #4660, which covers both redaction sites (this one fixes message_manager but misses the history serialization path in agent/views.py where secrets can also leak).

@laithrw laithrw closed this Apr 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: sensitive_data redaction breaks when one secret is substring of another (partial leak)

4 participants