Get data from the user's device - javascript

I need to get the serial number or some information that doesn't change from the user's device, I thought about getting IPV4 but depending on where the user is it can change and all the logic I tried to implement didn't work, I'm doing it in an MVC project .net 6.0 and this logic I'm trying to implement in C# but it would be possible in JavaScript I would also use this information to automate the user's login, using a security device already pre-registered by him

Disclaimer: I work at Fingerprint.
I would also use this information to automate the user's login, using
a security device already pre-registered by him
It might be a good idea to use a browser identifier (fingerprint/visitorId) as a decision point for further choices (e.g. whether to challenge a user with another factor or put some additional barriers). It's not a good idea to use a fingerprint/visitorId as a password replacement. There might be falsy results and this technology is not intended to replace passwords.
Moreover, I'd like to correct some misconceptions from the question and comments.
but from what I saw in the documentation to implement it, you need to
register an SSL address
Open source FingerprintJS is a pure client-side library. There are no HTTP APIs, servers, or requests. You don't perform any Subdomain setup whatsoever.
The Subdomain setup and SSL certificates are related to the Fingerprint Pro, it's a different service (take a look at Pro vs open source comparison). The Subdomain setup improves accuracy among other benefits. You can try the service on localhost without it. Moreover, with the Subdomain setup, you can develop your app on localhost without any limitations as well.
It will generate a hash unique to the browsing device
This is not correct, they are not unique at 100% cases. The accuracy of the open source FingerprintJS is ~60%. The accuracy of Fingerprint Pro is ~99.5%. Nevertheless, there might be some false positives/negatives. This is the main reason why it's not a good idea to use fingerprint/visitorId as a password replacement.

Related

Opening an instance of Microsoft Word from Javascript

I am building an application that will allow user to open a word document through a web page. This web application will open the word document using the local word instance on the machine.
I have two working solutions.
Using ActiveX (Only on IE)
Since the application is intranet application, I am using PsTools in the web service to remotely open word instance on remote machines.
The second architecture is what I am following right now. It is based on a Web Service which receives machines name through Javascript/jquery call. Later in the web method I am using PsTools to remotely execute MS Word instance on remote machine.
Both the architecture works, but both of them have limitations. With ActiveX I can use it on IE and it also requires changes in network policy to allow ActiveX. With PsTools, it is working great but I can't get the path of Word.Exe and I can only assume that it would always be at \\machinename\C$\Program Files(x86)\.....
We might make this application public as well and in that case our solution with PsTools will not work anymore.
I was just wondering if there is any other more suitable/cross browser way to open local word instance through web application ?
The document has to be modified on a remote location, one option would be to let the user download the document, then modify it and upload it to the server, this is out of question since we are replacing a thick client and wants to keep the user experience same
I am building an application that will allow user to open a word
document through a web page.
If it is an Intranet scenario, then you could use application protocol with Office URI schemes for links to the documents which will then open in the locally installed client.
The Office URI schema is like this:
<scheme-name>:<command-name>"|"<command-argument-descriptor> "|"<command-argument>
For Word specifically, an example would be:
<a href='ms-word:ofe|u|https://example.com/example.docx'>Edit</a>
Where, ms-word: is the scheme, ofe command stands for open-for-edit, the u is the command-descriptor to use the URI that follows, and finally the URI to the document itself. There are other commands like ofv (open-for-view), and nft (new-from-template), and also other command-descriptors like s for save.
Here is the complete reference: https://msdn.microsoft.com/en-us/library/office/dn906146.aspx
The protocols are registered with Windows when the Office client is installed.
You could enable WebDAV easily on your IIS server. The WebDAV client is built-in with Windows at the client-side.
You can also use components like FFWinPlugin Plug-in which is part of the SharePoint Foundation, or OpenDocuments Control which is an ActiveX control installed along with the Office client.
We might make this application public as well
I would discourage you from doing that, unless your company owns or deals-with services like OneDrive or Office.com. This can quickly get tricky as mentioned in the other answer. Moreover, enforcing a proprietary client on general public is not a good idea anyway. Further, even Microsoft's own solutions do not work reliably across browsers and work best with IE only (even Edge has problems with this), which would be forcing a specific browser to general public. Not a good idea.
However, if you really need to, then it would be better if you could use some of the solutions already built around WebDAV. Alfresco ECM (enterprise content management) is one example of public offering which uses WebDAV similar to your use-case.
There is another one by IT Hit and a live demo is here: http://www.ajaxbrowser.com. They also have a basic tutorial on how to setup your own WebDAV server on the same lines as your use-case. You will need to find their documentation.
When you say: "We might make this application public as well", what kind of scale are you talking about? Just a couple of folks from the a team, or as a real web application that needs to deal with edit conflicts, transactions, locking, performance, etc.? Even the intranet solution you mentioned will likely become a headache as soon as 2-3 people start to edit the same document.
For this type of document sharing, you basically have two options:
Significant investment in a rich web UI that behaves similarly to MS Word, with back-end services that will store the info in a scalable data store and provide simultaneous edits and document downloads, or
Integrating with a third party vendor API or white-label provider that offers similar capabilities for a fee. E.g. Box.com APIs, HyperOffice, FirePad, etc.
This would be a super-simple problem to solve if you can convert the document in question to a type of form. There are probably a hundred different services that offer embedded forms functionality with excellent reporting and database management. If a document in Word format is needed, then your app would just convert the stored data to a .doc/.docx document for users to download at will.
Whatever direction you go with, try to get out of the PsTools-based current setup. It's like a rinkydink house of cards and as #Matt-Burland mentions, likely to cause a security disaster pretty soon.

