testcafe icon indicating copy to clipboard operation
testcafe copied to clipboard

Support Client Certificate Authentication with HTTP/2

Open dennis-grunert opened this issue 3 years ago • 4 comments

What is your Scenario?

We are attaching a client certificate to some requests with the method described in DevExpress/testcafe-hammerhead#2489 in Testface. This works with HTTP/1.1 but fails once the server activates HTTP/2 in addition to HTTP/1.1 (ALPN) for Testcafe 1.14.2 (with Hammerhead 24).

What is the Current behavior?

Given Testcafe 1.14.2 (which uses Hammerhead 24) and connecting to a server which supports HTTP/2, the client certificate added with the method described in DevExpress/testcafe-hammerhead#2489 in Testface seems not to be received by the server.

When running Testcafe with DEBUG=*, it shows

hammerhead:destination:http2 Destination session created ...
hammerhead:destination:http2 Destination stream ...

i.e., it is apparently using HTTP/2 even though this is not yet supported according to the Testcafe website and DevExpress/testcafe#7182.

What is the Expected behavior?

The server should receive the client certificate for Hammerhead >= 23.

What is your public web site URL?

Unfortunately, we have no public URL available.

Steps to Reproduce:

  1. Send a client certificate to a server only supporting HTTP/1.1 with Testcafe 1.13.0 (Hammerhead < 23). Verify that the certificate is successfully received.
  2. Upgrade the server to also support HTTP/2. The test still succeeds.
  3. Upgrade to Testcafe 1.14.2 (Hammerhead > 23). The test will fail.
  4. Deactivate HTTP/2 support at the server. The test will succeed again.

Even though DevExpress/testcafe-hammerhead#2653 also had the same workaround of downgrading to Hammerhead < 23, the fix provided in Testcafe 1.15.2-rc1 does not fix this issue here.

Testcafe HTTP methods on server Client Certificate received
1.13.0 HTTP/1.1 yes
1.13.0 HTTP/1.1 and HTTP/2 yes
1.14.2 HTTP/1.1 yes
1.14.2 HTTP/1.1 and HTTP/2 no
1.15.2-rc.1 HTTP/1.1 yes
1.15.2-rc.1 HTTP/1.1 and HTTP/2 no

The 3rd column should always show "yes".

Your Environment details:

  • node.js version: v14.17.0
  • browser name and version: Chrome 92.0.4515.131
  • platform and version: macOS 11.5.1 with Testcafe 1.14.2

dennis-grunert avatar Aug 04 '21 16:08 dennis-grunert

Hammerhead v24 shipped with TestCafe v14 implements server-side only HTTP/2 support. Since we still have to implement client-side HTTP/2 support to achieve full HTTP/2 compatibility, we cannot close DevExpress/testcafe#7182 yet.

The Client Certificate Authentication flow differs in HTTP/1.1 and HTTP/2 versions. In HTTP/1.1, you sign all HTTP requests with your certificate, and when testing your app with TestCafe, you can use the RequestHook#onRequest method to provide your certificate for signing your app's requests.

In HTTP/2, you should create and sign an HTTP/2 session before sending HTTP requests. Currently, TestCafe doesn't have a hook to customize a session when it's created, thus you cannot provide a certificate and enable the Client Certificate Authentication with HTTP/2.

Until we implement a special hook for handling HTTP/2 sessions, you can downgrade your server to HTTP/1.1. I'm also looking for a way to disable HTTP/2 on the TestCafe side. I will share any results if I find anything.

AndreyBelym avatar Aug 09 '21 14:08 AndreyBelym

@AndreyBelym

I'm also looking for a way to disable HTTP/2 on the TestCafe side. I will share any results if I find anything.

So far, I only see that PR DevExpress/testcafe-hammerhead#2681 of hammerhead introduced --disable-http2, which we already tried (see the original post above) both for 1.15.3 and the latest 1.18.5.

I don't see why this is tracked as an enhancement when it is a regression bug. We are forced since one year to stay on the old version 1.13. Every version above triggers this bug not allowing us to send client certificates as we were able to do so before. There should be at least a way to disable HTTP/2 functionality on the server side of hammerhead (--disable-http2 is not working, see above) to return to the old behavior.

dennis-grunert avatar Apr 06 '22 15:04 dennis-grunert

Hi @dennis-grunert

In the earlier TestCafe versions, requests were sent using the http/https module (not http2). The test server usually accepts such requests even if it is configured for using HTTP2. Then, we implemented the native HTTP2 support on the hammerhead side. Over time, we encountered a lot of issues with the implementation of the HTTP2 protocol in Node.js. To fix this quickly, we introduced the --disable-http2 flag that forces the old request sending way. This flag should fix your use case. If it's not so, please share an example where the issue is reproduced.

I don't see why this is tracked as an enhancement when it is a regression bug.

Since the HTTP2 protocol implementation is very different from HTTP, it's necessary to implement the new functionality (see https://github.com/DevExpress/testcafe/issues/6446#issuecomment-895293414).

miherlosev avatar Apr 08 '22 08:04 miherlosev

Update: Setting the --disable-http2 flag now works. It was a misuse on my side. Since we use a runner object, we cannot use the CLI argument --disable-http2. Instead I tried to set it with the .run() method, which is not supported. Setting it in the config file works.

dennis-grunert avatar Apr 25 '22 16:04 dennis-grunert

This issue can have some similarities with #7176

AndreyBelym avatar Oct 21 '22 10:10 AndreyBelym

This issue has been automatically marked as stale because it has not had any activity for a long period. It will be closed and archived if no further activity occurs. However, we may return to this issue in the future. If it still affects you or you have any additional information regarding it, please leave a comment and we will keep it open.

github-actions[bot] avatar Sep 07 '23 01:09 github-actions[bot]

We're closing this issue after a prolonged period of inactivity. If it still affects you, please add a comment to this issue with up-to-date information. Thank you.

github-actions[bot] avatar Sep 17 '23 01:09 github-actions[bot]