bjowes / cypress-ntlm-auth

Windows authentication plugin for Cypress
MIT License
55 stars 9 forks source link

'SELF_SIGNED_CERT_IN_CHAIN' Error when calling Authentication Server #172

Closed ninjabadgerpirate closed 2 years ago

ninjabadgerpirate commented 3 years ago

Hello I am trying to integrate Cypress.IO in our environment, and I am getting the following error when calling one of our APIs that using NTLM to authenticate the client's identity.

PROXY_TO_SERVER_REQUEST_ERROR on /api/v1/Account: Error: self signed certificate in certificate chain at TLSSocket.onConnectSecure (_tls_wrap.js:1497:34) at TLSSocket.emit (events.js:315:20) at TLSSocket._finishInit (_tls_wrap.js:932:8) at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:706:12) { code: 'SELF_SIGNED_CERT_IN_CHAIN' } Destroying client socket. +18s

The API has an SSL associated with it, but the certificate has been issued by my company's internal networking team. I suspect that because of this, and the lack of a "real" intermediate authority the SSL is being seen as a self signed certificate. Is there anyway I can get cypress-ntlm to accept these self signed certificates?

I tried running the following command:

set NODE_TLS_REJECT_UNAUTHORIZED=0

And this did not resolve the issue. I tried converting the SSL Certificate into a .cer fle and using this line in the hopes that it would allow the SSL to be correctly validated:

set NODE_TLS_REJECT_UNAUTHORIZED=0

But it didn't seem to do anything. I really want to use Cypress.IO, but this issue is currently a blocker for us adopting the tool. Any help you could offer me would be greatly appreciated.

bjowes commented 3 years ago

Hi @ninjabadgerpirate - are you sure you are setting the environment variable correctly? Setting it should disable all cert checks, including the one you are seeing. A common issue is using the set command within Powershell. This has no effect. The set command should only be used in a cmd prompt. In Powershell, you would set it like this $env:NODE_TLS_REJECT_UNAUTHORIZED=0

Also, it should be possible to resolve it properly even if there are no intermediate certs. Assigning your public internal CA Cert to NODE_EXTRA_CA_CERTS should work. For a more details explanation on cert handling, you can have a look at my conference session: https://youtu.be/gpT8uieBqX0

ninjabadgerpirate commented 3 years ago

Firstly, thank you so much for your prompt response - I really appreciate all the work that you have already done on this module. Your suggestion was correct and has resolved the issue I was experiencing with SELF_SIGNED_CERTIFICATE, but now I think I am dealing with a similar issue to what has been outlined here:

When I try to connect to my QA SSO server, I get a 401 Unauthorized error, even though I have confirmed that the credentials that I am using are correct (My SSO server is hosted in IIS 10 which seems to line up with the issue linked above) I have tested the same request against a locally hosted version of the SSO API, and it works as expected.

I have enabled debugging in my application, and I am seeing the following error:

