I am completly new to jquery and client side programing. I am trying to figure out a way of achiving this:
On the client side I have a hidden user id/profile id, which I wanna to encrypt, but while manipulating the hidden value, I have to decrypt and perform some operation on it.
I have a global array of arrays like below:
var users=[{"u_id":"1234", "u_name":"Test"},{"u_id":"12345", "u_name":"Test1"}];
this array is used by various other compoenets, e.g. when user mouse-over on the profile-id, it will get the details from the above array and display the result to him.
In short, I want to encrypt/decrypt all my global variables inside the script.
any plugin or ways to do will be highly appricated.
Encryption/decryption on the client side is entirely pointless. Encryption is used to hide something from somebody. For that you need a secret (password etc.) that you're not giving to that somebody.
If you want to encrypt and decrypt something on the client, the client will need the secret in order to do the encryption. Therefore, the client has everything it needs to decrypt any encrypted secret. That means any user has everything he needs to decrypt data and can in fact see the process happening (try breakpoints in your browser's Javascript debugger). Therefore, the entire exercise is by definition pointless. It may deter some very unskilled poker-arounder, but anyone with the skill to actually do something with the decrypted data can get it easily.
#deceze: Yes exactly, the example you have posted, lets say user 42, trying to update his age, basicaly user will see 42 as his profile id when he logsin, and then subsequent call he will make for changes he need to pass sessionkey/apikey along with profile id and data, so basically if you will suggest me how I can manage these sessionkey/apikey, so that user/hacker from outside can't missuse.. – Jayaram Pradhan 1 min ago
It's pretty simple:
Require users to be logged in via a regular login mechanism, typically involving a session id. This session identifies the user as securely as it's feasible to do anything securely over the web. Your security focus must be here.
Knowing who the user is, you can validate any and all of his actions. If the user requests to change the profile information of some user, check whether he's allowed to do that or not. No API key or anything needed. The server receives a request for change, the server knows who the requesting user is by the session, the server can decide to accept or reject the request.
In the concrete case of updating one's own profile, if the user is only allowed to update his profile and his profile alone: there needs to be only one action/URL, when a user POSTs data to that action, the server knows who the user is and updates that user's profile. The user doesn't need to submit a user id of the profile he wants to update, in fact he can't submit a user id, only his profile will ever get updated. There's no publicly accessible action that allows him to update anyone else's profile.
There is no 3.
i know no way to perform this on client side, you can serialize and obfuscate the data (like using base 64 encoding on json string).
Related
So in my case, after a user chooses a certain room, the number of nights he will stay and the number of guests, the price gets calculated (depending on certain factors) and then they are redirected to the payment page where they will see the total price, which the user can change by manipulating the price parameter in the url.
on the booking page :
<Link to={"/book?pricetotal="+total_prices+"&title="+title+"&img="+img+"&price="+price+"&checkin="+checkkin+"&checkout="+checkkout+"&idr="+idroom} >
and on the paiment page i am using
const windowUrl = window.location.search;
const params = new URLSearchParams(windowUrl);
and then i get the parameter using
params.get('price')
The solution i found is to encrypt the content of the Url parameter and then decrypt it.
Is the solution effective enough or are there other ways to implement it?
Anything on the client can potentially be intercepted and manipulated by someone interested enough. Encryption likely isn't enough if you're really worried about security because the user could examine the code that generates the link and perhaps reverse-engineer it.
You can't trust anything done on the client. Instead, when the user makes their choices:
after a user chooses a certain room, the number of nights he will stay and the number of guests
Save this data server-side, and give the user a session ID if they don't already have one. Then when it comes time for them to check out, you can calculate the total server-side, and then show it to the user somehow. Yeah, don't put it in URL parameters, because that's too easy for someone to mess up, even unintentionally - but putting it, for example, in response to a fetch request, or in a data element on the page would work.
When the user enters their payment info and submits it, use their session ID to determine what the price for what they chose was. Using this approach, even if someone decides to mess with the client-side script to display something else, it won't affect the final price - they'll only be messing up their view (and if they do that, any confusion that results is on them).
That isn't going to work, since you are encrypting and decrypting on the frontend.
A viable solution would be to send the products instead of the price of the products. Then, when you send the request to the backend for payment, also send the products, and in the backend calculate how much to charge the user.
My solution was to pass props in link react-router
<Link to={{pathname:`/book`,state: { total_prices,title,img,price,checkkin,checkkout,idroom },}} >
and access them in my other function component using
const location = useLocation()
console.log(location.state)
Basically my question is similar to this one:
How to secure php scripts?
with one slight difference, the other side is Shopify.
Background info:
Shopify user bought some credits (Audible style), and wants to know how many he has available. He logs in into his account, and it says there that he has X credits.
That number comes from AJAX call to my server (I have full control), where there is a simple php script which checks the value in db (which is updated using webhooks from Shopify, each of which needs to be verified so they are secure, I think).
The script uses customers ID for a look up, and that value needs to be passed to the script somehow, and that allows someone external to just keep running it until he has all IDs and corresponding credits values.
So, my questions is, how do I stop that? How do I ensure that only authenticated users can check it, and only for their IDs.
There is plenty of info on Shopify docs about securing the connections the other way, i.e. to make sure only correct scripts have access to the Shopify db, but nothing about my problem.
As far as I know I only I only have access to JS on Shopify, which creates the problem, because everything I send to my server is visible to all.
Thanks
EDIT: I just read up on CSRF. I can easily implement checks for origin and headers, but these can be faked, right?
EDIT 2: I got around this problem by using metafields. So, instead of storing all that info on my server's db, I just use Customer Metafields to store the available credits. Webhooks are secure so that's brilliant. It still doesn't solve a problem with the next stage though. Customers will still need to be able to use their credits and get digital products, which are generated by my server. So I still need to verify the requests.
EDIT 3: Comment by #deceze and answer by #Jilu got me thinking. Yes, you are correct, I need to do that, but I don't have access to back-end on Shopify, so I cannot create session. However, what I could do (if I figure out how in js) is hash it. PHP login scripts operate on password_hash. That way you do not store a password in the db. Password get's verified again hash (or whatever you call) in the db, and it's either true or false. If true, you are logged in. So I could try to generate a token using a specific string (make it very long) and user id. Send it with the request, and using password_verify or what not, check it against the users. The one that pops positive is logged in user who requested the information. That is assuming I can hide the string in the Shopify...
Step1: Do a session login system.
Step2: Before the Ajax, generate a random token in your form or request page, put it into a input display none, send it with POST.
Verify each time if the token is set and is the same that you got.
You have now verified if the user is really logged in with session.
And you checked that he is from the right page.
You create a token out of shared secret (both Shopify and server have it), and client ID.
On Shopify:
{% assign my_secret_string = "ShopifyIsAwesome!" | hmac_sha256: "secret_key" %}
My encoded string is: {{ my_secret_string }}
On server:
We gonna be checking received hash value against values in our db, so we need to hash local client IDs using the same algo and key (that probably should be done on receiving the Customer Creation webhook).
Hash IDs using: http://php.net/manual/en/function.hash-hmac.php
$hashed_id = hash_hmac('sha256', '$client_id', 'secret_key');
Compare hash using: http://php.net/manual/en/function.hash-equals.php
$check = hash_equals($hashed_id, $received_id);
Then all that's requires is to loop through the db until you find a match. There may be quicker ways of doing it.
In my project a user can make a post (post a photo or some text). Technically I identify each post with a unique id in table posts where I store the user_id (owener of the post) and the id of the post is set to auto increment . Knowing the identification for each post I fetch all rows in the post table and put these post and relevant details( post_id, user_id, data, etc) inside an HTML. There are more things a user can do on that post, like discuss on the post, rate the post, and etc.
These things are done via an ajax post since I store the post_id on the HTML element attribute like ( data-p=52). sometimes I use the php base64_encode function to encrypt the post_id
Most in my application an event is acted on these post_id and user_id that is or are stored in the HTML custom attributes.
Now I am thinking of security issues and my question is : Is there a proper method or way I can hold these info in Javascript or a proper way I can encrypt these information about the post.
It is good you are thinking about the possible security vulnerabilities within your system. However, at the moment, from what I can tell, you are not quite worrying about the right thing. Data, like a user's ID, a post's ID, is not sensitive in itself. If you look at the URL of social networks, etc, it is very likely you will see user ID information, etc. What you need to think about, is how can I make sure that it doesn't matter this data is public? In other words, how can I prevent an attacker from using this data? Because this data on it's own, is just a bunch of numbers. Now, if there is a reason why these IDs are actually sensitive in your system, you should think about a slight structural rearrangement.
Take the common (or less so these days) SQL Injection technique. Where a attacker will input SQL code into a user input, and that input will then be concatenated/substituted right into a SQL query, therefore giving unwanted access to the database (see here http://www.w3schools.com/sql/sql_injection.asp). It does not matter the attacker knows the post ID, meaning oh no! He can delete the post he wants to, instead, it matters that he can delete any post he wants. So the problem is in the SQL vulnerability, not the knowing of the ID. And, to fix the SQL vulnerbabilty, you need to make sure that user input will disallow code-like characters. This is known as sanitization.
Of course I am not saying you shouldn't take care of what data is available to users. But the system itself needs to be robust.
The scenario you're worried about (that an attacker can use these IDs to send requests to your system to manipulate data in a way that you don't want) is independent of whether you expose your IDs to the client or not.
In some fashion, requests from your client will need to be handled by your server. If you have a feature where authors of posts can delete their own posts, hopefully you are validating delete requests that the user initiating the request is actually the owner of that post and not just blindly deleting data whenever someone asks your system to. Even if you introduced a surrogate key so as to prevent the actual primary key from leaking to the public, whatever route endpoint that is used to delete posts will still need to handle that data in a robust fashion that maintains the integrity of your data.
As I stated in a comment, really the only thing you should worry about are people performing maths on your IDs (such as plus and minus 1) in order to see if they can game your system and receive data back that maybe they shouldn't have. But even in that scenario whatever endpoint is responding to the request should validate that request before returning anything back. You can prevent this entirely by a) validating that the user requesting the data actually owns the data and b) by not using auto incremented integers as a primary key and instead relying on UUIDs as your primary keys.
I've got a single page node.js FB Canvas App. Every user action triggers an AJAX POST to my node.js HTTPS server, returning the result.
Now I need a way to send a user token I create from the userId on app boot (this is an AJAX POST too, returning all content + user token). I verify that it is this user by doing a Graph API call (which is required for my boot for another reason) on the server.
Q1 So to create the token what should I use?
Q2 How to send the token with every AJAX call:
POST param?
cookie?
something else?
Q1 I assume that tokens should be unique and secure. That's generally not an easy problem. I would go with following steps:
generate a random number
try to save it into DB (or any other shared storage)
if it already exists in DB go to step 1. if not go to step 4
send the token
Ad.1. To generate a random number use crypto.randomBytes with large enough size param (256 is more then enough) in order to minimize collisions:
http://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback
crypto.randomBytes should be secure. There are however some subtleties with it. For example you have to ensure that your machine has enough entropy. It can be a problem when your server does not have keyboard, mouse or mic. You can always add a hardware entropy generator:
http://en.wikipedia.org/wiki/Hardware_random_number_generator
If you don't need it to be secure then you can use crypto.pseudoRandomBytes instead.
Also it is a good idea to create and use your own algorithm (based on crypto of course). For example add a current date to that number, hash it, whatever. Just be careful not to overdo it.
Also remember about cleaning DB from old tokens.
Q2 It doesn't really matter. Whatever suits you. Probably putting it in a cookie is the easiest solution.
If you need this token for preventing from a CSRF attack, I'd recommend to send it into a POST parameter.
I'm trying to make a bookmarklet that does something similar to what Instapaper's does. I need the bookmarklet to send the URL of the page the user is visiting and the user's token(so the server identifies the user). How can this be done? Do you recommend I send a POST request or rather by routing the URL(for eg http://example.com/USER_TOKEN/URL )?
Also, will I need to worry about the user's token being stolen? If so, how can I handle that?
will I need to worry about the user's token being stolen
Since everything you transmit over plain HTTP is basically unencrypted plain-text, yes, you need to worry about the token being stolen.
What's more important imo, is that including the user token into your bookmarklet seems rather hack-ish:
What if a machine is used by multiple users A, B and C?
Users A and B are both using your service? Separate bookmarklets?
User C is pissed off about something A did - clicking his bookmarklet on a dozen porn sites sure sounds like fun, eh?
I would suggest something along the following lines:
Submit the URL to a GET (if you care about performance much) or POST (if you care about getting CRUD right) route.
Server-Side: Check if a user session exists (via cookies, obviously).
If so, process your data, send success callback as JSONP.
If not, send failure callback as JSONP which triggers a "Please Log in" popup/overlay.
Extra points are given for the "Please log in" thingy remembering the URL the user has been trying to save so he doesn't have to re-submit after having logged in.