In an HTML5 web app, I'm building a feature that relies on client-to-client communication (with pusher). It's made of PHP on the server-side and Javascript with Vue on the client side.
The typical scenario is: a window popup is opened, and from there it communicates directly with some other windows opened into any another browser on the same computer. Let's say you have 2 browsers installed, you open the web app popup with Firefox and it communicates with its web app sister page you did open previously into Chrome.
The only (half-)way we have found so far is to use the public IP address to build a private channel named with the IP address… It's basic and efficient.
However, if there is more than 1 computer connected to the same router, all of them will share the same public IP, and that's where things become difficult!
A solution could be to add the computer's local IP to the channel name (that was already built with the public IP), but despite a few nice workarounds I found to get this info from an initiated RTC Connection, this looks quite unreliable and often goes against browsers privacy rules…
Obviously, I cannot use session information with PHP on the server-side, nor cookies / local storage on the client-side, as all those solutions are tightly coupled with the browser itself (thank God Chrome won't share its cookies with Firefox on your computer). Those solutions would be perfect (and no need for a pusher) if we were using 1 single browser, but we need to handle multiple browsers on the same machine.
That's where I'm wondering if anyone would have already dealt with this design challenge and shared some tips, it would be awesome! Thanks for reading so far!
You can check the user agent of the browser.
You can check a combination of the request headers coming from different browsers.
You can explicitly throw and catch an error in the user's browser and send it in the request header/body to determine what browser they're using.
You can do canvas drawings to see the user's GPU/CPU information (since you're already using html5 that's a bonus).
You can directly use webgl to do the same with perhaps different metrics (since canvas uses webgl anyways).
You can check their typing speed or even build up a profile of their vocabulary and use of language.
If you ask for permissions you can see all of their connected media devices like headphones, even just asking for audio permissions will show you all of them.
You can benchmark their CPU with things like the time it takes to find primes or encrypt a key.
You can use audio fingerprinting, which is almost as unique as your voice, since each browser and CPU architecture slightly differ in the digital pattern and oscillations created from audio, which can be captured.
You can check their window size and screen size and screen resolution.
There's probably even more I didn't think of now, you can also use any of them in combination to fingerprint a device.
For more information research browser sniffing and digital fingerprinting. What's more is that you can uniquely identify the user across their own browsers on the same computer and also different users from different devices using a combination of browser sniffing/digital fingerprinting.
In your specific case you can't use all the browser sniffing techniques but you can still use some of them, like the user agent since it will still give you the user device information even if they're using a different browser.
The idea with digital fingerprinting is that you want to build up a probability high enough that you can be fairly certain it's the same user, you can't ever be truly sure, but sure enough. Something like screen size doesn't mean much by itself, there's millions of devices using i.e. a size 1600 screen, however consider the following hypothetical example:
User's device has screen size of 1600, that's i.e. ~1/8 users.
User's device took 20ms to encrypt a 4096 key, that's i.e. ~1/8 users.
User's device took 40ms to draw a canvas image, that's i.e. 1/8 users.
Now you already have a 8 * 8 * 8 = 1/512 probability of knowing what user it is and that value goes up way higher very quickly, based on 3 fundamentally unidentifiable things.
However it should be noted that using any browser sniffing or digital finger printing techniques like above fall under privacy regulations (at least in some countries). A lot of things like the user agent is being deprecated and if you do things like this on a site you'll get into trouble with things like GDPR. I believe you can get around that if you explicitly ask the user for their permission and let them know that i.e. their browser is being fingerprinted. However you have to be careful because doing this can get you in trouble if it's malicious, doing things like this without a user's knowledge is unethical.
Related
I'm working on my bachelors project at University and I'm doing an app where I need a unique device ID. I'm working with javascript and the application (which is accessible when downloading the application or when entering the web page) would run on the following execution platforms:
mobile and tablets: Android, iOS, Windows Phone, Firefox OS, Tizen
Smart TV: Android, Tizen OS, Web OS
browsers: Windows, Mac, Linux
My question is: is it possible to obtain an identifier of the physical device, such as the MAC address, but that never changes (since the MAC can be changed by the user at any time) for all or, at least, for some of the execution platforms mentioned above?
If installed as an app on a mobile device or smart TV, you'll probably have a enough access to get a hold of something unique. I wouldn't necessarily go for a Mac address, but different devices will have different unique identifiers you can grab (even just a phone number would be a pretty good bet for a mobile phone).
Browsers, which are the most restricted environment you listed, are a different story.
Short answer, no.
Longer answer, no, but kinda.
There is no way to get any kind of identifier that is truly unique and unchangeable from the client. This means no MAC address, serial number, IMSI, or any of those other things.
You'd have to turn to an approach which advertisers frequently use to track you across the web.
Basically, you scoop up all the information you can access about a user. These things may include user agent string, IP address, OS, and the like. Basically, things that are sent in an HTTP request and/or via JavaScript client-side. By combining these values together, you can create something that's going to be reasonably unique fingerprint, though not guaranteed and will greatly vary by physical environment that users access it by.
For example, if I'm using my computer at home, and I'm all alone, and I have a fixed IP address, then getting my IP address alone will probably point to just me. If I'm in a college library or an office environment though, and pretty much every other computer all uses the same external IP (quite common a lot of times), and all of them are roughly the same amount of up-to-date, then a lot of people will show up all as the same user even if you mix a bunch of different data points together.
Depending on your use-case, it may be "good enough" (which is generally what advertisers go with), but if it you are using it for any kind of auto-access to security, don't do it. It's never going to be anywhere near secure enough for that. If you want to do something like that, at the very least mix it with a cookie and/or session specific values to reduce the risks.
It is not technically possible to obtain an ID unique to the device, from a browser.
However there is a way to work around this. You can use JavaScript to generate a long ID, which is statistically guaranteed to be unique, such as a GUID (a 128 bit integer). This value can then be stored in the browsers localStorage (or in a cookie), again using JavaScript.
The next time the users opens this page, you can check if a unique ID is found in the browsers localStorage. If found, you known which device this is.
You can also use other information to help indentify the device, such as the IP address, the device's screen size, and other settings which can be read through JavaScript.
Non of these solutions are guaranteed to work. For example if a browser is in private mode, the data in the localStorage will not persist.
In modern browsers you can create a function like the following to do the job. The machine ID will be unique for the browser/machine combo.
function getMachineId() {
let machineId = localStorage.getItem('MachineId');
if (!machineId) {
machineId = crypto.randomUUID();
localStorage.setItem('MachineId', machineId);
}
return machineId;
}
There is a NPM package available to resolve this https://www.npmjs.com/package/device-uuid
NOTE: This will give almost 90%-100% uuid across different browser.
You can get DeviceID in browser by below Easiest way
<script src="https://raw.githubusercontent.com/biggora/device-uuid/master/lib/device-uuid.min.js"></script>
<script>
var uuid = new DeviceUUID().get();
console.log(uuid);
</script>
output something like this:
a4883c6b-b18f-4c8e-bbdc-528b8f3xxxxx
Additional
You can get Device Browser , version, platform, OS
var du = new DeviceUUID().parse();
console.log(du);
[reference] :
https://github.com/biggora/device-uuid
I know this is not a specific question, but I just want to get design ideas about a screen sharing web site with SignalR.
We want to add a link on our website which is called "Share My Screen" and then our support team be able to see the content of the browser (not whole desktop) and even they be able to click or type on customer browser.
I was thinking to do it as
Taking screen shot from browser by js (by http://html2canvas.hertzen.com for example)
send taken screen shot to server constantly (I don't know how yet)
Server sends the received screen shot to our support team browser
Capturing mouse move and key press on support team browser
Sending this captured data to customer browser
Since each part of this needs a lot of work I just want to gather all possible ideas to find a tested solution
First of all, I do not think your idea of capturing screen is really doable with javascript technology. Security would be a huge issue, you would need to process a high amount of data, and syncing events would be a nightmare no matter how you approach it. Capturing and sharing tab content and events is a much more manageable goal.
If you are aiming to use this for people who can not manage to install a remote control app, then we can count newer technologies such as WebRTC out due to browser compatibility issues.
There is a good blog post discussing this issue here - (Screensharing a browser tab in HTML5?).
I especially like the first method, using Mutation Observer (browser support) and Web Sockets (browser support). It basically syncs two html documents through the use of mutation observer and uses web sockets for communication. You could use SignalR instead of standard web socket API for communication if you prefer.
We currently have a web browser application that runs only under Internet explorer that we are trying to make cross browser. The main reason for using IE is that we can access the hardware information from an ActiveX control. We would like to get away from this methodology for obvious reasons.
If we forget about the way things are currently being done and go back to the security requirements and look for other ways to accomplish the same thing. The user of the application must be on a known computer that must be in a secure location. I am at a loss on how to do this.
We currently use Protect/unprotect to encrypt the data we need and guarantee that the file can only be decrypted on the same machine. This keeps the user from finding the file and copying it to another machine and running. The file is put on the computer by a separate installation process that can only be run by authorized personnel.
So how do I get a machine specific key of some type that allows me to identify the computer with no chance of being replicated to another computer?
====================================
We are trying to do exactly what the web is trying to keep us from doing, so this may not be doable without specific browser extensions, such as a ActiveXControl.
The USB response is interesting but it does not guarantee location. We do use USB devices for terminals that require 2 factor authentication.
The other possibility is a user or machine certificate installed in the computer. The problem I see with that is the certificate can be exported. We had tried this years ago and the operational overhead was too high.
I am building a Time clock application for my employer to use with his employees. One of the requirements is to have it take a photo from a webcam every time a user clocks in and out of the system.
Thankfully this is possible using HTML5 and JavaScript and no longer requires Flash or Silverlight.
The problem however, is in this image below....
Since this application will be used on 1 PC and accessed by a large number of users everyday, this is a real problem for my application.
I hope there is a way to permanently authorize permission to use the camera for certain pages maybe or another alternative?
If your app is running from SSL (https://), this permission will be
persistent. That is, users won't have to grant/deny access every time.
http://www.html5rocks.com/en/tutorials/getusermedia/intro/#toc-security
Note, this only applies in Chrome. Each browser may implement the security prompts differently.
If you open http://app.ft.com (the Financial Times mobile web app), you are prompted to add the app to your "home".
After doing this, when you open the app, you are prompted again to allow the localstoreage database size to be increased up to 50MB.
How can this be done? Is there some JavaScript API call? Permissions or whatever?
Is this iPad (iOS?) specific, or does it work on other Webkit browsers?
I happen to know something about this ;)
There's no API for requesting an increase in storage size for an existing database. There is one way to force an increase: write data to the database in such a size that an increase is required, prompting the user. However, this would be slow and there's no way to tell the currently allocated space, so it's not recommended.
Black Frog has part of this correct: the only neat way to do this is to request a very large database when it is opened, for example:
openDatabase('databaseName', '1.0', 'My Database', 50*1024*1024, …
… to request 50MB of space.
However, when the user first visits the site, you may not want to prompt them about a 50MB limit at once; so you might think that you could ask for 5MB at first, and then later re-open it with 50MB? Unfortunately, this doesn't work - the second open attempt, with an increased quantity, succeeds silently, not prompting for a size increase and not actually increasing the available size.
The FT app therefore starts off with a 5MB "preview" database, so that the user isn't prompted on first load. It tries not to exceed this 5MB limit, as any space assigned has to be shared across all databases.
If the user chooses to allow storage of more content, the app then tries to open a database with a different name with 40MB of space (for which the user is prompted to approve 50MB). This allows 40MB in that database, and 5MB in the original preview database, so neither should fail when inserting rows - as 50MB total is currently the limit on iOS.
All browsers currently handle database space limits differently, so if you're planning cross-platform, test carefully. Desktop Safari handles it rather nicely, allowing much larger; Chrome doesn't allow any increase at all; etc. Expect all "HTML5" implementations to differ in strange ways :)
This database is part of Web SQL Database API, which is not part of HTML5. Use the following the set the size of your database
function prepareDatabase(ready, error) {
return openDatabase('documents', '1.0', 'Offline document storage', 50*1024*1024, function (db) {
db.changeVersion('', '1.0', function (t) {
t.executeSql('CREATE TABLE docids (id, name)');
}, error);
});
}
Introducing Web SQL Databases on HTML5 Doctor has a very quick tutorial on how all of this works.
I just tested with my offline app in iPad 2( iOS 5.1.1) that we do not need to do anything specific inside the app. For e.g., my app has about 18 MB of offline data. When the browser hit URL, browser popped up the message requesting increase in size to 25 MB and I accepted it and all is fine. Thanks
It's browser specific. Most have set it to 5MB and some give the option of increasing it through a setting somewhere. Not all browsers offer this though.
Huh — Dive into HTML5 says that no browser supported this as of February 2011, so I guess this might be an iOS 4.3 thing? (iOS 4.3 shipped in March 2011.)
I can’t find any references to it from a quick Google. Apple’s own developer documentation might mention it — I’m not sure if that’s available to non-SDK subscribers though.