Skip to content

Commit

Permalink
Merge pull request #3 from oxsecurity/add-option-to-partial-mask
Browse files Browse the repository at this point in the history
Add option to partial mask
  • Loading branch information
tamar-ox authored Dec 11, 2024
2 parents 5f78fc2 + 6f6eabd commit de2e86b
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 9 deletions.
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,24 @@ from masker_formatter import MaskerFormatter, SKIP_MASK
logger.info('Line you want to skip', extra=SKIP_MASK)
```

#### fix len masking
If you want the masking to be in a fixed size (and not in the secret len),
please set the `fix_masking_len`:
#### redact
Here’s a rewritten version suitable for inclusion in a README.md file:

---

### Partial Masking of Secrets
If you prefer to mask only a portion of a secret (rather than its entire length), you can set the `redact` parameter in the formatter. The `redact` parameter specifies the percentage of the secret to be masked.

Here’s an example of how to use it:

```
handler.setFormatter(
MaskerFormatter("%(asctime)s %(name)s %(levelname)s %(message)s",
fix_masking_len=30))
redact=30))
```

In this example, 30% of the secret will be masked. Adjust the `redact` value as needed to suit your requirements.

## The Config File

Here's where the magic happens!
Expand Down
14 changes: 10 additions & 4 deletions maskerlogger/masker_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,17 @@ class MaskerFormatter(logging.Formatter):
def __init__(self, fmt=None, datefmt=None, style='%', validate=True,
defaults=None,
regex_config_path=DEFAULT_SECRETS_CONFIG_PATH,
fix_masking_len=-1):
redact=100):
super().__init__(fmt, datefmt, style, validate=validate,
defaults=defaults)
self.fix_masking_len = fix_masking_len
self.redact = self._validate_redact(redact)
self.regex_matcher = RegexMatcher(regex_config_path)

def _validate_redact(self, redact: int) -> int:
if not (0 <= int(redact) <= 100):
raise ValueError("Redact value must be between 0 and 100")
return int(redact)

def format(self, record: logging.LogRecord) -> str:
if getattr(record, _APPLY_MASK, True):
self._mask_sensitive_data(record)
Expand All @@ -29,8 +34,9 @@ def _mask_secret(self, msg: str, matches: List[re.Match]) -> str:
for match in matches:
match_groups = match.groups() if match.groups() else [match.group()] # noqa
for group in match_groups:
replace_len = len(group) if self.fix_masking_len < 0 else self.fix_masking_len # noqa
msg = msg.replace(group, "*" * replace_len)
redact_length = int((len(group) / 100) * self.redact)
msg = msg.replace(
group[:redact_length], "*" * redact_length, 1)
return msg

def _mask_sensitive_data(self, record: logging.LogRecord) -> None:
Expand Down
2 changes: 1 addition & 1 deletion maskerlogger/secrets_in_logs_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def main():
handler = logging.StreamHandler()
handler.setFormatter(
MaskerFormatter("%(asctime)s %(name)s %(levelname)s %(message)s",
fix_masking_len=30))
redact=50))
logger.addHandler(handler)

logger.info('"current_key": "AIzaSOHbouG6DDa6DOcRGEgOMayAXYXcw6la3c"', extra=SKIP_MASK) # noqa
Expand Down

0 comments on commit de2e86b

Please sign in to comment.