Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Password masking #1155

Closed
dealproc opened this issue Jan 11, 2016 · 22 comments
Closed

Password masking #1155

dealproc opened this issue Jan 11, 2016 · 22 comments
Labels

Comments

@dealproc
Copy link

What is the state of capabilities for NLog to mask passwords as part of writing to the different sinks? Is it something that the application author is responsible for, or is there room for extension of the logging framework to provide for this?

@304NotModified
Copy link
Member

This is currently not possible out of the box, but I think you can implement it in a few lines - depending on the case.

@UgurAldanmaz
Copy link
Contributor

What do you mean with password masking? Passwords that in the NLog configuration, or log outputs that contains sensitive data like password, or another?

@304NotModified
Copy link
Member

Good question @UgurAldanmaz , I assumed the latter.

@dealproc
Copy link
Author

If I push a message into the pipeline of NLog, and attach an exception to it. Anything that is pushed out to any logger would not show password={my super secret password from my connection string}; or "password": "super secret password my user submitted"

Not sure how to explain this further.

@304NotModified
Copy link
Member

You can use the replace layout renderer for that (with regex)

https://github.com/NLog/NLog/wiki/Replace-Layout-Renderer

@dealproc
Copy link
Author

Can you please provide an example of setting this layout up? How would it work for dumping stack traces, inner exceptions, etc. I'm not replacing the password= portion of password=mysecretpassword, i'm trying to make it look like password=****** in these scenarios.

@bhaeussermann
Copy link
Contributor

How about using a regex lookbehind and lookahead? Maybe something like (?<=password=').*?(?=')

@bhaeussermann
Copy link
Contributor

@dealproc Did it work?

@dealproc
Copy link
Author

got side tracked. trying to get to vs2015, but will get back to this shortly.

@304NotModified
Copy link
Member

OK,

The regex (?<=password=').*?(?=') works, but it needs then quotes. E.g. password='mysecretpassword'. password=mysecretpassword wont work. Not sure if that's correct.

You need after all something like this: (< needs to be replaced)

${replace:searchFor=(?&lt;=password=').*?(?='):replaceWith=******:regex=true:inner=${message}}

If there performance is important, I would advise to write a custom replace which doesn't use a regex.

@bhaeussermann
Copy link
Contributor

If the password is not surrounded by quotes, but followed by a semicolon, you can try (?<=password=).*?(?=;)

@304NotModified
Copy link
Member

@dealproc any success on this?

@304NotModified
Copy link
Member

Let us know if this is still an issue.

@excelthoughts
Copy link

I know this is an old thread.. but it's the only one on this masking issue.

I want to be able to search for a JSON formatted key value pair and apply masking.
Key/value pairs are both in double quotes and separated by a colon.

{"members":[{"password":"139347","Id":55}]}
want to convert to {"members":[{"password":"******","Id":55}]}

I assume double quotes need to be escaped like this (")

${replace:searchFor=(?&lt;=&quot;password&quot;:&quot;).*?(?=&quot;):replaceWith=******:regex=true:inner=${message}

[]http://www.convertstring.com/EncodeDecode/HtmlDecode# tells me that I have the syntax correct:
Converts to:

${replace:searchFor=(?<="password":").*?(?="):replaceWith=******:regex=true:inner=${message}

However the replace layout renderer replaces the entire message with blank.

@excelthoughts
Copy link

@304NotModified Are you able to reopen this issue, or do you want to start another thread?

@304NotModified
Copy link
Member

please a new issue and link to this one, thanks!

@search8
Copy link

search8 commented Dec 10, 2018

I know this is an old thread but maybe this is helpful to someone. I have created this pattern primarily to remove passwords in connections strings (but could also be easily adjusted to match other/similar patterns):

It replaces passwords in the following format:

Case-insensitive password variable:

Password=myPassword
password=myPassword

Different line endings:

Password=myPassword (with nothing to follow)
Password=myPassword; (followed by semicolon)
Password=myPassword this a continuation (followed by space)

This is the pattern I have used: (?i)(?<=password=)(.*?)(?=(\;|$| ))
I used this to test it against: https://regex101.com/

This is what it translates to in an NLog variable:

<variable name="replacePasswords" value="${replace:searchFor=(?i)(?&lt;=password=)(.*?)(?=(\;|$| )):replaceWith=******:regex=true:inner=${message}}" />

And this is how I used it as part of my Database logger:

<parameter name="@Message" layout="${replacePasswords}" />

Hope this helps.

@snakefoot
Copy link
Contributor

snakefoot commented May 10, 2021

Alternative you could ensure that the sensitive-data is encapsulated in a custom class/struct. Ex. class SensitiveInformation.

Then let the class implement IFormattable and ensure that ToString() returns an obfuscated version of the truth.

Alternative one can make use of RegisterObjectTransformation for the custom class SensitiveInformation.

@andygarratt
Copy link

@excelthoughts Did you manage to resolve your issue with the entire message being blank, I have exactly the same issue :(

@304NotModified
Copy link
Member

@andygarratt your regex is maybe wrong? Please test, for example on https://regex101.com

@fmarchetti88
Copy link

I know this is an old thread but maybe this is helpful to someone. I have created this pattern primarily to remove passwords in connections strings (but could also be easily adjusted to match other/similar patterns):

It replaces passwords in the following format:

Case-insensitive password variable:

Password=myPassword
password=myPassword

Different line endings:

Password=myPassword (with nothing to follow)
Password=myPassword; (followed by semicolon)
Password=myPassword this a continuation (followed by space)

This is the pattern I have used: (?i)(?<=password=)(.*?)(?=(\;|$| )) I used this to test it against: https://regex101.com/

This is what it translates to in an NLog variable:

<variable name="replacePasswords" value="${replace:searchFor=(?i)(?&lt;=password=)(.*?)(?=(\;|$| )):replaceWith=******:regex=true:inner=${message}}" />

And this is how I used it as part of my Database logger:

<parameter name="@Message" layout="${replacePasswords}" />

Hope this helps.

This is very helpful for me but i have a scenario where the logs can have password row logs like this:

Password=myPassword
Password:myPassword
"Password":myPassword

In other words, in addition to the equal (=) character, I could have the password string followed by a colon (:) or double quote ("). I tried to modify the regex in this way (?i)(?<=password[=:"]{1})(.*?)(?=(\;|$| )) and i succesfully tested it on https://regex101.com/ (it work for all my cases) but it doesn't work when i set as variable in my NLog.config. Someone can help me?

@304NotModified
Copy link
Member

I guess you need to xml escape it. Or set it from code (e.g. C#)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants