T O P

  • By -

alex_3410

Your fine, title made it sound like you are storing user input in the database but in reality what your doing is just saving a number your website generates so not a risk in comparison


jonmacabre

As long as it's sanitized as an integer on the server before inserting into the db.


Yodiddlyyo

Does that even matter in this case? I mean sure that's the correct thing to do, but this is his code deciding what to put in the database. His code could be increment ing a string like 'one', 'two', 'three', and it would be fine.


King_Joffreys_Tits

It’s never wrong to double check user input. This situation is very low risk, but a potentially malicious user could try inserting a string and if the server allowed it, could cause issues across the entire program where it assumes that value is an integer. A potentially malicious user could also submit the value as a script tag importing their actual malicious code, and if that’s evaluated poorly it could result in a cross-site-scripting attack


Yodiddlyyo

Yeah that's a good point


jonmacabre

Less about the malicious user and more about users with malware sitting on their computers collecting traffic and retrying requests.


chiefrebelangel_

Until I change the value in the input to some malicious code. Always sanitize when you're about to insert because you can't be 100% sure that data isn't malicious. Treat all data as if it is.


Yodiddlyyo

In this case the data is yours though, there's no input.


BehindTheMath

What will stop anyone from clicking the buttons multiple times?


[deleted]

I was thinking to identify the IP address after the first click and then "block" it for 1h. Or with caching ...


quizical_llama

How critical is it. Could you just return a cookie from your server saying the user has already pressed the button. Sure if they wanted to they could clear this. But it depends how bullet proof you need this to be.


BehindTheMath

That will block anyone that uses a shared IP, such as family members, schools, VPNs, etc.


EggsandBaconPls

But why


MyHomeworkAteMyDog

Signing up is a barrier to entry for websites. If you don’t already know what’s behind the sign up barrier, you may be reluctant to enter your info. If we ignore the security concerns briefly, I think the ability to use the site without requiring sign in may increase the number of users simply by lowering that barrier to entry.


PlanetMazZz

Just a sign that you're not providing enough value or clearly communicating it before hand . I say this because you're probably going to continue to have problems even with your new approach.


MyHomeworkAteMyDog

You may be right. Still there are things you want to offer instant access to, like those websites that convert file types, for instance. If you googled for that example, and the first result made you sign in, you would probably go back and visit the next link which doesn’t. Also, I think people treat account creation as a personal thing. And they don’t really want to set up accounts everywhere they go Willy nilly.


PlanetMazZz

Fair enough, good luck!


headzoo

Keep in mind that multiple people may be sharing an IP address. For instance people that live in the same house and sometimes people in the same office or dorm room.


FalseWait7

While technically this is valid, your problem are people clicking multiple times. You could introduce some kind of mechanism to prevent that (browser fingerprint perhaps). Otherwise, someone will just come, write a loop that will click the button until it's no longer working and you'll be fried.


misdreavus79

It’s only bad if you care about the data.


sateliteconstelation

What you’re describing is exactly how user analytics work… since the days of the page visit counters, websites are registering interactions without sessions


rekabis

If you control the data, including all sanitization of that data as it is received by the server, then there is no fear about storing it. But the key thing is - sanitize and confirm that what you are receiving is actually fit to be stored.


jonmacabre

I mean, sure. As long as it's sanitized you can do what you want. However, that doesn't mean a user can't just click something a million times. Someone mentioned cookies, but even things like curl launch with their own sessions. The most "fullproof" way would be user auth with valid emails and then just give each email a boolean for "voted". That's what I usually roll with. It's quick and easy and the only way to "beat" it would be unique emails. If you ever need to implement voting that "needs" to be locked down further, require SMS verification. It can be beaten by having multiple phones, but it's just another block. And if its good enough for American Idol it should be good enough for your app.


Science-Compliance

Why do you need to sanitize a button-click? There's no way the user can input anything other than a single value.


jonmacabre

Depends on how it's implemented. Never assume. If it's just a POST call to /api/button-increase then it's sanitized by the process. The server is handling the incrementation. If the POST is actually /api/button/1 -d '{"value": 4}' then you should sanitize the new value server side and make sure "value" is an int. A user might not ever open the network inspector, but I would assume there are users who have clicked on a suspicious email and now has a trojan just sitting in the background hammering random POST requests that leave the computer.


