Storing users IP address in a DB in order to compare it later on - reactjs

I'm quite new to React and after doing a Todo web app I've tried creating my first fullstack web app.
The app sends a request upon entering an Email and pressing a button that should send the users mail to a DB and get his IP which would also be stored into the same DB. This would later be used to check if the user had already done something on the site (After entering the email the client-s sent to the next page) and disallow the user to proceed if either the email or IP are already stored in the DB. What would be the best way to both grab the IP upon entering the email and what would be the best approach in regards of storing it into a DB? (Should I even store it there is there a better alternative).
I'm writing my code with Typescriptx and using Express for my backend & postgres for my DB.
TLDR: How to get the clients IP onClick / upon recieveing a request from them and store it in a database to later compare when the user sends the same request again

On the server side, you can get the IP address from the incoming request. That's the right way to do this (but see below: I think you probably don't want to do this).
In express, this is available via req.socket.remoteAddress. If you're behind some kind of reverse proxy like a CDN then this will give you the CDN's IP, not the real user, but all modern proxies will include the original IP in a request header such as X-Forwarded-For to work around this. You can get the IP from there instead, if that's present. You'll need to look at the docs for your specific infrastructure to check the header they use in this case.
That said, it sounds like you're trying to ensure each user can do exactly one thing, so that after sending an email nothing else is allowed. Is that right?
If that's the case, limiting it by IP address isn't a great solution. Two reasons:
Many users share an IP address, e.g. many many mobile users who are behind CGNAT, everybody sharing an office/home, etc etc
At the same time, many users have multiple IP addresses, e.g. offices that use multiple internet connections in parallel for failover or performance, or people taking their computer from their home to a cafe, etc etc.
In both cases, you'll end up blocking or allowing large numbers of users incorrectly. Typically this kind of thing is done with cookies/local storage on the client side instead, which lets you block this individual user's browser. That will work correctly in environments with shared IPs and environments with multiple IPs.
A client-side approach is not 100% secure, since a technical user could easily clear their cookies to avoid this. If you need a hard guarantee though then neither option would work (it's easy to change your IP too: go sit in the coffee shop outside, or use your phone as a hotspot). In that case, you need to tie the user to something they can't as easily change, maybe an email address, credit card, or even legal ID if you're seriously trying to lock this down hard.
I wouldn't bother: for most web app, client-side storage is usually the right choice.

Related

User login in Django + React

I have looked through quite a few tutorials (e.g. this, this, and this) on user authentication in a full-stack Django + React web app. All of them simply send username and password received from the user to the backend using a POST request. It seems to me that, if the user leaves the computer unattended for a minute, anyone can grab his password from the request headers in network tools in the browser. Is this a valid concern that must be taken care of? If so, how should these examples be modified? A tutorial / example of the correct approach would be appreciated.
It seems to me that, if the user leaves the computer unattended for a minute, anyone can grab his password from the request headers in network tools in the browser
If the user leaves the computer unattended then what you are describing will probably be the least of his/her worries.
Authentication is a complex topic, if you really do not want to use existing libraries that handle this for you then you will need to spend quite some time to get things right (knowing that even then, risk 0 does not exist), the most basic thing being to never store plain text credentials on your DB and using https to transmit them over an encrypted connection. You can then start thinking about JWTs, avoiding local storage, CSRF and securing cookies, refresh tokens, etc.
You cannot do much however about cases like the one you describe of people giving away access to their computers or sharing their passwords with others except reminding them they should never do such a thing.
On a side note, if the user didn't have the network monitoring tool open when making the request to your website, opening it afterwards will not show the previously submitted plain text credentials (there are workarounds to this however)

how to send email on Code Name One using Gmail Api

I want to know if There Is a solution to send an email on a Code Name One app using Gmail Api,
i have an exception When i m using javaxmail,
error: cannot find symbol
import java.util.Properties;
symbol: class Properties
thanks in Advance.
You can use Display.sendMessage to send an email in Codename One. However, this is an "interactive" API that will launch the users email client and he'll need to press send to perform the actual emailing.
Alternatively you can use the sendgrid cn1lib to send an email via sendgrid. I would recommend against that though. If you send an email from the device that means your credentials (password etc.) would be on the device. A better way would be to contact your backend server and ask it to send the email for you. That way a hacker can't decompile your app and find out your credentials.
I agree with Shai's response, I'd just like to add a few more thoughts.
Sending emails from a mobile application (regardless of whether it is developed with Codename One) has two major problems:
the first problem, as mentioned by Shai, concerns the credentials: putting your Gmail account inside the client app code is a very bad idea;
the second problem is specifically about Gmail, since you're not referring to a generic mail service, but to Gmail itself: Stack Overflow is not the place to make recommendations on which services to use, however I can tell you why Gmail is probably not what you want to use. The main problem is that Gmail, when used for "third-party apps" (which Gmail considers insecure), doesn't allow you to change IP addresses frequently: if it notices an IP change, it blocks the service and forces you to manually unblock it in the security settings. Obviously the problem is minor if Gmail is contacted by your server that has a static IP address, but it becomes a big problem if Gmail is contacted directly from your users' phones, each of which will have a different IP.
That said, if your app made with Codename One needs to send emails (e.g. to activate new users), I recommend:
your app can use Codename One's Rest class to make a REST call to your RESTful server backend;
in your server, you could use an alternative service to Gmail that doesn't give problems if you change the server IP address every now and then or if you use the server both locally and remotely. For what is my experience, I can tell you that on my Spring Boot server I use org.springframework.mail.javamail.JavaMailSender, which is compatible with various mail services (just for information, I use a free ZohoMail account, however there may be many other alternative and equally valid mail services that I do not know).
As for using Codename One's Rest class, I'll point you to the developer guide (https://www.codenameone.com/developer-guide.html#_rest_api) and to this blog posts: https://www.codenameone.com/blog/terse-rest-api.html and https://www.codenameone.com/blog/new-rest-calls.html
When making Rest calls with Codename One, always keep in mind that there may be no Internet connection or other connectivity issues (or server-side errors), so careful handling of possible errors is critical.

Store sensitive, non editable data client side

I have an angularjs app that is on a separate domain than my backend, and the users from my backend all have roles and permissions that allow them access to various areas and elements of my frontend.
Before, I was just storing to a cookie and checking as I needed through the use of angular services and whatnot, cool.
Now the permissions datum have reached the point where they are too big to store in a cookie in the browser. And I'm avoiding Localstorage for fear of user tampering.
The Question:
How do I store the users sensitive data (or anything sensitive, really) that are too big for cookies on the client side in a manner that is safe and doesn't require API calls all the time to get?
I don't want to have to phone home every page change to get this data direct from the server when I need it, because I feel this would be really detrimental to the speed and flow of the site, not to mention the frequency at which this would need to happen would be ridiculous for my app.
Keep in mind that I do proper permission checking on the backend before carrying out any actions, but I'm more concerned about users tampering with their permissions to show certain elements that were removed on the frontside before.
What would be your solution or your advice on this?
If it ends up on the user's computer, regardless of whether it's in a cookie, in local storage, in the URL, in the browser's cache, or anywhere else on the user's computer, assume that the user can see it and mess with it. (You could encrypt it, but if your client-side logic knows how to decrypt it, you're back to step one.)
The best that you can do is exactly what you've described - be sure that the server only carries out authorized actions, and never trusts what the user tells it.

Secure / Authenticated interaction from a WP7 app

I am working on a WP7 application. This WP7 application will interact with some web services that I have created. I do not want other applications interacting with these web services. The reason why is because I do not want them stealing my data. With that in mind, here is what I'm currently doing:
Connecting to web services via HTTPS
Making my users initially login to the application
Passing the users username / password with each web service interaction
At this time, I don't see what is stopping a malicious developer from creating a username / password combo and using that account in their application to interact with my web services. How do I really lock this thing down?
Thanks!
As a start towards a more secure system you should stop storing the password and sending it over the wire with each request (even if you're using SSL).
If you must pass it with each request, store a salted hash of the password and use that instead.
I'm using a multi layered approach to this problem. I recommend thinking creatively and using a variety of methods to validate that requests are coming from devices you expect requests to come from.
Alternatively, if there is any merit in your scenario, open up your api to 3rd party developers and make this work toward your objectives.
If you do decide to store a key in your app, don't store RAW text but instead declare a byte array of the UTF8 values, this won't be as easy to read.
You can then handshake with your service using a salted hash of the key the first time the app is run, the service hands out another key for the device to actually use day-to-day.
The phone should have an almost accurate time, so you can recalculate the key each day or hour. You can also revoke the key at the server end for just that device.
This API will be useful in ensuring you can blacklist a device permanently.
DeviceExtendedProperties.GetValue(“DeviceUniqueId”).ToByte();
I've not looked into symmetric encryption by you might even be able to use the above unique ID as a private key.
I think the key to success is that first hand-shake, and ensuring that is not snooped. If it's a really important system, then don't use any of these ideas since rolling your own encryption is always flimsy to anyone with serious intent - use well-known methods and read up.
Luke
You could introduce an "Authorized Application ID" feature where the application sends its name or identifier within each HTTP request body. Then on the server side you can verify the application's identity (e.g. store the authorized app ID's in a table). The application ID would be encrypted within the HTTP(S) body.
This would also give you the option of pushing out new application ID's in updated versions of the WP7 application if you wanted to get rid of an older application ID. You'd also be able support new applications on difference devices or platforms in the future.
You may want to look at this
http://channel9.msdn.com/Blogs/Jafa/Windows-Phone-7-Trade-Me-Developer-Starter-Kit

Why would I need to save IPs of my web site users?

Should I save this information in the database?
For example when users sign up or log in?
Unless you're tracking the users coming to your site, limitting access based on IP address, or providing geographical services (based on IP lookup)...then you don't need to save this information at all.
Rate Limiting (to protect your resources eg. API)
Security (for auditing reasons - match IP with user credentials)
Geolocation based services (if not now, maybe in the future?)
Data for future load-balancing functionality
Some sites, like banks, will use this info as a security measure. If you try to sign in again from another IP address, you will be asked to confirm your identity.
If you were implementing an auto-sign on feature than you are likely to store this (alongside checking for data in a cookie) to attempt to verify that the computer is the correct one for the user, before auto-logging them on.
Most web servers already log this kind of information in their log file.
You may want to log the IP in order to match up the web logs with your user via the IP (and time).
This will not be 100% correct, as IP addresses can be shared (for example behind a NAT firewall).
Should you do this? It depends. Do you need this functionality? Depending on the answer to this question, you should make your decision.
IP bans for misbehavior. About the only solid reason for collecting the raw IP addresses (and not "cooked" data like geolocation or ISP). If you get several similar ban reasons for new accounts, check the IPs they logged in from, and if they are the same or very similar you may want to block on per-IP basis.
You should save IPs of users only when you have a poll or rating system where anyone can vote once. Also you could store IP data to check for multiple log in sessions so people can sign out other active sessions from your site, like in GMail.
We do a site where the "authorities" of our country often call in and what to have IP addresses from a specific user because of copyright infringements or other lawsuit reasons. This might be country specific but for us, this is a reason to keep some IP addresses of our users.

Resources