cypress:plugin:ntlm-auth PROXY_TO_SERVER_REQUEST_ERROR on /: Error: Parse Error: Expected HTTP/ at Socket.socketOnData (_http_client.js:509:22) at Socket.emit (events.js:315:20) at addChunk (_stream_readable.js:309:12) at readableAddChunk (_stream_readable.js:284:9) at Socket.Readable.push (_stream_readable.js:223:10) at TCP.onStreamRead (internal/stream_base_commons.js:188:23) { bytesParsed: 241, code: 'HPE_INVALID_CONSTANT', reason: 'Expected HTTP/', rawPacket: <Buffer 48 54 54 50 2f 31 2e 31 20 35 30 34 20 47 61 74 65 77 61 79 20 54 69 6d 65 6f 75 74 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 74 65 78 74 2f 68 ... 2532 more bytes> } Destroying client socket. +6ms cypress:plugin:ntlm-auth PROXY_TO_SERVER_REQUEST_ERROR on /: Error: Parse Error: Expected HTTP/ at Socket.socketOnData (_http_client.js:509:22) at Socket.emit (events.js:315:20) at addChunk (_stream_readable.js:309:12) at readableAddChunk (_stream_readable.js:284:9) at Socket.Readable.push (_stream_readable.js:223:10) at TCP.onStreamRead (internal/stream_base_commons.js:188:23) { bytesParsed: 241, code: 'HPE_INVALID_CONSTANT', reason: 'Expected HTTP/', rawPacket: <Buffer 48 54 54 50 2f 31 2e 31 20 35 30 34 20 47 61 74 65 77 61 79 20 54 69 6d 65 6f 75 74 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 74 65 78 74 2f 68 ... 2539 more bytes> } Destroying client socket. +6ms HEAD / - - ms - - cypress:plugin:ntlm-auth Removed agent for 127.0.0.1:58297 due to socket.close +4ms cypress:plugin:ntlm-auth Removed agent for 127.0.0.1:58298 due to socket.close +1ms HEAD / - - ms - - cypress:plugin:ntlm-auth Received NTLM message type 2, using NTLMv2 +50ms cypress:plugin:ntlm-auth Sending NTLM message type 3 with initial client request +3ms cypress:plugin:ntlm-auth NTLM authentication failed (invalid credentials) with host https://mysso.domain.com:443/ +62ms cypress:plugin:ntlm-auth Removed agent for 127.0.0.1:58240 due to socket.close +758ms cypress:plugin:ntlm-auth Removed agent for 127.0.0.1:58249 due to socket.close +1s cypress:plugin:ntlm-auth Removed agent for 127.0.0.1:58290 due to socket.close +3s cypress:plugin:ntlm-auth Removed agent for 127.0.0.1:58293 due to socket.close +288ms GET // 304 1.482 ms - - GET /cypress/runner/cypress_runner.css 304 0.862 ms - - GET /__cypress/runner/cypress_runner.js 304 2.514 ms - - GET /cypress/static/favicon.ico 200 2.620 ms - - GET /cypress/iframes/integration/pages/open-orders/traders.orders.spec.js 304 1.495 ms - - GET /cypress/runner/fonts/fa-solid-900.woff2 304 3.074 ms - - GET /cypress/tests?p=cypress%5Cintegration%5Cpages%5Copen-orders%5Ctraders.orders.spec.js 200 6.094 ms - - GET /__cypress/tests?p=cypress%5Csupport%5Cindex.js 200 11.021 ms - - cypress:plugin:ntlm-auth Created agent for client 127.0.0.1:58311 to target http://127.0.0.1:57804/ +7s cypress:plugin:ntlm-auth Request to config API +1ms cypress:plugin:ntlm-auth Created untracked agent for target http://127.0.0.1:57804/ +1ms cypress:plugin:ntlm-auth Received valid NTLM config update +5ms cypress:plugin:ntlm-auth Added new hosts [ 'mysso.domain.com' ] +0ms cypress:plugin:ntlm-auth Created agent for client 127.0.0.1:58314 to target https://mysso.domain.com:443/ +41ms cypress:plugin:ntlm-auth Request to https://mysso.domain.com:443/ in registered NTLM Hosts +1ms cypress:plugin:ntlm-auth Received 401 with NTLM in www-authenticate header. Starting handshake. +72ms cypress:plugin:ntlm-auth Sending NTLM message type 1 +1ms cypress:plugin:ntlm-auth Received NTLM message type 2, using NTLMv2 +64ms cypress:plugin:ntlm-auth Sending NTLM message type 3 with initial client request +3ms cypress:plugin:ntlm-auth NTLM authentication failed (invalid credentials) with host https://mysso.domain.com:443/ +61ms cypress:plugin:ntlm-auth Removed agent for 127.0.0.1:58311 due to socket.close +5s cypress:plugin:ntlm-auth Removed agent for 127.0.0.1:58314 due to socket.close +243ms

I have searched online and it seems to suggest that HPE_INVALID_CONSTANT means that the response is malformed in some way: https://stackoverflow.com/questions/34769824/what-does-this-error-mean-hpe-invalid-constant

bjowes commented 3 years ago

I haven't seen this specific error before, but as you already found it indicates that the response is malformed. The response in question is the response from server (not from the plugin). Since the logs are a bit redacted I cannot see what server that response came from, but if you are only communicating with mysso.domain.com it would be from there.

From just decoding the raw buffer content it doesn't look invalid (the bytes in the log represent this:

HTTP/1.1 504 Gateway Timeout
Content-Type: text/h

Likely the root cause of the parsing error occurs later in the buffer - it could be that the content length is not defined correctly. Either way, the response is a 504 Gateway Timeout, signaling that the server is trying to act as a proxy and could not get a response back in time.

Does that help? I think I need to know more about your network and server setup to be able to help more.

ninjabadgerpirate commented 3 years ago

504 gateway timeout definitely means that the proxy is causing some kind of an issue. I am integrating this solution behind a corporate proxy, so I am pretty sure that the Proxy is causing this issue.

