Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Within a web browser, is it possible for JavaScript to obtain information about the HTTPS Certificate being used for the current page?

Is there a method for JavaScript running in a browser to determine which CA certificate is being used to authenticate the remote host for the browser's current HTTPS connection, and also obtain properties of that certificate, such as the name of the CA?

If not, are there any other options for programatically obtaining this information, such as ActiveX, Java, CGI on the server side, ...?

like image 498
sutch Avatar asked Mar 08 '10 14:03

sutch


People also ask

How does web browser verify certificate?

The web server sends a copy of the SSL certificate to the browser. The browser checks the authenticity of the certificate and sends a message to the webserver. In return, the webserver/website sends a digitally signed acceptance for initiating an SSL encrypted session.

Can anyone get a HTTPS certificate?

To use HTTPS with your domain name, you need a SSL or TLS certificate installed on your website. Your web host (Web Hosting Provider) may offer HTTPS security or you can request a SSL/TLS certificate from Certificate Authorities and install it yourself. SSL/TLS certificates may need to be renewed periodically.


5 Answers

You can use the opensource Forge project to do this. It implements SSL/TLS in JavaScript. You can make an ajax call to the server and use a callback to inspect the certificate. Keep in mind that the server is the one sending the JavaScript so this shouldn't be used to determine whether or not you trust the server the JavaScript is from. The Forge project does allow cross-domain requests, so if you are using this for trust, you can load the Forge JavaScript from a server you already trust and then contact the server you don't yet trust. However, unless that other server provides a cross-domain policy, you will not be able to perform the cross-domain request.

https://github.com/digitalbazaar/forge/blob/master/README.md

The blog links in the README provide more information on how Forge can be used and how it works.

like image 68
dlongley Avatar answered Sep 26 '22 20:09

dlongley


Copying my own answer from Is there any way to access certificate information from a Chrome Extension

2018 answer: yes, in Firefox 62

You'll need to make a WebExtension, which is also called a browser extension.

See accessing security information on MDN

You can also check out the docs for:

  • getSecurityInfo
  • SecurityInfo
  • CertificateInfo.

You'll need Firefox 62.

Here's a working background.js

var log = console.log.bind(console)

log(`\n\nTLS browser extension loaded`)

// https://developer.chrome.com/extensions/match_patterns
var ALL_SITES = { urls: ['<all_urls>'] }

// Mozilla doesn't use tlsInfo in extraInfoSpec 
var extraInfoSpec = ['blocking']; 

// https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest/onHeadersReceived
browser.webRequest.onHeadersReceived.addListener(async function(details){
    log(`\n\nGot a request for ${details.url} with ID ${details.requestId}`)

    // Yeah this is a String, even though the content is a Number
    var requestId = details.requestId

    var securityInfo = await browser.webRequest.getSecurityInfo(requestId, {
        certificateChain: true,
        rawDER: false
    });

    log(`securityInfo: ${JSON.stringify(securityInfo, null, 2)}`)

}, ALL_SITES, extraInfoSpec) 

log('Added listener')

manifest.json:

{
    "manifest_version": 2,
    "name": "Test extension",
    "version": "1.0",
    "description": "Test extension.",
    "icons": {
        "48": "icons/border-48.png"
    },
    "background": {
        "scripts": ["background.js"]
    },
    "permissions": [
        "webRequest",
        "webRequestBlocking",
        "<all_urls>"
    ]
}

enter image description here

It also may be implemented in Chromium once this code is merged.

like image 34
mikemaccana Avatar answered Sep 26 '22 20:09

mikemaccana


JavaScript running in the web browser does not have access to the certificate information. The certificate information is also not passed through HTTP to the application. My research indicates that there is no way for the web application to determine if a man-in-the-middle attack has injected a bogus certificate somewhere between the host and client.

like image 42
sutch Avatar answered Sep 23 '22 20:09

sutch


No. You could obviously do it with AJAX/ActiveX/Java/Flash/Silverlight and a custom server-side script, but I can't see why you would need this.


EDIT: The idea above is that you would make a network request (using one of the above technologies) to the server and ask what certificate was used for that network request. The server could then inspect its own configuration and answer the question.

If the browser is somehow trusting an invalid certificate and connecting to the wrong server (e.g. a MITM server), the server could lie. Once the browser's trust mechanism is compromised, I don't know how to avoid that.

As far as I know, there is no way (purely using client side APIs) to directly ask the browser what cert it's using "for the browser's current SSL connection". Even Forge doesn't do that. It creates an entirely parallel SSL session, but it doesn't let you ask about the browser's native SSL session.

like image 22
Matthew Flaschen Avatar answered Sep 23 '22 20:09

Matthew Flaschen


AFAIK not with Javascript alone. But some webservers allow you to access the connection parameters of the thread or process. A serverside script can then send those values along with the request and you use it.

I found this for nginx webserver: http://wiki.nginx.org/NginxHttpSslModule (Look at the bottom of the page for the variables). It should be possible to set them as environment variables and pass them to your FastCGI processes or whatever you use.

AOLServer/Naviserver allows similar access with the nsssl module.

like image 34
initall Avatar answered Sep 23 '22 20:09

initall