Identifying users without cookies etc - node.js

I want to write a new aggregator site where users can submit news and up and down vote on them (Pretty basic stuff, similar to a tiny reddit).
My problem is this:
Someone can only up or downvote a news article once a day
I don't want users so sign up
Cookies for voting could be deleted
How do i identify a user over the course of the day and how do i make sure that this user didn't vote on some article some minutes before.
Is this even possible?

You could use the browser fingerprint.
The browser fingerprint is an identifier generated from the information that every browser sends on every connection (HTTP headers) and additional information available through basic JavaScript.
Information like:
User agent
Language
Installed plugins
Screen resolution
... and more.
A browser fingerprint identification isn't bulletproof because there are self-defense tactics but it can spice up your recipe. Despite its controversy, it's widely used.
Mozilla has a great wiki article about the subject.
And you can check your own browser fingerprint at https://panopticlick.eff.org/

Short answer: No, it is not possible to reliably identify a user without login and without using cookies or a similar technique.
I hate to post this, but the evercookie project is a good collection of the techniques for making something like a cookie that is somewhat more persistent than your standard cookie. It uses some neat tricks, but one could also argue that it has some privacy issues. I would not recommend you to implement it. Even if you did (or borrow some of their ideas), then
Any remotely tech-savvy user would still be able to clear the cookie.
You can't guard against users using multiple devices and browsers.
You can't (reliably) guard against users not posting via a browser, thus circumventing cookies and other tricks.
Etc, etc.

Related

Is there a way to get a client's browser and os name such that client cannot modify it?

So i have to get a client's browser and os name. But the thing is that we don't want the user to be able to manipulate information about os or browser. But some websites show that there is only one way to do it that is by using request header userAgent.
Below are the links I've been through:
Retrieving Browser, OS and Device Type By Parsing User Agent
How to prevent user-agent to be changed by user
How do I prevent websites from detecting my OS? Which browser should I use?
so according to these we can only do it with the help of userAgent And it is not a difficult thing for a client to change it and also there is no way that we can detect that if a client has modified it. And it turns out that even mnc's like amazon and facebook rely on userAgent.
So on learning about Device fingerprint i got to know about a javascript library called FingerprintJs and it seems that they don't rely on userAgent for finding out the clients os name as i tried using it and turns out that on manipulating userAgent i got the original result. I am still trying to figure out how they exactly work for getting the os and browser name. And even if client can manipulate this too is there still a way that we can atleast make it difficult for a client to fake about browser and os ?
You are not able to restrict values that are sent with a request to your server. A user will always be able to use e.g. curl to send some arbitrary headers, cookies, etc. You can make it more difficult to tamper with the values through some obscurity, but that is not making such a solution secure.
Device fingerprinting might help, but you will most probably get blocked by ad blockers as they target fingerprinting as well. Still, even if you do implement device fingerprinting and get more accurate data about the user's browser, the user still can tamper with requests and change that data.
I don't know what are your requirements, but normally, you shouldn't be that much concerned with the user's browser or OS.
As there's no guaranteed way of knowing the user's OS/browser (since the user is able to send anything with their request), the more important question to ask may be:
Why do you want to know the user's OS/browser?
This can help us find a better answer for your actual requirements.
For example, this might help: https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent#considerations_before_using_browser_detection
One method I can think of, is through a custom browser extension/plugin. You may even be able to use a browser API, depending on the target browser.
You would then craft a payload, which would compute/calculate the "client signature" out-of-band, not within the browsers standard request cycles and compute a signed, self validating hash, stored as a cookie.
This would require some knowledge of the related layers involved.
You are essentially talking about device fingerprinting.
While there are a vast number of approaches, you may not really want to maintain the overhead required, as it is generally done using multiple approaches, many of which are accomplished by exploiting bugs in browsers, http protocals, network routing analysis and even the clever targeting of numerous OS bugs and or quirks.
A much simpler approach is to feed your user a hashed cookie, with a scheme to detect if it's been modified. That cookie, along with other authentication and verification mechanisms would be far simpler and may be enough for your purposes.
There are 3rd party APIs which provide such a service, if it's really mission critical.
Of course philosophically speaking, if weather or not should you be fingerprinting your users? Is really up to you and the expectations of your users.
But there you go, I hope that provides a broader view of what's involved.

Playback using saved session cookies

I did a small sample test and found that almost all web sites I tested suffer from the vulnerability where I can access restricted pages (ie pages that require logging in) even after I have logged out from the browser if I save the cookies while I am still logged on.
The test was fairly simple. I just replayed a web request in Fiddler after I had logged out from the browser. For example, with outlook.com, after logging out, I could replay the page that shows the address book and still get my contacts' email addresses.
May I know what the industry standard is regarding this as I have one customer who insists on fixing this vulnerability but not wanting to increase the hardware specs.
I'm not sure if there's an industry standard, but there are best practices. And the best practice is to clean the cookies, and cookie management.
You shouldn't have to worry about hardware on this either. It's a simple lookup to see if a value is valid. If it isn't, then the session state shouldn't get resurrected.
Again, I would use HttpOnly and a secure flag on the cookie. That way, it will limit replay attacks more. And when it comes to resurrecting sessions, make sure that session files are destroyed on the server, not just abandoned.
Abandoned sessions mean they can potentially be resurrected.
Hardware will generally not be an issue with this problem. If it is, then look at your solution, as there might be a better way.

How to make a proper and simple authentification for nodejs website?