I have set my HTTP/HTTPS_PROXY/NO_PROXY environment variables and I see that the values are being reflected in the Cypress UI under Settings -> Configuration, however no matter what I try setting my NO_PROXY settings as, I cannot change the values that show up under Settings -> Proxy Settings:

image

The Proxy Server http://127.0.0.1:57942 is the value set by Cypress NTLM as the ntlmProxyUrl. The Proxy Bypass List is always set to <-loopback> which I understand forces all traffic for localhost to run through the proxy. I am trying to test an application that is running on my QA server within my network on a custom domain (e.g. myuidomain.com), so the domain is not localhost.

I believe that means that the Proxy Bypass List should include myuidomain.com, but I can't quite figure out how to set it correctly, it always seems to include the <-loopback> setting - can you advise me if I am doing something wrong?

bjowes commented 3 years ago

The proxy settings shown within Cypress are set by the plugin. This is how the plugin actually works, it acts as a proxy for Cypress where it can intercept the traffic and handle windows authentication when needed. So <-loopback> is correct, this is required for the traffic to pass to the plugin.

When you set NO_PROXY before starting cypress-ntlm, it will pick up that setting and use it internally. Then it will pass the <-loopback> setting along to cypress. So from your description you seem to have set it up properly.

If you enable debug logging, there is some information printed when the plugin modifies the NO_PROXY variable.

Does your corporate proxy require authentication? The plugin does not support that scenario.

ninjabadgerpirate commented 3 years ago

Hi bjowes, I haven't ever had to setup authentication with our internal proxy, so I don't think it requires authentication as I have gotten the proxy working with quite a few different tools without having to authenticate. At this point, not really sure what else I can try - I will try enabling debugging and digging through the logs to see if I can see what may be causing the issue.

bjowes commented 3 years ago

I have just made a beta version available that will accept (but warn) invalid (such as self signed) certs by default. Please try it out to see if that helps. npm i cypress-ntlm-auth@4.0.0-beta.1

ninjabadgerpirate commented 3 years ago

Hi Bjorn, thanks for letting me know. I will add it to my solution and let you know what I find. Beyond adding to as a dependency is there anything else I should do to enable this feature?

ninjabadgerpirate commented 3 years ago

Hi Bjorn, I have added the beta version and I removed the SSL Validation environment variable that I had enabled using: _$env:NODE_TLS_REJECTUNAUTHORIZED=0 but now my authentication no longer works. I am getting the following error:


  cypress:plugin:ntlm-auth Removed agent for 127.0.0.1:59867 due to socket.close +3ms
  cypress:plugin:ntlm-auth Created agent for client 127.0.0.1:59870 to target https://authserver.acml.com:443/ +17ms
  cypress:plugin:ntlm-auth Request to https://authserver.acml.com:443/ in registered NTLM Hosts +1ms
  cypress:plugin:ntlm-auth PROXY_TO_SERVER_REQUEST_ERROR on /SSO.Api/api/v1/Account: Error: unable to get local issuer certificate
    at TLSSocket.onConnectSecure (_tls_wrap.js:1497:34)
    at TLSSocket.emit (events.js:315:20)
    at TLSSocket._finishInit (_tls_wrap.js:932:8)
    at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:706:12) {
  code: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY'

When I re-run the the following line: $env:NODE_TLS_REJECT_UNAUTHORIZED=0, the authentication works again. Let me know if you need me to try anything different and I will give it a try.

bjowes commented 3 years ago

Well, it is in beta for good reason, but I have tested it successfully on my own machine. I will need to test it more on a windows machine. You could double-check that you are really using the beta version, and you could try setting the HTTPS_VALIDATION environment variable to something odd like 'invalid' - that should trigger an error log and would confirm that the code published in the release is indeed the correct one.

bjowes commented 3 years ago

Found an issue, just released cypress-ntlm-auth@4.0.0-beta.2. Please try that instead.

ninjabadgerpirate commented 3 years ago

Hi Bjorn, that looks like it did the trick. I no longer have the NODE_TLS_REJECT_UNAUTHORIZED variable set and it my tests executed as expected. Thanks very much for sharing this with me.

Please let me know if you need anything else from me, and I will do what I can to assist.

bjowes commented 3 years ago

That's great news! If you would have a look at the docs describing the HTTPS_VALIDATION, and give me a short feedback if it is clear and understandable that would be great. The whole intention of this change was to make it easier - so I want to make it fairly easy to understand the docs too :) Otherwise, just be alert if anything appears to behave strangely with the new version. I will likely go to stable if there are no new issues in the coming weeks.