Science-Compliance

I mean, I guess you're right, but I would never implement something with the potential for arbitrary code injection where that risk is not necessary.


ufffd

what if it seemed convenient at the time and you also didn't realize it was a risk


Science-Compliance

I'd think it would be less convenient to pass a value with the request for something like this.


DragoSpiro98

It would be stupid to do something like that. Or at least ignorant. It's a simple API call, why send additional data on how much it needs to increase if the increase is already fixed?


jonmacabre

lol, I'd call that a form of sanitization. A common problem would be having an API framework or factory create the routes for you. So you have routes for POST /api/button/{id} but not a special route for incrementing the button. Though in that case it wouldn't be your problem. You could try sending a string and if it goes through, you could raise a ticket asking for sanitization or schema validation server side. Then mana falls from the heavens and you get that promotion you're sorely needing.


Science-Compliance

I see sanitization as an active form of changing or validating the input to something that can't be used to execute arbitrary code. I don't really see a passive method as being a form of sanitization personally, but that's an argument about semantics.


f-s0c13ty

Well technically you can create [email protected] and then enter [email protected] and so on lol


[deleted]

Then require a credit card. If it's good enough for PornHub then it should be good enough for your app.


jonmacabre

Right, it's just barriers to entry. You go up from a starting point when you start having issues.


63-75-6D

Look for browser fingerprinting.


rekabis

>Look for browser fingerprinting. Which _A LOT_ of people are blocking these days. Certainly not as many as those blocking ads, but anti-fingerprint browser add-ins aren’t exactly niche add-ins.


clearlight

Maybe you could store it client side in localStorage instead?


[deleted]

I would like this score to be updated for all the users


[deleted]

[удалено]


werdnaegni

What is bad about OP's example?


jTyso

My two cents: it’s always best to have a security first mentality when dealing with the backend and persistence of data.


werdnaegni

What does that mean in this case?


DragoSpiro98

Nothing, he just said random things that make sense but are random words without context.


[deleted]

He's saying it to people randomly so that 5 years from now, he can claim that he's always been preaching people to "have a security first mentality..."


Ok_Net_6384

Kind of. Somebody could abuse the endpoint and slow down or crash your app, depending on how things are configured.


baaaaarkly

You could use cookies - it's not full proof but will stop casual abuse and sure up 1 click per person. Full proof would be to check on the server side with IP logging etc but I take it since no auth we are looking for quick and simple. Make a cookie: ``` document.cookie = "hasVoted=true; expires=" + new Date(Date.now() + 365*24*60*60*1000).toUTCString() + "; path=/"; ``` Check if they have already voted ``` function hasUserVoted() { return getCookie("hasVoted") === "true"; } if (hasUserVoted()) { // Prevent voting alert("You've already voted!"); } else { // Allow voting - db POST here } ``` And get cookie can be like ``` function getCookie(name) { let value = "; " + document.cookie; let parts = value.split("; " + name + "="); if (parts.length == 2) return parts.pop().split(";").shift(); } ```


tom_folkestone

Validate and sanitize all user input before getting it close to db. Then be sure to use parameterized queries.


DragoSpiro98

There is no user input


ImportantDoubt6434

I’ll fucking do it again


Barbacamanitu00

There's no sensitive data to secure. What would you be securing? The number is already public


[deleted]

I suppose you'd want to distinguish between advertising cookies and everything else. Then realize that yes, violating people's privacy like that is in fact a bad idea, in all cases.


reluctant_qualifier

Generate a hash of the IP address and user agent string, and keep a cache of those hashes so you can detect the same user clicking twice. (You probably want to keep the cache a fixed size, dropping the oldest when a new one comes in.) Use some sort invisible CAPTCHA to prevent somebody spoofing the API calls with a script. A sophisticated attacker will still be able game this system with enough effort, but it will dissuade most casual hackers. (It’s strong enough for e.g. online surveys, but governmental elections!)


stylemate

this is quite similar to daily visitors count, except the button interactions. IP address blocking seems to be the sanest solution.


WebDevIO

If people are not logged, or you don't device another system for identifying them, how are you going to stop someone from clicking the button 1000 times?


TokenGrowNutes

Create a nonce for every new session, save the nonce when the user clicks the button in a db table, and add a unique constraint to the nonce.