I am learning to make a website with nodejsn, express, socket.io and mongodb. I am pretty much self-taught but when it comes to authentification, I can't find a tutorial that explains how it works in simple terms.
I have a login form, a signup form, the user data is stored into the database on registering. When I login, the page greets me with my username, but when I refresh or close the tab and come back, I have to login again.
All I want is that make users able to come back without having to log in systematically.
All I can find are explanations like : http://mherman.org/blog/2015/01/31/local-authentication-with-passport-and-express-4
And I don't really get it.
Can someone explain what am I missing here ?
Session management is something that Jekrb highlighted and is also a great question when it comes to highlighting users if it be anonymous or users of your application.
Though before I go into any depth I am going to highlight that cookies have a slight problem if your application is going to work on a larger scale where you have this scenario: "What happens if you have N servers where N > 1 ?" so to some degree if your unsure of your user-base, cookies may not be the correct approach.
I'm going to presume that you don't have this issue so providing cookies as a means of identifying users is appropriate, but isn't the only method available.
This article outlines a few ways in which the industry tackles this:
https://www.kompyte.com/5-ways-to-identify-your-users-without-using-cookies/
My favorite method here would be canvas fingerprinting using https://github.com/Valve/fingerprintjs2 Which will create a hash that you can store and use to verify new connections, Probably with something like socket.io which you've listed as using. A major upside of this is scalability as we can store these unique hashes centrally inside of the database without the fear of always being stuck with one server.
Finally I haven't posed any code which I dislike but the topic is hard to pin down to specifics, though I have hopefully offered some alternatives to just cookies.

Voting system hack proof

I'm implementing a voting system like Stackoverflow's. How can I implement this so it is hack proof?
I've got some PHP that does database work according to the ajax request sent after the javascript parses it. Would doing a query to check the current vote state of a user be enough to avoid unauthorised votes?
It is definitely possible to implement pretty reliable solution. But this must be done server-side.
Basic rule of security: you don't trust client data.
Move all your checks to PHP and make your javascript as dumb as
$(".vote").click(function(e) {
$.post('/vote.php', vote_data, function(result) {
// update UI according to returned result
}
}
It's a common thing, however, to still do checks on the client, but as a way to improve usability (mark required form fields that weren't filled) or reduce server load (by not sending obviously incomplete data). These client checks are for user's comfort, not for your security.
Answering to your updated question:
If you store full log of when which user voted for which question, then yes, it's pretty easy to prevent multiple voting (when user can vote for the same thing several times). Assuming, of course, that anonymous votes are not allowed.
But if you have a popular site, this log can get pretty big and be a problem. Some systems try to get away by disabling voting on old articles (and removing corresponding log entries).
What if someone intentionally tries to hack me?
There are different types of attacks a malicious user can perform.
CSRF (cross-site request forgery)
The article lists some methods for preventing the attack. Modern Ruby on Rails has built-in protection, enabled by default. Don't know how it is in PHP world.
Clickjacking
This attack tricks users into clicking on something what isn't what they think. For example, they may click "Play video", but the site will intercept this click and post on user's wall instead.
There are some articles on the Web as well.
Wiki on clickjacking
5 ways to prevent clickjacking
Javascript to prevent clickjacking
NOTE: THIS IS AN ANSWER TO THE ORIGINAL QUESTIONDon't downvote it just because the OP radically changed his question.
It's a huge error even just thinking of relying on browser-side components to enforce application logic. Javascript should be used, in untrusted environments, exclusively for presentation purposes.
All application logic should be implemented, validated and enforced server-side.

Is this CSRF Countermeasure Effective?

Please let me know if the following approach to protecting against CSRF is effective.
Generate token and save on server
Send token to client via cookie
Javascript on client reads cookie and adds token to form before POSTing
Server compares token in form to saved token.
Can anyone see any vulnerabilities with sending the token via a cookie and reading it with JavaScript instead of putting it in the HTML?
The synchroniser token pattern relies on comparing random data known on the client with that posted in the form. Whilst you'd normally get the latter from a hidden form populated with the token at page render time, I can't see any obvious attack vectors by using JavaScript to populate it. The attacking site would need to be able to read the cookie to reconstruct the post request which it obviously can't do due to cross-domain cookie limitations.
You might find OWASP Top 10 for .NET developers part 5: Cross-Site Request Forgery (CSRF) useful (lot's of general CSRF info), particularly the section on cross-origin resource sharing.
If a persons traffic is being monitored the hacker will likely get the token also. But it sounds like a great plan. I would try to add a honeypot. Try to disguise the token as something else so It's not obvious. If it's triggered, send the bad user into the honeypot so they don't know they've been had.
My philosophy with security is simple and best illustrated with a story.
Two men are walking through the woods. They see a bear, freak out and start running. As the bear catches up to them and gaining one of them tells the other, "we'll never outrun this bear". the other guy responses, "I don't have to outrun the bear, I only have to outrun you!"
Anything you can add to your site to make it more secure the better off you'll be. Use a framework, validate all inputs (including all those in any public method) and you should be ok.
If your storing sensitive data I would setup a second sql server with no internet access. Have your back-end server constantly access your front-end server, pull and replace the sensitive data with bogus data. If your front-end server needs that sensitive data, which is likely, use a special method that uses a different database user (that has access) to pull it from the back-end server. Someone would have to completely own your machine to figure this out... and it would still take enough time that you should be able to pull the plug. Most likely, they'll pull all your data before realizing it's bogus... ha ha.
I wish I had a good solution on how to protect your customers better to avoid CSRF. But what you have looks like a pretty good deterrent.
This question over on Security Stack Exchange has some useful discussion on the subject.
I especially like #AviD's answer:
Don't.
-
Most common frameworks have this protection already built in (ASP.NET, Struts, Ruby I think), or there are existing libraries that have already been vetted. (e.g. OWASP's CSRFGuard).

Resources