In a browser environment, is it possible to obtain list of SSL certificates in JavaScript?

In order to connect to a third party application, I have to give my users the capability to select one of their installed SSL client certificates and transfer it to the third party which is used by the application server. (My web application does not require SSL, it is the third party that require SSL certificates).
It seems to me that access to this list of certificates is only possible by the browser itself when connecting to a service that require SSL. Is it possible to launch the same dialog box through Javascript or is there any way for a web application to browse the SSL store of the end-user ?
If it is not possible, can I simply open a file dialog box and upload the client certificate as any standard file ?
I have to support any browser from IE9 and no plug-ins are allowed in our application.
Thanks.
If it is not possible, can I simply open a file dialog box and upload the client certificate as any standard file ?
Firstly, that's not the way SSL/TLS client authentication works at all. It's simply not a matter of uploading the certificate. The private key matching the certificate is used to sign some content (in the CertificateVerify TLS message) during the TLS handshake. That's what performs the authentication.
Coming back to your main question, for security reasons, the SSL/TLS stack is handled outside the scope of the JavaScript code. Selecting the client certificate is part of that.
You could potentially have some sort of API to let the JavaScript code access some of the cryptographic features of the browser (and there has been work in this area). However, there would be security considerations to take into account.
Even if certificates only contain public information to some extent, that doesn't mean it's public information that is to be distributed to anyone in the world, at least not necessarily in conjunction with the act of browsing any website.
If you had the ability to list the user's list of certificate from the JavaScript code sent by your server, you'd certainly have the ability to send that list back to yourself almost transparently with an Ajax call. While some people are concerned about the privacy implications of being tracked by cookies, being tracked by which client certs you may have takes this to another level (e.g. Subject DN with CN=John Smith and Issuer DN with CN=Department/Ministry of Health/Defence: that would be a bit of a giveaway).
My web application does not require SSL, it is the third party that require SSL certificates.
Here, you're not saying whether that third party is accessed directly by the user's browsers, or if you expect the users to delegate their credentials for you to interact with that third party (without direct user involvement).
If the users have direct access to that third party (via another request), their browser should prompt them for the certificate they with to use.
If it's about credential delegations, that's another problem entirely, since users you never give you the private key for their own client certificate to be able to sign in their name. (It's might be technically possible for users to just give you their PKCS#12 file, for example, but it defeats the point of putting up in place this sort of authentication in the first place).
There has been work done about authentication delegation with certificates using proxy certificates (RFC 3820). Essentially, your EEC (End-Entity Certificate) is used as a mini-CA, despite not having the CA flags, to issue a short-lived certificate with the remote party will accept. This sort of mechanism is generally not well integrated in browsers.
Another, more realistic approach, would be to look into the world of SSO, SAML and Shibboleth, for example. That does work with existing browsers, but the overall architecture is a bit different (so you'll need to discuss that with the third party).
The certificate isn't part of the DOM, so no, this won't be possible.
In a browser environment, is it possible to obtain list of SSL certificates in JavaScript?
The WebCrypto API allows you to discover some things, like shared and derived keys. But looking at their charter and use cases, its not clear to me if they allow enumeration and discovery of certificates.
I see it was discussed in the past and an issue was raised. Here's the discussion: Crypto-ISSUE-15: Discovering certificates associated with (private) keys. But I can't find anything on Issue 15 in the WebCrypto Tracker.
Also see Will the WebCrypto API allow discovery/enumeration of certificates? question on the WebCrypto Mailing list. Hopefully there will be a simple, YES/NO answer.
But don't be surprised if its not available through WebCrypto. The browser security engineers have a particular way of looking at things, and that usually does not include client certificates. Client certificates would effectively stop MitM attacks (see, for example, Origin Bound Certificates), and browsers don't make stopping MitM a priority. Instead, they are OK with mishandling credentials like passwords; and they opt for a One Time Password (OTP) using U2F.
In a reality stranger than fiction, the browsers will even (1) use Public Key Pinning for HTTP, and then (2) break a known good pinset because the user was phished! You can't make this stuff up...

Detect if user is accessing my network (WIFI) using NodeJS

My question is a NodeJS newbie question. I would like to somehow detect if a user is accessing my network (Wifi) and I would like to indicate the users presence in my network.
How would I go about identifying the user presence. I'm completely clueless as I was unable to find any library that could help me detect this in Node. Is this even possible? If so could you point me to the appropriate libraries and the approach that I need to use.
If you run a router like a Linksys, etc. that can support DD-WRT, you can flash that firmware and then use either SNMP or web page scraping to get connected clients. There are node.js libraries for SNMP and there are a ton of examples of web page scraping with Node.JS.
Alternatively, you could get really complicated and add in RADIUS authentication to your DD-WRT installation and watch for an authentication event.
Another option, you could send ICMP (Ping) packets to every potential address that your router would acknowledge. e.g. if it's 192.168.1.1 on a 255.255.255.0 subnet, you would have 253 addresses to ping. Of course, the connecting user's machine would have to have ICMP responses turned on (which they typically do by default).
I hope one of these suggestions helps.

JavaScript Code Signing

How can a user, using one of the major modern browsers, know for sure that he is running my unmodified javascript code even over an untrusted network?
Here is some more info about my situation:
I have a web application that deals with private information.
The login process is an implementation of a password-authenticated key agreement in JavaScript. Basically during login, a shared secret key is established between the client and the server. Once the user logs in all communication with the server is encrypted using the shared key. The system must be safe against ACTIVE man-in-the-middle attacks.
Assuming that my implementation is correct and the user is smart enough not to fall victim to a phishing attack there remains just one large hole in the system: an attacker can tamper with my application as it is being downloaded and inject code that steals the password. Basically the entire system relies on the fact that the user can trust the code running on his machine.
I want something similar to signed applets but I would prefer a pure javascript solution, if possible.
Maybe I am misunderstanding your problem, but my first thought is to use SSL. It is designed to ensure that you're talking to the server you think you are, and that no one has modified the content midstream. You do not even have to trust the network in this case, because of the nature of SSL.
The good thing about this approach is that you can fairly easily drop it into your existing web application. In most cases, you can basically configure your HTTP server to use SSL, and change your http:// requests to https://.
This is an old, open question but the answers seemed to not do this justice.
https:// provides integrity, not true identification nor non-repudiation.
I direct you to http://www.matasano.com/articles/javascript-cryptography/
Don't do crypto in JS, because a malicious injected script can easily grab passwords or alter the library. SJCL is neat, but it offer a blatantly false sense of security (their quote, and quoted by above)
Unfortunately, this is not as great as in desktop applications
because it is not feasible to completely protect against code
injection, malicious servers and side-channel attacks.
The long-term issue is that JavaScript lacks:
Uniformly working const
The ability to make objects deeply const and not reprototypable.
Code-signing
// codesign: cert:(hex fingerprint) signature:(hex MAC)
Certs would be managed similar to CA certs. MAC would be used with appropriate sign/verify constructions.
Crypto, clipboard stuff are reasons to have JavaScript native plugins (signed, of course)
Getting JavaScript engines to all implement a standard is another thing, but it's doable an it's absolutely necessary to end a large swath of malware.
You could have an external Javascript file which takes an MD5 hash of your login JS, and sends an Ajax request to the server to verify that it is correct and up-to-date. Use basic security or encryption practices here - public/private keys or some other method to be sure that the response came from your server.
You can then confidently display to the user that the client-side scripts are verified, and allow the login script to proceed.

Self-signed certs -- helping users know they need to add root CA to trusted cert store

I have a desktop product which uses an embedded webserver which will use self-signed certs.
Is there something that I can put in a web page that would detect that they haven't added the root CA to their trusted list, and display a link or DIV or something directing them how to do it?
I'm thinking maybe a DIV that has instructions on install the CA, and a Javascript that runs some test (tries to access something without internal warnings??), and hides the DIV if the test succeeds. Or something like that...
Any ideas from the brilliant SO community ? :)
Why do you want to do this? It is a bad idea to train users to indiscriminately install root CA certificates just because a web site tells them to. You are undermining the entire chain of trust. A security conscious user would ignore your advice to install the certificate, and might conclude that you are not taking security seriously since you did not bother to acquire a certificate from an existing CA.
Do you really need HTTPS? If so, you should probably bite the bullet and make a deal with a CA to facilitate providing your customers with proper CA signed server certificates. If the web server is only used for local connections from the desktop app, you should either add the self-signed certificate to the trusted list as part of the installation process, or switch to HTTP instead.
Assuming you know C# and you want to install a pfx file.Create a exe that will be run from a url.Follow this URL
and this
The only idea I have is to use frames and some javascript.
The first element of the frame will act as a watchdog waiting x amount of time (javascript setTimeout) before showing your custom ssl failure message to the user with hyperlinks or instructions to download the self-signed cert.
The second frame element attempts the https connection and if successful resets the watchdog frame so that it never fires. If it fails (assume https cert validation failed) the watchdog message would then fire and be presented to the user.
Depending on your browser you will most likely still see some security warning with the approach but you would at least be able to push your own content without requiring users to run untrusted code with no proper trust chain (This would be much much worse from a security POV than accepting the cert validation errors and establishing an untrusted ssl session)
Improvements to the concept may be possible using other testing methods such as XMLHttpRequest et al.
You should not do this. Root certificates are not something you just install, since adding one could compromise any security given to you by https.
However if you are making a desktop app then just only listen to 127.0.0.1. That way the traffic never leaves the users computer and no attacker can listen in.
You might try to add some (hidden) Flex element or Java Applet once per user session.
It will just download any https page of your server and will get all information about connection:
com.sun.deploy.security.CertificateHostnameVerifier.verify()
or
javax.security.cert.X509Certificate.checkValidity()
I suppose Flex (which is more common to users) shoul have similar ways of validating https certificate from user's point of view. It should also share OS' trusted cert. store while Java might have its own.
Since the server is running on the client machine (desktop product) can it not check the supported browsers for installed certs using winapi/os functions? I know Firefox has a cert database in the user's profile directory and IE probably keeps information in the registry. It wouldn't be reliable for all browsers but if the server simply chooses between "Certificate Found" and "Please ensure you have installed the cert before continuing" then no harm is done as the user can choose to continue either way.
You could also simplify matters by providing an embedded browser as well (ie, gecko), this way you only have 1 browser to deal with which simplifies a lot of things (including pre-installing the root CA).
To recap: you are setting up webservers on desktop apps; each desktop will have its own webserver, but you want to use SSL to secure the connection to that webserver.
I guess there are several problems here with certificates, one being that the hostname used to access the desktop has to match the certificate. In this case you have little choice but to generate certificates on the client. You'll need to allow the user some way to specify the host name in case the name used by outsiders can't be detected from the host itself.
I'd also suggest allowing for an admin to install a trusted cert, for those who don't want to rely on self-signed certs. This way you can also offload the cost of trusted cert maintenance to the admins who really want it.
Finally, in my experience browsers either allow or refuse the self-signed cert and there is no way for the server to know if the cert is denied, or temporarily accepted, or permanently accepted. I assume there must be a mechanism somewhere to handle SSL failures but typical web programming doesn't operate at that layer. In any case, the only thing a webserver can do if SSL fails is to fallback to non-SSL, and you've indicated in a comment that you can't have anything non-SSL. I think you should try to have that restriction lifted; a non-SSL start page would be extremely helpful in this situation: it can test (using frames or images or JSON or AJAX) the https connection, and it can link to documentation about how to set up the certificate, or where to download an installer for the cert.
If the browser won't connect because of a self-signed cert, and you're not allowed to use plain HTTP at all, by what other means could you communicate with the user? There are no other channels and you can't establish one because you don't have any communication.
You mentioned in a comment writing a win32 app for installing the cert. You could install a cert at the time you install the application itself, but that doesn't help any remote browsers, and a local browser doesn't need SSL to access localhost.
We've been working on an opensource JavaScript project, called Forge, that's related to this problem. Do you have a website that your users could access? If so, then you could provide a secure connection to those desktop apps via your website using a combination of Flash for cross-domain + JavaScript for TLS. It will require you to implement some web services on your website to handle signing certificates the desktop app certificates (or having your desktop apps upload the self-signed certs so they can be accessed via JavaScript). We describe how it works here:
http://blog.digitalbazaar.com/2010/07/20/javascript-tls-1/
An alternative to setting up a website, but is less secure because it allows for a MiTM attack is to host the JavaScript+Flash directly on the desktop app server. You could have your users hit your desktop app over regular http to download the JS+Flash+SSL cert, but then start using TLS afterwards via the JS. If you're on a localhost connection the MiTM attack might be a little less worrisome -- perhaps enough for you to consider this option.
An ActiveX control could do the trick. But I really didn't chime in to help with the solution, more to disagree with the stance that what you are doing is a security risk.
To be clear, you are needing a secure cipher (hopefully AES and not DES), and are already in control of your endpoints, just not able to completely rule out promiscuous-mode network sniffers that could catch clear-text passwords or other sensitive data.
SSL is a "Secure Socket Layer", and by definition, is NOT dependent upon ANY certificates.
However, all effective modern ciphers require it to authenticate the tunnel endpoints, which is not always a necessity for every application; a frustration I have dealt with in numerous back-end datacenter automation routines using web service APIs to manage nodes, where the "users" were actually processes that needed encrypted key exchange prior to a RESTful command negotiation.
In my case, the VLANs were secured via ACLs, so I really "could" send clear-text authentication headers. But just typing that made me throw up in my mouth a little bit.
I'm sure I'll get flamed for typing this, but I'm extremely battle-hardened and would've made the same comments to you in years 10-15 of my IT career. So I empathize with their worries, and very much appreciate if they are passionate enough about security to flame me. They'll figure it out eventually.....
But I do agree with the fact that it is a BAD idea to "train" users to install root CA's on their own. On the other hand, if you use a self-signed cert, you have to train them to install that. And if a user doesn't know how to determine if a CA Cert is trustworthy, they definitely won't be able to determine a self-signed cert from a CA Cert, and thus either process would have the same effect.
If it were me, I would automate the process instead of having it assist the end-users, so that it becomes as hidden from them as possible, just like a proper PKI would do for an enterprise.
Speaking of which, I just thought of a potential solution. Use the Microsoft PKI Model. With Server 2012 R2, you can deliver trusted keys to endpoints that are not even domain members using "device control" via "workspaces", and the client machines can subscribe to multiple workspaces, so they are not committed solely to yours if they subscribe. Once they do, and authenticate, the AD Certificate Services Role will push all root CA Certs necessary, as are present in active directory, or specified LDAP server. (In case you are using offline CA servers)
Also, I realize this thread is like 7 years old, but am sure it still gets referenced by a good number of people needing similar solutions, and felt obligated to share a contrasting opinion. (Ok Microsoft, where's my kickback for the plug I gave you?)
-cashman

Categories