Unique DeviceID on Javascript Web Application(Angular, React, ...) - javascript

I have a specific need which is giving me some hard time. The basic requirement is: We need to Uniquely Identify the Device(can be a PC, Mac, Tablet, Phone) via one ID, just like an IMEI... This is needed due to some Licensing restrictions of some applications.
The challenge: We are running a Angular and the browser makes it nearly impossible to uniquely identify the device. As we are on the Browser sandbox, I have no chance to get something like a Mac address or anything that would be a good start in defining a unique ID.
What we tried so far:
MediaDeviceInfo.deviceId: https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo/deviceId
In one hand, on the first tests I made on my Chrome, it came empty and additionally it is not supported on Safari...
ValveĀ“s FingerprintJS2: https://valve.github.io/fingerprintjs2/
At a first sight we think we hit the Jackpot as it properly generated the same ID, even if I called it from an Anonymous window! But, It still generates another ID for a different browser...
Basically It works by enumerating all browser capabilities(at least the ones accessible) and then by creating a hash of that... The Issue: If you have devices with exactly same configurations, they will have the same ID! I tried that on 2 iPhones that have the same config and were even bought on same day! :-)
Creating UID and saving on Localstorage: create a UID (How to generate UUID in angular 6) and store it on Local Storage. Some issues on our way:
If I open an Anonymous window, of course that the LocalStorage would be not there, meaning that I would get a new "UUID"
Besides that, we have some individual angular applications and they would need to share the local storage, which is not possible to do due to the SameOrigin security Limitation. We could overcome it using an iFrame and the PostMessage (https://levelup.gitconnected.com/share-localstorage-sessionstorage-between-different-domains-eb07581e9384). There are actuyll some NPM packages doing that as this one: https://github.com/ofirdagan/cross-domain-local-storage. Being honest, we do not like much the idea of create a "cross-domain-local-storage"...
I am aware that this problem has no easy solution, but I wanted to ask here if Someone faced a situation like this and how did they solve it. Of course if I would be able to run out of the browser sandbox having direct Access to device Information such as MAC address, IMEI or anything like that, it would be easy, but as mentioned, the browser sandbox is restrictive...
Ideas?
Thanks in advance!!!
Pedro

I'm going to refer you to an answer I wrote back in 2018 which is still pretty much the same now: how can I get a unique device ID in javascript?
The short answer is: you can't, really.
You won't be able to get anything that uniquely identifies a device across all browsers and incognito vs regular. As you've found, you can get close, but it isn't a sure thing.
The best you can do is combine a couple of techniques together (like the fingerprint + stored UID) and it'll probably get 99% of cases, but you won't be able to get them all for sure.

Related

Programmatically update firefox profiles

Windows 7 / Firefox Latest versions / Preferrably 64bit beta versions
Whenever a Firefox Profile is updated, the user is presented with a dialog to check for updates to the addons. I would like to interact with tha dialog programmatically so that it is automatically ok-ed.
So far my research has brought me to:
https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIWindowMediator
For that I need a windowtype to enumerate. The window type correspons to the attribute in the XUL definitions. On my installation of Firefox, these seem to be compressed inside "c:\Program Files\Mozilla Firefox\browser\omni.ja\chrome\browser\content\browser".
I have limited experience of the firefox API. I'm executing code through userchrome.js.
Any pointer would be gladly received.
UPDATE 1 20151125 0748: I believe this is the xul - https://archive.is/NyGBS - any pointer on how to "overlay" it within userchrome.js? I can also try to enumerate windows of windowtype="Addons:Compatibility".
UPDATE 2 20151125 0748: It looks like the extensions update dialog is not showed if I have:
user_pref("xpinstall.signatures.required", false);
Which marks the addon as unsafe but allows you to continue using it.
[Which solves my immediate problem, but I am sure I will have this requirement at another point for another dialog, so would still like to get to the bottom of this]
TL;DR version with info about the problem follows.
I currently have a vbs script that:
Deletes FIREFOX_RUNNING_PROFILE folder.
Copies FIREFOX_BASE_PROFILE folder-> FIREFOX_RUNNING_PROFILE folder.
Runs FIREFOX_RUNNING_PROFILE.
Whenever a firefox update takes place, a number of dialogs need to be confirmed by the user in relation to checking/updating extensions.
The outcome of this process will not stick to the profile as obviously given my setup the RUNNING_PROFILE is recreated every time.
Note that for the purposes of this discussion it doesn't matter whether the udpate is performed automatically. I have the ability to rewrite the prefs.js so i can change behaviour dynamically just by doing that and restarting the browser externally - it's vbs right now but I'm ready to move over to something else if I hit some limitations with process / window management, or I want this to be portable (e.g. python). Note these are not dealbreakers right now and I'd be happy for a reasaonbly sleek windows-only solution.
I have a few of this BASE_PROFILES, hence I would like to handle the updates programmatically.
I have not found a way of achieving this that does not involve interacting with the dialogs firefox presents in the GUI. And I have noticed that the dialogs popping up after each update can change.
Options:
1) userchrome.js -> I already use this to manage some imacros autostart features, including grabbing the profile name from Components.Interfaces. I am reporting snippets below to help the reader understand what is the most sophisticated snippet I've written against the Mozilla xpcom components:
var strProfileFilePath=Components.classes["#mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile).path;
I have had a look at the documentation and it looks rather impressive. It feels like it will let me do pretty much everything, so my next move here would be to undersrtand how to enumerate dialogs and somehow select the right one based on some properties, then push the "ok" button. I think that's pretty much all I need to do.
2) Autohotkey. I can try and send keys to the firefox window (not sure about the exact dialog inside the window). The dialogs normally have shortcuts that would respond to those to this keysends (nice theory). In autohotkey I can also "position-click", although it is less desirable for obvious reasons.
3) One of the avenues through Autohotkey involves using the MozRepl Firefox addon behind the scenes. Library discussed here https://archive.is/73u4f, github seems out of date https://github.com/arbiter34/FF-Control. I could then use mozrepl directly, no need for Autohotkey. I would rather code in python, java, or even javascript, powershell, vbs than autohotkey. Ar a first look it looks like it would give me the same power that userchrome.js currently offers.
4) Selenium. There are some profile manipulation capabilities I could exploit - although Selenium was not really designed to interact with Firefox own's dialogs, and I don't see an API to automate that. Rather one would synthesise a profile on the fly, installing on top all the required extensions from a known superprofile (that would contain a superset of all the extensions to be used), and applying whatever mods to prefs.js also dynamically. This sounds a bit ugly for my original requirements but experience has told me that ugly is still better than manual.
5) There is also the option of writing an addon, but again, I think I'ld be interacting with the same interfaces that I can get in userchrome.js (actually I believe userchrome.js is even better as it seems to have unfettered access to the core components, which is exactly what I sense I might need for my case). I would rather avoid having to write an addon, although I might be lost for words trying to explain why exactly.
I appreciate I have not "fully" investigated further, but I am at a point now where I need to elicit the opinion of the community before I start spending substantial time on either of these.
The below isn't strictly required to address the question above, but I feel it might be useful to share this as there must be a few others undergoing the same predicament:
Additional Points:
a. As a general principle, I have zero desire to update anything (firefox.exe, addons, language packs, plugins and what not) (plugins are actually completely disabled). I am ok with the way the system works, and I don't want to change it one millimitre. Yes, NOTHING, not even the security updates. This is because of the particular circumstances of my app, my particular estimation of the particular risks I'm taking, and my general aversion to risk. YMMV. NEVERTHELESS I'm still forced to upgrade whenever (1) I "make a mistake" (all it takes is for one profile to have the update settings wrong for the exe to be updated for all the profiles on the machine - doh! there's only one exe); (2) Firefox is crashing too much / unusable (happened twice); (3) I need functionality offered by the upgrade (hasn't happened); I would also like to reserve the option for the "very critical security updates" (sigh! sometimes even I can bow).
b. The arcane art of keeping your firefox profile integer across updates also involves search engines - it doesn't matter if I say I don't want to update them, whenever there's a firefox.exe update I will get the new standard fluff installed in the program folder. I currently have a way of resetting that by (1) emptying the firefox program subfolder containing the xml files (in %programfiles%\Mozilla...), and (2) deleting search-metadata.json and the searchplugins folder (in the profile folder), then copying them over from a baseline afresh. It all feels very greasy. I have yet to try this on the 64bit version I'm running right now as this is a minor issue and I would rather not introduce more entropy. The firefox search engines mechanism might have changed in the meantime.

How to detect whether a HTML file is opened in browser or some Application Software?

I need to do some changes in my HTML file based on whether it is opened in browser or Some Desktop Application.
Till now I've tried this in my script:
alert(navigator.appName);
alert(navigator.appCodeName);
alert(navigator.platform);
But the values are coming same whether the HTML file is opened in browser or some application Software.
How can i set a variable which toggle its value from 0 to 1 when opened in application Software and vice versa.
PS: Application Software like Matlab, MS Office , Britanica Encyclopedia etc.
Short answer, you can't.
Longer answer, to some extent. What you need to do is make a list of differences in each desktop apps implementation, based on known flaws, missing/existing properties, user agent flavours and so on (some of this called "browser spoofing"), to be able to sort them out. It will still be possible to trick this if one want to though.
Normally there is another way of dealing with the differences, the question is what is the different behaviour you want between the 2?
As a sample, and if you still need/insists to detect this, there is device detection libraries which can help as a start, like https://51degrees.com/device-detection
I still recommend to find another way to solve it.
UPDATE
As it is easy to create a desktop app and return the values needed for your page to believe it is a normal browser, I think the best solution is to ask the user on first page hit if they are on a normal browser or not (the one who is not will normally know) and then store in a cookie/set a flag and act upon what the user selected.
I mean it is easy to cheat your page either way so better trust on user selection.
You can use 2 step verification for such cases as devices are getting quite varied. First you can detect devices by media queries strings using innerWidth property. And then you can apply second filter matched by protocol it supports.
Secondly, this SO question might help Frame Buster Buster ... buster code needed

How to get PC hardware IDs using any way using browser (e.e. javascript)

I searched but couldn't find answer.
I want to get Hardware IDs from PC using browser only to generate a unique code.
So even when user use virtual PC. I can detect them via Hardware because they can not change their hardware's identity.
Applications can easily do it but is there any possible way to do same with flash application, java/javascript or browswer add one etc?
Thanks
I believe the only way is to write a browser plugin - if you require a hardware id from the user then it reasonable to be explicit about this with the user and require them to install the plugin first.
For javascript, you can't access the MAC address of the machine, which is probably the closest thing to a "hardware id".
Java and Flash are being deprecated in the browser too, so while I'm sure an option exists there, many users won't be able to use them very soon.
I think a good solution would be to have a server assign a unique ID to a user, which is then stored as in a cookie on the user's machine.

Why CasperJS and browsers show different behaviors with CAPTCHA? [duplicate]

Is there any way to consistently detect PhantomJS/CasperJS? I've been dealing with a spat of malicious spambots built with it and have been able to mostly block them based on certain behaviours, but I'm curious if there's a rock-solid way to know if CasperJS is in use, as dealing with constant adaptations gets slightly annoying.
I don't believe in using Captchas. They are a negative user experience and ReCaptcha has never worked to block spam on my MediaWiki installations. As our site has no user registrations (anonymous discussion board), we'd need to have a Captcha entry for every post. We get several thousand legitimate posts a day and a Captcha would see that number divebomb.
I very much share your take on CAPTCHA. I'll list what I have been able to detect so far, for my own detection script, with similar goals. It's only partial, as they are many more headless browsers.
Fairly safe to use exposed window properties to detect/assume those particular headless browser:
window._phantom (or window.callPhantom) //phantomjs
window.__phantomas //PhantomJS-based web perf metrics + monitoring tool
window.Buffer //nodejs
window.emit //couchjs
window.spawn //rhino
The above is gathered from jslint doc and testing with phantom js.
Browser automation drivers (used by BrowserStack or other web capture services for snapshot):
window.webdriver //selenium
window.domAutomation (or window.domAutomationController) //chromium based automation driver
The properties are not always exposed and I am looking into other more robust ways to detect such bots, which I'll probably release as full blown script when done. But that mainly answers your question.
Here is another fairly sound method to detect JS capable headless browsers more broadly:
if (window.outerWidth === 0 && window.outerHeight === 0){ //headless browser }
This should work well because the properties are 0 by default even if a virtual viewport size is set by headless browsers, and by default it can't report a size of a browser window that doesn't exist. In particular, Phantom JS doesn't support outerWith or outerHeight.
ADDENDUM: There is however a Chrome/Blink bug with outer/innerDimensions. Chromium does not report those dimensions when a page loads in a hidden tab, such as when restored from previous session. Safari doesn't seem to have that issue..
Update: Turns out iOS Safari 8+ has a bug with outerWidth & outerHeight at 0, and a Sailfish webview can too. So while it's a signal, it can't be used alone without being mindful of these bugs. Hence, warning: Please don't use this raw snippet unless you really know what you are doing.
PS: If you know of other headless browser properties not listed here, please share in comments.
There is no rock-solid way: PhantomJS, and Selenium, are just software being used to control browser software, instead of a user controlling it.
With PhantomJS 1.x, in particular, I believe there is some JavaScript you can use to crash the browser that exploits a bug in the version of WebKit being used (it is equivalent to Chrome 13, so very few genuine users should be affected). (I remember this being mentioned on the Phantom mailing list a few months back, but I don't know if the exact JS to use was described.) More generally you could use a combination of user-agent matching up with feature detection. E.g. if a browser claims to be "Chrome 23" but does not have a feature that Chrome 23 has (and that Chrome 13 did not have), then get suspicious.
As a user, I hate CAPTCHAs too. But they are quite effective in that they increase the cost for the spammer: he has to write more software or hire humans to read them. (That is why I think easy CAPTCHAs are good enough: the ones that annoy users are those where you have no idea what it says and have to keep pressing reload to get something you recognize.)
One approach (which I believe Google uses) is to show the CAPTCHA conditionally. E.g. users who are logged-in never get shown it. Users who have already done one post this session are not shown it again. Users from IP addresses in a whitelist (which could be built from previous legitimate posts) are not shown them. Or conversely just show them to users from a blacklist of IP ranges.
I know none of those approaches are perfect, sorry.
You could detect phantom on the client-side by checking window.callPhantom property. The minimal script is on the client side is:
var isPhantom = !!window.callPhantom;
Here is a gist with proof of concept that this works.
A spammer could try to delete this property with page.evaluate and then it depends on who is faster. After you tried the detection you do a reload with the post form and a CAPTCHA or not depending on your detection result.
The problem is that you incur a redirect that might annoy your users. This will be necessary with every detection technique on the client. Which can be subverted and changed with onResourceRequested.
Generally, I don't think that this is possible, because you can only detect on the client and send the result to the server. Adding the CAPTCHA combined with the detection step with only one page load does not really add anything as it could be removed just as easily with phantomjs/casperjs. Defense based on user agent also doesn't make sense since it can be easily changed in phantomjs/casperjs.

IE8 ADO warning when opening a record set with JavaScript

I have a few HTML pages that use javascript to run sql queries etc. these html files are accessed from a share drive on the network. this works perfectly in IE6. My workplace is updating to IE8 and I now get the following warning:
"This Web site uses a data provider that may be unsafe. If you trust the Web site, click OK, otherwise click Cancel."
This is very annoying as every sql interaction results in this warning.
I have spent a lot of time researching and the solution seems to be that I need to add the site to my trusted sites list. However, I am unable to do so due to group policy disabling access to IE settings, and my IT department says that they will not alter the trusted sites list.
Are there any other options? If I could somehow get a trusted certificate would that help? I have also researched other ways to try and run sql without javascript and without a web server but I didnt have much luck.
you're getting the cross-domain alert because your accessing data on a different server. you can put them on the same server and that should fix your problem.'
regardless, and i mean this with all sincerity, you need to get up with your it department and have a little heart-to-heart; they're going to be wary of you and most likely dissmissive...do not let them dissuade you. be polite but be just as stubborn. and if you really want to be a dick about it, when they're up on their high horse telling you nay, you should question their expertise...particularly with user-agents. if they're converting from ie6 in 2012....there's no situation they can describe that makes that acceptable. i'm assuming your intranet was built specifically for ie6 and that'll be their main excuse.....dude ie7 came out in 2007. their excuse is five years old. furthermore....it's still weak sauce.
you and all of your coworkers can enjoy chrome if you add chrome frame to your installation. look it up. wow your it department.
lastly....you're a developer that is not allowed to choose browser, and the browser they grant you access to isn't even fully functional? a)Quit b)Quit c)Quit
Albert already talked you through it (and how right he is). Otherwise a solution could be to put a pass through server (somewhere in your network) between the client and database, e.g. using node.js with an odbc library like node-tds or tedious.

Categories

Resources