I have an exception handler method in my VB.NET application that retrieves details from the last exception to occur and e-mails that information to our Help Desk (me) for diagnostics and troubleshooting. One instance of a possible exception is when the application attempts to connect or execute some SQL on one of our database servers. In those cases - especially when the exception is because of a failure to connect - I want to see the database connection string that's being used to make certain it's properly formatted.
However, database connection strings usually contain the user's ID and password, and I want to mask the password within the string. The challenge, however, is that we connect to multiple database types (e.g., PostgreSQL, MySQL, SQLite, MS Access, etc.) and, depending on the database, there may or may not be a password in the connection string. Also, connection string formats vary from one provider to the next.
I'm extremely unfamiliar with RegEx but, using https://regexr.com/, I've managed to come up with the following RegEx pattern that seems to work sometimes:
(?<=;?[Pp][Aa][Ss][Ss].*=)(.*?)(?=;)|$
An example connection string would look like this:
Host=SERVERNAME;Port=####;Database=DBNAME;Username=USERID;Password=MyPa$$Word;Integrated Security=False
The pattern above correctly matches MyPa$$Word
in the string if it's explicitly in this order, but if I move the Password
key/value pair closer to the beginning of the connection string like this:
Host=SERVERNAME;Port=9999;Password=MyPa$$Word;Database=DBNAME;Username=USERID;Integrated Security=False
it then matches MyPa$$Word
, DBNAME
, and USERID
. If I move it to the end of the string:
Host=SERVERNAME;Port=9999;Database=DBNAME;Username=USERID;Integrated Security=False;Password=MyPa$$Word
the pattern doesn't find any matches. Just to make sure the key/value with the space (Integrated Security=False
) wasn't confusing the pattern, I removed that from the string and got the same results.
Because the connection string may be structured in a variety of ways depending on the database type, the user input, etc., I'd like to be able to use RegEx to find the (case-insensitive) password key/value pair anywhere in the connection string, extract only the actual password value, and replace it with something (like [HIDDEN]
). I know that I could probably just do a String.Split(Convert.ToChar(";"))
on the whole connection string and check each key/value pair, but I'd prefer to do it with RegEx, if possible.