Password escapes in SQL Azure connection string - entity-framework-core

I had the bright idea of generating a secure password using KeePass password manager and give it to my DBA.
Now I constructed my Azure SQL connection string as follows
Server=tcp:something.database.windows.net,1433;Initial Catalog=SomeDbName;Persist Security Info=False;User ID=someuser;Password=[read later];MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;
The password contains at least the following characters, along with upper/lowercase/digits
/"|&#]<#
Error is: ArgumentException: Format of the initialization string does not conform to specification starting at index 151.
At index 151 I can see the semicolon after the username (which I named someuser in the redacted example but only contains lowercase and a digit). VS Code points column 151 right before the ;Password= sequence
Questions:
Does my SQL Azure password contain illegal characters?
Which ones need to be escaped?
How do I escape them?
[Edit]: a note about the double quotes, which must be always escaped in C# Strings. I buried the connection string under Azure App configuration tab. It means that the double quote is unlikely to be re-escaped. I believe EF Core currently reads double-quote correctly

Actually escaping is specified here: connection-strings
Simple test shows that for your password, it is enough to add single quotes:
var csBuilder = new System.Data.SqlClient.SqlConnectionStringBuilder();
csBuilder.Password = "/\"|&#]<#";
var cs = csBuilder.ConnectionString;
Console.WriteLine(cs);
Password='/"|&#]<#'

Related

Postgres - PreparedStatement.setString sending incorrect data

I'm trying to use select pg_catalog.hashtext(?) via JDBC PreparedStatement, and running into a weird behavior.
For most strings it works fine, e.g. the following randomly generated string:
"Fm_:VW:<jBGOl$K "
and I get the correct hash back: 641495800
But for some of the strings, it spits back a hash that doesn't match the value when I query directly the DB via psql or some other tool such as DataGrip.
For instance, this works fine:
"}F:d(2 dS8xt9KP0$~tYw;R(V"!2[7&Xs2Wj#5 k|F[}%.ZQ^93~
Cuk&93d!t8b|{4F&{1j{.;C},1s/b&wYZ Ckc5vqy|e+5&5EW%RQ6F0>R4#h.6$iU>{=kl!{e(CTH^DvN/<eG9 bjHx#9=&& G$W_Y =! j\q3T;[H.ve-~>S5j8eI.gWQmg. C!WpWK0z>f?^^LLMO:3R';!4eVxU2)~1F6Zs!p0 F'1b*G:xBO5cN{O'1P~
fj5g%IcT}]w ;;DlD Q~D=wT qN7zON]/J9Heh3qwJ #n qMTG\M7#h,8JUP3Sl}L:wb7#bRc&eIWp\z>HuwZI2Ej5;v7M _8DU.d?mvD| !rS!XS;8QQYh6D=BMJ5m2$>cR ob#'{dCOr#NzDk c!JtQbzCg&#dG:qtHy)O4 ohWQ`ed
2 O'HmHt\<SO
gHKAo`WIb"HF\LrpKKDsW -e##v%RS+,-61lze bd|tyl);A0h":O40O71b(0cDM57gTFL~[7ksp
_Nx:"
But this doesn't:
".4X$!S"s
3E&fJZP*yC#6 ii7^D%Nj3Qn(]:&ykP3(%9 Ww}| ZOmcZ:(w<d= On/m\)vfAEu)s:Yy<17:l9GImT!BgH,FG(:DanwL|3'#XS
a_+nwbqPYBu[DWW`VbBKzF%CnaYpH "
Now, I tried using Statement instead of PreparedStatement along with a String concatenated query, and that works fine, as long as I escape single-quote characters (') with two-single quotes ('') before executing the query. So it appears that somehow PreparedStatement.setString is doing something weird with the String that I pass to it.
Note: The reason I'm testing this with random strings is because my code needs to be able to work with any UTF-8 string that's thrown at it. This test only uses ASCII, and it's already failing in some cases. I don't want to use Statement as that opens up a whole different discussion.

How to escape special characters on saving/retrieving data from Mongo

Assume a value has all windows special characters including "-" and it cannot be inserted directly to Mongo.
where i can find the mongo db special character restrictions?
How to escape while saving or retrieving?
example, do we need to pass the value within brackets ([...])? how to insert and retrieve the record with special character.
Thanks.
Values in MongoDB can be any UTF-8 string. Escaping would be the responsibility of your client program. Depending on which client program / language driver you are using, you would need to use the necessary escape character(s) for that language.
Since you mentioned that you're using Jongo, that means that you're using Java and the mongo-java-driver. In Java, you can just use the unicode escape sequence for the character you're trying to use. For example, \u2014 is the em-dash character.
For example:
DB db = new MongoClient().getDB("test");
Jongo jongo = new Jongo(db);
MongoCollection collection = jongo.getCollection("mycollection");
collection.insert("{fieldWithDash: 'x-y', fieldWithEmDash: 'x\u2014y'}");
Test test = collection.findOne("{fieldWithEmDash: 'x\u2014y'}").as(Test.class);
System.out.println(test);
This:
MongoCollection.findOne(query, parameter)
resolved the problem.
Query and parameter explicite:
MongoCollection.findOne("{ empName: # }", empName)

Powershell Byte Array input string invalid format

I've written a powershell script which changes the password of a local administrator that works well - It sets the password through a config file which contains the encrypted password and the aes key with which it was generated.
Its done the way described here: http://www.adminarsenal.com/admin-arsenal-blog/secure-password-with-powershell-encrypting-credentials-part-2
Now we have a management suite which streamlines administration of windoze and linux, and somehow it doesnt pass the aes key right into the script.
If I try to execute it through the management suite, I get the following error:
Cannot convert value "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33" to type "System.Byte". Error: "Input string was not in a correct Format."
I think the problem is the difference between PS and the management suite to handle variables (Or the black magic Powershell does under the hood which the management suite doesnt). In the script im reading in the aes-key from config file to a variable, which contains the values that are in the error message, which represent the aes key.
Now my question is: How do i get powershell to recognize the aes key as a byte array?
I cannot simply do a get-content C:\aes_keyfile, which maybe does the right typecast or whatever, because the streamline process has its own methods, so what I get in the script is the following:
$blah = $blahobject.get_variable("aeskey")
$blah
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33
I cant do:
[byte[]]$new_blah = $blah - Error: Cannot convert value "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33" to type "System.Byte[]". Error: "Input string was not in a correct format.""
What is the correct format? How can I find out what it is current and what it expects?
Ok, i found it out, thanks to your hint with the type:
I had to split it at the comma, so the right way is:
[byte[]]$new_blah = $blah.split(",")
Now the decryption of the password works.
Thanks a lot :>

hstore value with single quote

I asked similar question here for: hstore value with space. And get solved by user: Clodoaldo Neto. Now I have come across next case with string containing single quote.
SELECT 'k=>"name", v=>"St. Xavier's Academy"'::hstore;
I tried it by using dollar-quoted string constant by reading http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS
SELECT 'k=>"name", v=>$$St. Xavier's Academy$$'::hstore;
But I couldn't get it right.
How to make postgresql hstore using strings containing single quote?
It seems like there are more such exceptions possible for this query. How to address them all at once?
You can escape the embedded single quote that same way you'd escape any other single quote inside a string literal: double it.
SELECT 'k=>"name", v=>"St. Xavier''s Academy"'::hstore;
-- ------------------------------^^
Alternatively, you could dollar quote the whole string:
SELECT $$k=>"name", v=>"St. Xavier's Academy"$$::hstore;
Whatever interface you're using to talk to PostgreSQL should be taking care of these quoting and escaping issues. If you're using manual string wrangling to build your SQL then you should be using your driver's quoting and placeholder methods.
hstore's internal parsing understands double quotes around keys:
Double-quote keys and values that include whitespace, commas, =s or >s.
Dollar quoting is, as you noted, for SQL string literals, hstore's parser doesn't know what they mean.

How can I quote a named argument passed in to psql?

psql has a construct for passing named arguments:
psql -v name='value'
which can then be referenced inside a script:
SELECT :name;
which will give the result
?column?
----------
value
(1 row)
During development, I need to drop and recreate copies of the database fairly frequently, so I'm trying to automate the process. So I need to run a query that forcibly disconnects all users and then drops the database. But the database this operates on will vary, so the database name needs to be an argument.
The problem is that the query to disconnect the users requires a string (WHERE pg_stat_activity.datname = 'dbname') and the query that drops requires an unquoted token (DROP DATABASE IF EXISTS dbname). (Sorry. Not sure what to call that kind of token.)
I can use the named argument fine without quotes in the DROP query, but quoting the named argument in the disconnect query causes the argument to not be expanded. I.e., I would get the string ':name' instead of the string 'value'.
Is there any way to turn the unquoted value into a string or turn a string into an unquoted token for the DROP query? I can work around it by putting the disconnect and DROP queries in separate scripts and passing the argument in with quotes to the disconnect and without quotes to the DROP, but I'd prefer they were in the same script since they're really two steps in a single process.
Use:
... WHERE pg_stat_activity.datname = :'name'
Note the placement of the colon before the single quote.
The manual:
If an unquoted colon (:) followed by a psql variable name appears
within an argument, it is replaced by the variable's value, as
described in SQL Interpolation below. The forms
:'variable_name' and :"variable_name" described there work as well.
And:
To quote the value of a variable as an SQL literal, write a colon
followed by the variable name in single quotes.