-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Send a PKI from the client to the server #2694
Comments
This is a critical piece of functionality for our ability to use Cypress as our testing framework. |
We also need to add a specific certificate to communicate with the server. |
I've reviewed the PR here #2740 and understand the implications of this and have some feedback. I see three areas that need to be addressed:
Thoughts: Update: |
Even in a CI environment it is more difficult to add this to a browser instance. |
Thanks for reviewing :) Just to provide a bit of background in regards to your first point, our reasoning for focusing on By allowing certs to be passed through via In regards to your third point, my understanding of how PKI typically works is that a certificate is unique to a single user/machine, but can be used to authenticate across multiple domains that a corporation manages. With this in mind, certainly for us, the ability to configure just a single certificate in We'd more than happily work with whatever implementation you felt was best, but hopefully this sheds some more light on what we're trying to achieve. |
@brian-mann Hi there. I worked with @matt-rhys-jones on this and we would like to keep this PR moving. Did you come to a conclusion on what you thought the best approach was? Thanks for the feedback btw. Cheers. |
This PR would need to be updated to reflect / address the issue in a more comprehensive way. I would prefer coming up with a solution that:
Updating just @matt-rhys-jones and @craigkj what would be most helpful is if you can find us examples of using other testing tools to accommodate this need - selenium/webdriver, puppeteer, etc. When I looked I did not see a way to launch chrome with arguments that would add these certificates so I cannot find a comparable way in which this could be achieved. If there are existing solutions we can piggy-back off of their ideas. To be clear, without an easy way to configure each browser means that we'd be looking at implementing this at the network layer behind the scenes in a way that the browser doesn't know that it's happening. That'll work across all browsers but may have unintended effects, since I'm not super experienced with PKI in general, although I understand how it works. Additionally it seems that whatever way we come up with would have to be targeted on a domain basis, and possibly also expose specific sets of configuration. |
Hi @brian-mann - thanks for your thoughts. I agree that updating In regards to existing solutions, I haven’t come across many in the past, and certainly not any elegant ones. Most seem to involve automating dialogue box clicks with device automation tools. Selenium does allow the web driver to be configured to custom Firefox profiles with the various certificates provided but as you say this isn't possible across all browsers. These solutions are inherently flakey, you'd know more than me but personally I don’t think it would be easy to come up with a reliable cross browser solution that automated the various dialogue boxes (or configs for headless browsers) to support PKI. This would also require continued maintenance as new versions of browsers emerge, and documentation updates too. I think that for this to work reliably it would need to be done at the network level. My understanding is that SSL operates at the Session/Presentation layer of the OSI model rather than Application layer. While the browser can be configured to support PKI in it's entirety, I believe the Operating System would typically be responsible for housing and trusting Root Certificates / Certificate Authorities, and the browser would verify against these. Either way, how the browser ultimately handles the HTTPS response should remain unchanged as that’s at the Application layer. This is probably an over-simplistic viewpoint and I"m sure the separation between OSI layers in the browser isn't as clear-cut as that, but that's my understanding of how it should work. Therefore I think implementing this transparently at the network layer of Cypress makes more sense as the browser shouldn't care whether the original request was being made to a PKI domain or not providing it gets a valid HTTPS response from it's original request. If we were worried about side effects it might be sensible to implement PKI support behind an opt-in feature flag or switch (e.g. cypress run —enablePKI). If the flag is enabled then we could check the configuration for certificate/domain combinations and pass the certificates on with the request to the relevant domains transparently.
I’d imagine the most challenging part would be maintaining the standard of Cypress’s error handling and messages. Errors returned from If you think the above approach is viable, and Cypress would be happy to provide support with PR reviews and some guidance (if the docs fail me) then I would be happy to have a go at implementing this in my spare time. Alternatively, if you wanted to add PKI support to your roadmap and develop in house then I would be happy to test it out. Either way, it's definitely a feature we feel would be valuable for us at the BBC, add value to Cypress as a product, and address the original issue that was raised. Please do let me know how you'd like to proceed! :) |
Seems that our problem is also not fixed by the PR. |
Yes, it should definitely be implemented for all requests. However you can at least use fixtures for your subsequent XHR requests as a middle ground until we have a more rounded solution. |
I can see it was added to Sprint 11, but never got fixed or added to the subsequent sprint milestones. |
The scope of this issue has been expanded - so work on this has been postponed until the implementation details are decided first. See #2694 (comment) |
Realize this is closed, just wanted to drop for future reference how we did it. I'm a US government software engineer and ran into this problem today, decided to just leave Cypress as-is and implement a reverse proxy instead. Basically expose different proxy ports with different scenarios: Valid, invalid pass, revoked, tampered, etc. That way Cypress (or anything else) can just get the scenarios it needs via a port. We generate the SSL certs dynamically and inject them into the test environment. Also note, this app uses web sockets so I had to add a handler for that, it would be even simpler without. const httpProxy = require('http-proxy');
const fs = require('fs');
const http = require('http');
const morgan = require('morgan')('dev');
proxyBuilder('Valid cert', 'client-valid.p12', 'test', 25000);
proxyBuilder('Invalid cert password', 'client-valid.p12', 'bad-password', 25001);
proxyBuilder('Untrusted cert', 'client-untrusted.p12', 'test', 25002);
proxyBuilder('Revoked cert', 'client-revoked.p12', 'test', 25003);
proxyBuilder('Expired cert', 'client-expired.p12', 'test', 25004);
proxyBuilder('Tampered cert', 'client-tampered.p12', 'test', 25005);
function proxyBuilder(testTitle, certPath, certPass, targetPort) {
try {
const proxy = new httpProxy.createProxyServer({
target: {
protocol: 'https:',
host: 'localhost',
port: process.env.SERVER_PORT,
pfx: fs.readFileSync(`${__dirname}/../ssl/${certPath}`),
passphrase: certPass,
},
secure: false,
changeOrigin: true,
});
const proxyServer = http.createServer((req, res) => {
console.log(testTitle);
morgan(req, res, () => null);
proxy.web(req, res);
});
proxyServer.on('upgrade', (req, socket, head) => {
console.log(testTitle);
morgan(req, socket, () => null);
proxy.ws(req, socket, head);
});
proxyServer.listen(targetPort);
} catch (e) {
console.error(`Problem starting ${testTitle}`);
console.error(e);
}
} |
@clevrtec This issue is not closed. It is part of our roadmap, but has not had any work done on it at this time. |
In my use case, I would like to use |
We also need this feature to be able to use Cypress at all. Any Updates? Thank you! |
What are you waiting for?
…On Fri, Jan 1, 2021, 4:04 PM Danny Feliz ***@***.***> wrote:
I am still waiting for this. I need this to run my test suite in the dev
env.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2694 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AGFNCXD2VXNWBJDPJVZ2CRDSXZIGLANCNFSM4GATRAEQ>
.
|
Hi @GCHQDeveloper911, Did you get any feedback on your changes? if not could you send an example of the custom commands and certificate config entries in cypress.env.json |
Hi @CMalanaphyStatpro - Didn't really get any feedback, but I'm working on it anyway - give me a bit to sort a couple of issues! |
@GCHQDeveloper911 We would be open to a PR for this. It may help accelerate the work. We would still likely need to do some additional work on top of it. We're not sure exactly how the API would look, whether it would be those commands exactly. We would also want to have full cross browser support before an official release. Feel free to open a PR in 'draft' and let us know if you need any review. A way to get this out quickly, without the Cypress team's complete buy in, would be to create a plugin that people can use. |
Hi @jennifer-shehane Some colleagues of mine have picked this up, and I think are close to a "pr-worthy" solution. However, I'll ping them a link to this thread, to highlight the plugin suggestion. Thanks! |
@GCHQDeveloper911 Wondering about the progress your colleagues are making with this. Have a need for cert based authentication with Cypress for the project I am working on. Currently using a reverse proxy but would be interested in a different approach that doesn't require that. I'd be willing to help with the implementation. The plugin idea sounded promising. |
Hi @jonminter - I just spoke to the guys, they're just doing some work to re-baseline against 6.5.0... Hopefully get a PR in soon... Cheers |
We were hoping to use Cypress with certificates to impersonate different users at the same URL to test differing functionality/permissions. It looks like your PR introduces the ability to use the same certificate for all tests that relate to a particular URL. Am I right in thinking Cypress still won't support our requirement after your PR or is there a way to achieve what we need? Thanks |
@GCHQDeveloper911 @thirstycoda I have the same requirements and question after reading over the PR. I think this could be accomplished by adding a method to the Cypress API to set or override the configured client certificate for the request. Something like:
|
Hi @jonminter & @thirstycoda .... We completely agree with you this would be a very nice further feature. However, for now our focus was a design that did not alter the 'test-facing' APIs so that it could be added to Cypress without breaking Cypress users' existing tests - key to getting the Cypress authorities to accepting the change. The guys I've been working with that have done the hard work(!) on this have more changes coming / planned, including cert validation on start up. I'm sure they'll also look at your 'cert switching' suggestions too. But for now, the view is "keep it simple" and "get the basics approved". Hope this helps :) |
+1 @GCHQDeveloper911, per-test PKI config can be added at a later date. See #2694 (comment) for some additional discussion on API design. |
@jennifer-shehane Has this been addressed yet? If not, do you have any timeframe for it? |
I'm really happy to see progress on this feature. In common with other commenters, I am working at an organisation that uses client certificates extensively, so to date, our Cypress tests haven't been truly representative of real world usage. I want to second @thirstycoda's comment: being able to configure Cypress with a single client certificate is a big step forward, but really unlocking all client certificate based testing will require the capability to set certificates per call. In addition to the example @thirstycoda gave, it would be good to test the rainy day cases, like users presenting an expired certificate, or an invalid certificate, or no certificate, etc. It would be great if this could be given consideration soon after #15179 (I also wonder if #15179 does actually make switching between client certificates possible, by changing the file referred to in the config on the fly). |
While I agree more capability around certificates will be helpful, let's get this first increment to the finish line (released) before we worry about more. I wouldn't want to see this delayed, by starting to look at more. |
This is kind of a big deal. Trying to upgrade our tests from cypress 4.2 to 7.3.0 and hitting this. AFAIK, Cypress does not surface TLS client certificate errors. I got so frustrated by this (I didn't know what the underlying issue was... why SSO authentication no longer worked) I started a sample project using playwright. Sure enough, the first chromium test I ran popped up a dialog asking me what client certificate I'd like to use. Here's the workaround for playwright: microsoft/playwright#1799 |
@jeff-mccoy thanks for sharing that work around. Do you mind clarifying how you are using it:
I see @GCHQDeveloper911 is the hero hammering out the PR with this. Thank you for doing that. Current Use-caseJust to generally add to the requirements/expectations, here is my setup:
The testbed allows for a real mtls connection. While this could be done with just having a local nameserver override a record, that is more complex and does not have the overall assurance of a single proxy enforcing internet access. Right now the main issues with cypress integration are:
I believe that the @jeff-mccoy 's solution can actually handle this, as long as I run |
Co-authored-by: GCHQDeveloper911 <[email protected]> Co-authored-by: Jennifer Shehane <[email protected]> Co-authored-by: Zach Bloomquist <[email protected]> Co-authored-by: Zach Bloomquist <[email protected]>
The code for this is done in cypress-io/cypress#15179, but has yet to be released. |
Released in This comment thread has been locked. If you are still experiencing this issue after upgrading to |
Need a way to send a PKI from the client to the server when it is requested by the server on login (two way SSL).
On connecting to our application, the server requests a PKI / personal certificate from the client. This PKI is unique to the user; it is installed in the browser so that they can authenticate to websites with it.
The browser prompts the user to “Select a certificate to authenticate yourself”, where the user can select OK to send it.
This prompt/dialog isn’t appearing in Test Runner. Instead, our custom error message indicating that the user did not send a PKI is displayed.
I attempted to use a group policy to force all instances of Chrome to auto select a certificate, but the PKI still isn’t sent from the client to the server. The group policy does work for all other instances of Chrome that aren’t created by Cypress.
The text was updated successfully, but these errors were encountered: