I’m building a mobile app that requires knowing the location of the user when is sending data or posting
We have a concern if the users start to utilise proxy servers.
Are there any solutions/ python libraries that can be incorporated into the mobile app to detect users faking their location?
Users can fake their location by using a VPN. Proxies actually have other usages.
Use an API which does this. You need a real-time API which you can call through request. I use Abstract API because it's reliable and free: https://www.abstractapi.com/ip-geolocation-api you need to create an account though, but it's painless.
import requests
response = requests.get("https://ipgeolocation.abstractapi.com/v1/?api_key=YOUR_KEY&ip_address=THE_IP")
print(response.content)
In the JSON response, you have a boolean in ['security']['is_vpn'] to know if the IP belongs to a VPN.
An alternative solution is to create a script yourself, which would compare your user's IP with a list of known VPNs' IPs. But it may be not easy to find and collect all VPNs IP and update them regularly.
EDIT In response to your comment:
My answer will still work with an app spoofing the GPS locations like the one you linked because a real-time API won't be affected by that.
If you plan to use the GPS data from the phone and only look for a way to detect if it's real or fake, you can compare those GPS coordinates with the coordinates given in the API response. If there is too much of a difference, you can conclude the GPS data is faked.
You can download and host VPN or proxy list in your own server and query it with app IP address to detect if one IP address is behind a VPN or proxy.
There are public web services available but I do not recommend it as the 3rd party API site might be blocking your API call if traffics is huge.
Related
[Never worked with a RPi before, absolute noob on that field]
I want to make a desktop/mobile app to access a program on a RaspberryPi. The only task of the app is to send a command and display the received response on an UI. It's meant only for private use, but it should also work outside my local network. So as long as I have mobile internet on the phone it should be possible to access the program with the app.
Can I achieve this without using any kind of public website? I saw some tutorials that used Flask and other frameworks to do sth similar, but I want the access to be restricted to the app. There shouldn't be any URL I could type in my browser, that gives me access to a login page or sth like that.
If you know the specific term for what I am describing here or even better an article/tutorial that features it, that would be very helpful.
You need two things for that:
Make your Raspi visible to the outside world. That can typically be done by configuring port forwarding in your router. Note that this might impose a certain security risk.
Make sure you have a global DNS name for your internet access. Since the IP of your router may change frequently (depending on your ISP), you need a URL or rather, a DNS entry. There exist public DNS services that can assign a DNS entry to a dynamic IP (typically for a fee). Many routers support a protocol to configure such services.
After that, you can program an app that uses the given DNS entry to talk to your Pi.
So no, without a public URL, this is not possible, at least not over the long term. You might be able to go with the public IP of your router, but then your app may fail from one day to the next.
In my python project I have to track user IP address and country and region, and other information, I used "https://ipapi.co/json/" for tracking the IP address, but thing is when i deploy my model(web-app) on the deployment website, it is giving me that server IP address instead who is using my web-app. when i try in my local machine it is giving my IP address. Actually, i am currently new and don't know that much about tracking IP another.
Please anyone can describe how i will achieve this thing. how to track the user of my web-app IP address instead of the deployment server IP address.
Ref- I am using streamlit sharing for the deployment it is giving me streamlit office address instead of my friend(test user) IP. I need my fried IP address when he is using the deployed web app.
Thank you sir for your consideration, a help will be great for me, am really stuck here. my project in Python.
It sounds like you're trying to get the IP from this 3rd party service from your server, which would of course return the server's IP address.
Based on a comment on the question:
I am using streamlit for creating the web app.
Based on a cursory Google search, it sounds like getting the client's IP is non-trivial in that system:
https://discuss.streamlit.io/t/i-run-a-streamlit-app-and-it-processes-some-records-based-on-client-user-input-i-want-to-log-ip-address-of-client-user-and-records-processed-by-that-user-can-you-help-please/2382
https://discuss.streamlit.io/t/how-to-get-all-ip-addresses-and-their-countries-connecting-to-a-live-streamlit-app-on-aws-ec2/2273
https://discuss.streamlit.io/t/how-to-output-client-or-remote-ip-s-to-console/832
(Based on this I would probably recommend using a different Framework/platform for building web applications. This sounds... extremely limited. But that's another matter entirely.)
The service you reference would need to be accessed from the client computer, which means accessing it from JavaScript. If that service doesn't allow CORS requests, there are other options available. Once you have the value(s) you need in JavaScript, you can send them to your server-side code via an AJAX request, a Form POST, etc.
I'm trying to secure my API routes with API keys and website URL of the client.
I'm using the tuple (api_key, website_url) to grant the access to my API. In fact, the website URL is sent in the request. Example: using Angular httpClient
this.restPost(this.endpoint,body,options)
the options include: the API key and website URL.
How can I check if the website_url inserted in the options matches the URL of the request sender? I'm using Flask microframework in the backend.
What you are asking for is impossible.
Fundamentally, if requests are coming to you across the public internet, you cannot know the identity of the application sending requests to you.
You can make an educated guess about the remote client. But since the remote client is running on a platform you can't control, nothing prevents an attacker from reverse engineering how it works and then sending you identical requests. You won't be able to tell the difference if the attacker is skilled enough.
There are tools that can help you detect and block malicious clients, but there are also tools for malicious clients to evade detection (just search Stack Overflow for many examples of the reverse problem). It's an arms race and if you want to win you will need to invest more time and money than your counterpart(s) on the other side are.
The normal solution to this problem is to make it your clients' problem. Charge them for a quota of API requests, and bill them if they make more than that. Then if they share the API key with someone else, they also need to pay the bill for them. Then you don't need to care whose API key it is: you're getting paid either way.
If you can't bill them (e.g. if it's a free service) then the next best thing is rate limiting. Don't allow more than, say, 10 requests in a second for a single API key.
If you're serious about this sort of thing, you probably don't want to reinvent the wheel. There are cloud-scale API gateway services out there. Pick one and use it to handle all your API key authentication and client throttling.
Is there a way to specify a proxy server when using urlfetch on Google App Engine?
Specifically, every time I make a call using urlfetch, I want GAE to go through a proxy server. I want to do this on production, not just dev.
I want to use a proxy because there are problems with using google's outbound IP addresses (rate limiting, no static outbound IP, sometimes blacklisted, etc.). Setting a proxy is normally easy if you can edit the http message itself, but GAE's API does not appear to let you do this.
You can always roll your own:
In case of fixed destination: just setup a fixed port forwarding on a proxy server. Then send requests from GAE to proxy. If you have multiple destinations, then set forwarding on separate ports, one for each destination.
In case of dynamic destination (too much to handle via fixed port forwarding), your GAE app adds a custom http header (X-Something) containing final destination and then connects to custom proxy. Custom proxy inspects this field and forwards the request to the destination.
We ran into this issue and reached out to Google Cloud support. They suggested we use Google App Engine flexible with some app.yaml settings, custom network, and an ip-forwarding NAT gateway instance.
This didn't work for us because many core features from App Engine Standard are not implemented in App Engine Flexible. In essence we would need to rewrite our product.
So, to make applicable URL fetch requests appear to have a static IP we made a custom proxy: https://github.com/csgactuarial/app-engine-proxy
For redundancy reasons, I suggest implementing this as a multi region, multi zone, load balanced system.
For a college project for my course on Introduction to Programming, I decided to make a small software that traces the IP address and puts them nicely on a GUI (PyQt). Not a big deal I know, but still I like the idea.
So I Googled around and found MaxMind's IP and their free offering and the pygeoip, which is an API for the MaxMind GeoIP databases. Pretty cool, eh!
But the downside is that to query their database, I have to download individual databases for country city. This is not good cause I have to make the end user download additional files (in MBs) just to look up an IP address.
So I am wondering, is there another method of doing this? How do I trace IP addresses? Note that I need them down to the city level, if possible. Something like this guy aruljohn.com/track.pl
Thanks!
I would have preferred "pygeoip", because it allows you to develop a complete solution locally. Of course, you will need to keep the database.
If you do not want to keep the database locally, you will have to depend on an external service to query for location of an IP. This will keep your solution small but dependent on this service.
For this check out: ipinfodb.com
http://ipinfodb.com/ip_location_api.php
They provide JSON and XML APIs interface which should be sufficiently easy to build.
Check out more information at : http://ipinfo.info/html/geolocation_2.php
I have even better idea. Why don't you make a very simple web app, which will do the actual look up; and you PyQt client would do HTTP request to that. Or maybe in that case you don't even need a client. Just make a web page to get IP address and show city.