I have programmed a webserver meant to run on the user's localhost that gets jsonp requests from a remote https page. This architecture stems from the fact that applets are about to stop being supported by every browser and I need some sort of interface in between a smartcard and the browser.
I am planning to create a root certificate and the corresponding ssl certificate, and to start serving my jsonp endpoints using https.
In order to do so, I'd like my application to allow importing the root ssl certificate to the computer so that the browser does not complain when performing https requests to localhost.
(TL:DR) Is it possible to programatically install a root ssl certificate using java? Using which libraries?
I have just discovered that I shouldn't need to have any certificates installed. Taking in account the current w3c draft on my problem it seems that http://127.0.0.1* domains should not be considered mixed content in an otherwise safe webpage. Here is a link to the commit that added this to the draft, where one can read on its comment:
Based on the discussion in the public-webappsec thread starting at
3, our face-to-face at 4, and our recent call at 1, this patch
aligns mixed content's checks with Secure Context's definition of
potentially trustworthy URLs.
Among other things, this means that http://127.0.0.1/ will not be
considered mixed content when loaded in an otherwise secure page.
I have reported this issue for Chrome...
Related
I'm trying to use Java and Selenium to test a website that requires a client certificate.
When I browse to my site I get a popup like the one below to select the correct certificate.
My requirements are as follows:
Select a certificate by name
On different versions of Windows / IE / Edge
Ideally the popup is never shown; i.e., the solution would involve invoking some API or setting some configuration to pin the correct certificate to use.
My own solution ideas:
I tried a solution based on visually detecting the correct certificate using SikuliX (which does works) but I'm wondering if there is a better solution that does not rely on visually detecting the popup. Something that is less likely to fail across multiple versions of Windows and that is future proof if Microsoft decides to change the appearance of this popup.
Another idea that I had (but I don't know how/if it is possible) is to remove all installed certificates except for one so that the popup is never shown:
Backup the entire store
Remove all client certificates that IE could use (except the one I need)
Do the login which would no longer require any certificate selection
Restore the backed up store
Does anyone know how to do this (in Java, possibly invoking CLI commands)?
Is it possible to start (using Selenium Java) an Internet Explorer Window that only knows the single certificate that I need?
Is it possible in Internet Explorer to set a default certificate for a given domain?
The solution we use is quite clean, easy and portable between browsers and operating systems - use proxy server that will handle SSL handshake for you.
You can set up an in-memory Man-In-The-Middle proxy server in the same JVM the tests is running, or even multiple instances on different ports, each assigned to different client certificate. Then, when creating WebDriver instance, use setProxy method suitable for your browser. Note, the browser will be presented with server certificate that is installed on the proxy itself, not the target server, so there might be some invalid certificate errors that should be suppressed in WebDriver settings. Alternatively - the proxy may simply use valid server certificate, if its key is available to you, in which case the connection is fully transparent for the test script.
One simple proxy server that offers what is required in Java is LittleProxy. Perhaps something like BrowserMob offers a more complete solution with readily available API.
An example using LittleProxy just needs a few (dozen) lines of boilerplate:
Step 1:
Extend org.littleshoot.proxy.MitmManager class with something you can plugin into your code, making use of client certificates (e.g. p12 files or PEM files). Working example available publicly at this repo.
Step 2:
Start proxy server using client certificate and server certificate of your choice:
org.littleshoot.proxy.impl.DefaultHttpProxyServer.DefaultHttpProxyServer.bootstrap()
.withIdleConnectionTimeout(FIVE_MINUTES)
.withName(clientCertFile.getName())
.withPort(port)
.withAllowLocalOnly(localConnectionOnly)
.withManInTheMiddle(new MutualAuthenticationCapableMitmManager(
usingPKCS12File(clientCertFile, clientCertPassword),
usingPemKeyPair(serverKeyPair[0], serverKeyPair[1])))
.start();
Create another proxy for each client certificate you need reusing the same port or by startnig concurrent instances.
Step 3:
Start WebDriver using the proxy. Major browsers (IE, Firefox, Chrome) support the setting in similar fashion:
org.openqa.selenium.Proxy proxy = new Proxy();
proxy.setSslProxy("127.0.0.1:5555");
proxy.setNoProxy("<-loopback>"); // overwrite the default no-proxy for localhost, 127.0.0.1
FirefoxOptions options = new FirefoxOptions();
options.setProxy(proxy);
WebDriver driver = new FirefoxDriver(options);
Step 4:
When running tests, the browser will never bother you with any certificate prompts. Profit.
If using this technique, please be extra carefull to keep the secrets secure and especially the proxy server itself unreachable to third parties. Exposing keys is never good idea outside of secure corporate network, regardless if they are real (!!!) or fake.
I can't say for sure, but I wouldn't be surprised if this was impossible with selenium.
This question doesn't fill me with hope:
Selenium can't deal with Confirm Certificate popup in IE
The further you get away from the webpage and towards native browser and then OS controls, the more impotent Selenium becomes.
As the only answer to the linked question states: you can disable the popup in the browser, which may or may not be a workable solution.
If you don't want to go down that route, people most often fall back to a Java Robot to handle things that the selenium driver can't do e.g. interact with the print dialogs and other such controls.
See mouseMove, mousePress, mouseRelease
You'd call each of these, providing the button position to mouseMove.
https://docs.oracle.com/javase/7/docs/api/java/awt/Robot.html
We have recently needed to change our SSL certificate on our server. Our consuming application has suddenly stopped working. I had presumed this was to do with Java's cacerts, and modified the program to import the new certificate to each client, the problem was not resolved.
When the application attempts to load the remote view (shown below) on the server, it simply loads a white page. I have tried loading the page through http:// and it seems to function, however the rest of the application (including the API) requires https, and subsequent calls to the API fail (images loaded through https are showing as broken within the app).
The website is functional, and when I access URL's being provided to the app, through my desktop browser they load without issue. The app is also functional when I run it in Debug mode, these issues only occur when I use the "Run" build mode.
I have tried creating a blank MAF application, hoping it was some caching issue, however this new app also cannot load the remote URI. I have done a clean build and have tested other remote URI's (they work). I feel as if there is an issue with Java somehow not accepting the new certificate. The first time I tried to load the website within Eclipse's browser, an error displayed along the lines of "certificate revocation information". I didn't pay much attention to this error and it provided the option to install the new certificate, after which the page loaded within eclipse's browser.
In Jdeveloper there is an option of Disabling the Application Transport Security as shown in the image.
Could you try disabling in your eclipse too, Kindly refer this doc https://wiki.eclipse.org/Jetty/Howto/Configure_SSL, this might do a little help :)
The issue seems to be due to the changed SSL certificate on your server.
Short answer:
There was no chain installed, I installed the provided ca-bundle file and updated the httpd.conf file to reflect the chain location and the app now works.
Long answer:
When our server dev installed the new certificate, he neglected to install the ca-bundle (certificate chain) provided by the CA. The site was working in a browser, I can only assume, because it has a more complete list of trusted CA's built in. My best guess is that MAF requires the chain to be installed and was failing some security test, or the chrome webview it uses did not have this CA on the trusted list.
I have java web application which is running on several tomcats behind apache. Application use HTTPS protocol. Some pages from the app include images from sites which use only HTTP protocol. On pages with this images the client's web browser shows message (warning) that despite service is certified correctly some contents are not secure.
What should I do to avoid this message? Should I use some proxy for this images? Can I do something in java code?
Thanks in advance.
You can't do anything nor should you.
The browser is correct in warning the user even though there are no bad intentions here.
Using a proxy could be useful if you're really worried. In that case, the unencrypted connection is between your server and the hosts of the images instead of between the hosts and the user's browser.
Nothing you can do in java.
You need to register your certificate at some official certification authority, you can do that through the registration authorities.
A registration authority (RA) is an authority in a network that
verifies user requests for a digital certificate and tells the
certificate authority (CA) to issue it.
Google it. Of course you'll pay for that.
Also, you can avoid that browser message if manually add your certificate into Trusted Certificate on client machine.
Say, I have a Java web app inside a war file that is hosted on cloudfoundry at the url mycoolapp.cfapps.io, which works perfectly. I now need to host it on a custom domain mycoolapp.com and I have purchased the domain.
What is process to host it on my own domain? Can I do it via Cloudfoundry?
My app needs ssl. Currently https://mycoolapp.cfapps.io works. But I need it to work on my custom domain. What will be involved in this? (I think I need to get a certificate for my domain, but what next?)
In the app some confidential information is embedded in urls (this cannot be changed), so I'd also need to ensure that the provider cannot know the urls accessed (apart from the base url). Can this be done? If not, what are the alternatives?
It could be done by creating a CNAME record for your app (see Azure example here). Unfortunately, it seems that Cloud Foudry (CF) does not support it yet. As I understand, it is caused by the fact that CF router determines the exact Virtual Machine (and, hence, IP) by parsing URL and determining the route according to the host name (mycoolapp in your case). Ideally there would be an interface in CF where you could register all CNAME aliases for your app (as implemented for Azure websites)
If CNAME record would be enabled, that it would also work for HTTPS, as it basically resolves IP address. And definitely there would be an interface for you to upload a certificate for your domain. This leads to problems mentioned below about SSL termination. But, again, as far as I know, it is not supported by CF yet.
That it a question to the internal structure of run.pivotal.io deployment of CF. Conceptually HTTPS will do the trick as it encrypts URL parameters. However I suppose that SSL terminates on the router (as certificate is issued for *.cfapps.io - single cert for all apps - you could check it in browser connection to your app by HTTPS). That likely means that internally CF has access to ALL data of your request, and leads to my question about SSL termination in CF, which currently has no answer. Hope CF will provide a way to terminate SSL on the final server processing the request.
UPDATE:
Cloud Foundry has proposed its own way to support custom domains - through using CloudFlare proxy. If the fact of using proxy that decrypts your data is Ok for you, it could be used.
I would like to know if there is an easy (or hard) way to spy the secure sockets from a java applet ? (without having the source code)
The goal here is to know exactly what for informations send an (very good obfuscated) applet.
I thought i can simply compile myself a modified java version with a log function but the full source code from java is not available for security reasons...
Set up a proxy server with a security certificate that the applet accepts. Afterwards, you just have to configure your browser to use that proxy and the applet should use the same config.
See Does https prevent man in the middle attacks by proxy server? for how it works technically.
Some things you will need: A proxy than can act as a web server and which is probably reachable with the name of the real server from your browser. You will need to create a valid certificate for this combination which isn't trivial unless the applet is configured to accept certificates from untrusted sources (no CA authority will issue a certificate for, say, "google.com" so that you can feed that to your proxy).
Googling for "man in the middle attack ssl proxy" turns up many links that should be useful.
This article seems to describe an out-of-the-box solution: Understanding Man-In-The-Middle Attacks - Part 4: SSL Hijacking
It doesn't mention applets but Fiddler might fit the bill (from Capturing HTTPS traffic in the clear?)
Just set -Djavax.net.debug=all in the JVM properties. You will get all kinds of output from different layers of the network stack, including the pre-encrypted SSL traffic.
If you're talking about SSL, it wouldn't be secure if that was possible, and it is secure, so it isn't.