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

Connection fails if some parameters contain single quotes passed to the CrmServiceClient constructor. #518

Open
break9111 opened this issue Feb 24, 2023 · 5 comments
Assignees

Comments

@break9111
Copy link

break9111 commented Feb 24, 2023

I have identified the following error, which I think needs to be resolved.

How to reproduce the error
When connecting to Dataverse using Connect-CrmOnline, an error occurs if the user's password contains single quotes.

Description of the error

PS C:\Users\aaaa> Connect-CrmOnline  -ServerUrl https://org27XXXXXX.crm.dynamics.com -Credential $cred
New-Object : Exception calling ".ctor" with "1" argument(s): "Object reference not set to an instance of an object."
At C:\Users\aaaa\Documents\WindowsPowerShell\Modules\Microsoft.Xrm.Data.Powershell\2.8.19\Microsoft.Xrm.Data.Powershel
l.psm1:255 char:19
+ ... obal:conn = New-Object Microsoft.Xrm.Tooling.Connector.CrmServiceClie ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

Cause of error
When calling the CrmServiceClient constructor, the input parameters for Connect-CrmOnline are concatenated into a single string and passed to the constructor as follows.
If the password contains single quotes, the process of parsing this concatenated string will fail, resulting in an error before any authentication process is performed.

$global:conn = New-Object Microsoft.Xrm.Tooling.Connector.CrmServiceClient -ArgumentList $cs
##value##
$cs = "RequireNewInstance=True;Url={your Dataverse environment URL};AuthType=Office365;Username=testuser@aaaaa.onmicrosoft.com;Password='Pass'word'";

Other ways to cause errors
I have observed that the same error occurs with the -ConnectionString parameter as well as the -Credential parameter.
As far as I have tried in my environment, I think the same error occurs with Secret, but I don't know if the client secret of the service principal could contain single quotes. Does anyone know what the rule is for this?

Solution
I contacted MSFT with a support request, but they replied that they are not going to update the CrmServiceClient constructor.
To avoid the error, I think we need to update the logic of Connect-CrmOnline, if the password or connection string contains single quotes, to double the single quotes (escape) by replace function.

Password='Pass'word' → Password='Pass''word'

@seanmcne
Copy link
Owner

As a workaround for this trying using oAuth (-forceOAuth) that will help ensure its connecting using modern auth but also you won't have to handle the password directly (if you auth via the browser window directly).

Since escaping works as a workaround, let me see about building that in (replacing any single quotes with '' inside of the parameter itself). Thx for identifying this and reporting it!

@seanmcne seanmcne self-assigned this Feb 24, 2023
@break9111
Copy link
Author

Thank you for your reply. Even if -forceOAuth is used, an error will occur as long as -Credential is also used.
(I assume you replied about using -forceOAuth only)

As you say, I agree that authentication via the browser (interactive) will allow a successful connection using a user with a password containing single quotes.

@seanmcne
Copy link
Owner

I was able to find a few minutes today to code up something I think will work here https://github.com/seanmcne/Microsoft.Xrm.Data.PowerShell/tree/AddSingleQuotePasswordEscaping

Still need to test/validate and look at publishing but if you have a min to test it out let me know. Thx!

@break9111
Copy link
Author

I checked the commit you made. The fixes were exactly what I expected. I don't think there is a problem because the results are the same as what I have tested in the past.

One thing I'm worried about is when we used -ConnectionString as a parameter.
I want to cut out the password from the value that combines the parameters whose order is not fixed and replace it in the same way, but there is no appropriate delimiter.

Single quote is inappropriate because it is the cause of this issue, and other symbols (; and =) can also be included in passwords, so it is not possible to cut the password and value reliably.
Am I correct in understanding that there is no workaround for this part?

@seanmcne
Copy link
Owner

seanmcne commented Mar 3, 2023

I just stumbled up a comment in a stackoverflow that might offer a more comprehensive way to escape the string - I'll test this out later but wanted to be sure I captured it here.

# all chars. inside [...] are -escaped
'a*b\c~d;e(f%g?h.i:j@k/l' -replace '[*\\~;(%?.:@/]', '`$&'a`*b`\c`~d`;e`(f`%g`?h`.i`:j`@k`/l  

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

No branches or pull requests

2 participants