Know original IP address of user when request coming from a web proxy - ruby-on-rails-3

Context
I am working on an application which detects the user's IP address from the request and restricts them from doing certain actions on a page based on the country they are in.
Problem
When a user makes a request to our application via some Web proxy, we are unable to fetch the original IP address of user's device and hence, the country from it. Examples of web proxies can be a website like hide.me, OR a browser extension such as GeoProxy, etc.
I tried to scan the whole request object inside my Rails controller to see if there is any information about the real IP address of user, but my every attempt seems to return the IP address of web proxy instead. See some results (development mode + ngrok) below:
> request.ip
=> "154.48.196.3" # This is IP address of web proxy i used, while my actual IP address is "119.82.x.x"
> request.remote_ip
=> "154.48.196.3"
> request.remote_addr
=> "127.0.0.1"
> request.env
=> {"GATEWAY_INTERFACE"=>"CGI/1.1",
"PATH_INFO"=>"/shops/alinea",
"QUERY_STRING"=>"",
"REMOTE_ADDR"=>"127.0.0.1",
"REMOTE_HOST"=>"localhost",
"REQUEST_METHOD"=>"GET",
"REQUEST_URI"=>"https://86d3f832.ngrok.io/shops/alinea",
"SERVER_NAME"=>"86d3f832.ngrok.io",
"SERVER_PORT"=>"443",
"SERVER_PROTOCOL"=>"HTTP/1.1",
"SERVER_SOFTWARE"=>"WEBrick/1.3.1 (Ruby/2.1.10/2016-04-01)",
"HTTP_HOST"=>"86d3f832.ngrok.io",
"HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36",
"HTTP_ACCEPT"=>"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"HTTP_X_FORWARDED_PROTO"=>"https",
"HTTP_X_FORWARDED_FOR"=>"154.48.196.3",
...}
> request.env['HTTP_X_FORWARDED_FOR']
=> "154.48.196.3"
Can someone guide me on how to generate a foolproof solution that will return me the original IP address of users every time, no matter how they try to access our application?
Best solution should cover as many points from this doc as possible.
Configuration
Ruby v2.1.3
Rails v3.2.22.5

Related

How can I limit API access to a limited set of domains

I'd like to limits API access from one or more domains - in other words I have a set of exposed API endpoints but I only want to respond to specific remote servers.
I intend to issue tokens to the servers that I intend to respond to but I want to ensure that I'm really dealing with the right servers in case the tokens become public knowledge.
I thought I would be able to use Origin or Referrer from the HTTP headers but perhaps because I'm sitting behind an Nginx front end, those headers don't always seem to be visible.
Any suggestions gratefully received.
You can't find domain names by ip (nslookup/dig $IP) becausethe reverse resolution requires an entry in the reverse zone (dns) configured for that ip. Not everyone sets up a reverse zone and, more importantly, many domain have just an A record configured.
Using other informations coming from the request itself, IMHO, are not a valid solution because these information can be forged so there's an high chance they make be "fake".
The best solutions I can suggest you are:
Filter by ip: if you know who's going to call your api, they know what's the ip they're using to call your webserver. Configure apache so allow access to such ips.
Configure a client side authentication on your api so only those with a valid and authorized certificate (which doesn't need to be signed by a valid CA: you can create and use your custom CA) will be able to connect.
Limiting CORS / origin headers is one way if your API calls are coming from client side.
If its from server side call, IP is one way, but not guaranteed if there are many network hops in between and references are not passed by load balancers.
May be you can try something like this (Node.js):
const whitelist = ['https://www.example.com','https://www.example.com'];
const corsOptions = {
origin: (origin, callback) => {
if(whitelist.indexOf(origin) !== -1){
callback(null, true)
}else{
callback(new Error('Not allowed by CORS'))
}
},
optionsSuccessStatus: 200
}
replace https://www.example.com with your domains.

How to access COWIN APIs?

I want to access these APIs from cowin.gov.in
This API is for getting the vaccination certificate -
https://ndh.digitallocker.gov.in/public/marketplace/api/cowin/cowincert
But when I access this using mobile number and a beneficiary ID , I get unauthorized access.
It requires to generate token and require following this from this site - https://openapi.aarogyasetu.gov.in/profile
I am integrating this to my Flutter App how can I get the following
Your Public Key (Callback data will be signed using this)
Callback URL
I am an individual using this API but it needs some company info too. What should I do?
Check this image for more details of registration
I checked the website https://openapi.aarogyasetu.gov.in/ and got the contact details
openapi.aarogyasetu#gov.in. Please try to send a mail to this id and lets see what they are going to respond. I am not sure whether individuals can get access to those API's since they are asking a lot of information about company/organization.
As stated in the image below, We might need to contact the Ministry of Health and Family Welfare, Government of India to get access to the protected APIs.
You can now raise your issues on https://github.com/cowinapi/developer.cowin
This is official github repository of COWIN
You can check all the open issues as well the closed issues for clarifications.
You don't need an api key for accessing the public api end points
mention general user agent like this {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 Edg/90.0.818.56"} to avoid getting the error.
Co-WIN Public APIs allow any third-party application to access certain un-restricted information, that can be shared with its users. This is limited only to read access in Co-WIN. The appointment availability data is cached and may be up to 5 minutes old. Further, these APIs are subject to a rate limit of 100 API calls per 5 minutes per IP.
Swager API documentation official resource
https://apisetu.gov.in/public/api/cowin/cowin-public-v2
header = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36',
'origin': 'https://selfregistration.cowin.gov.in/',
'referer': 'https://selfregistration.cowin.gov.in/'
}
also needs
data = {"mobile": mobile,
"secret": "U2FsdGVkX1+z/4Nr9nta+2DrVJSv7KS6VoQUSQ1ZXYDx/CJUkWxFYG6P3iM/VW+6jLQ9RDQVzp/RcZ8kbT41xw=="
}
source
https://github.com/pallupz/covid-vaccine-booking/

Get Client Machine Name and ID - ASP.NET Core 3.1

I need to get the computer name and id of a client when it uses my SSO web .net core application.
My first solution was to this for the machine name:
var machName = Environment.MachineName;
And this for the machine id:
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
{
// consider ethernet interfaces
if(nic.NetworkInterfaceType == NetworkInterfaceType.Ethernet && nic.OperationalStatus == OperationalStatus.Up)
{
return Ok(nic.GetPhysicalAddress().ToString());
}
}
Then is dawned on me that these are getting the name and id from the server, as in my computer.
I am currently debugging the request info including the header info, but I can't see anything in the header that correlates to the name and id. I am able to get the request IP and user agent from the HttpContext which is something i need, but not the name and id.
As far as I know, it's impossible actually to get client machine name and host name is not client machine name.
The client will send request to the server, so we could only get the parameter through request.
The request contains below things:
Request IP address (TCP/IP)
HTTP headers
That's all. IP address is an IP which is given by your Internet provider, and host name is name of some provider machine which Internet traffic passes through.
From request IP you cannot get real client machine name in general. In HTTP headers browsers also don't pass machine name.

How do I extract an ip address in the azure api management policy?

Is there an out of the box policy to extract the incoming ip address? I could not find one.
Do I need to write code to do that? If so, how do I go about it? What are the other alternatives?
You can extract IP address in any policies using policy expressions. The expression would be context.Request.IpAddress
You can definitely use policy expressions.
But an easier approach might be the below:
If your goal is to capture the origin IP address (and not Azure's) on your backend (for logging purposes, etc.), then:
Whenever Azure API Management Studio forwards requests to your backend, it includes the header X-Forwarded-For
E.g.
{[X-Forwarded-For, 123.45.67.891, 13.75.131.25:1795]}
The first IP Address is the one you want.
The second IP Address is actually Azure's.
E.g. First, A mobile app makes a request to Azure API Mgmt --> Second, Azure API Mgmt forwards the request to your back end --> Lastly, you capture client's the IP (i.e. the mobile device's IP) from X-Forwarded-For.
How you capture the IP from the headers on your backend is up to you and what technology you're using (e.g. ASP.net core, node.js, etc.).
Here's a snippet of code where I'm capturing the IP
private LogMetadata BuildRequestMetadata(HttpRequestMessage request, Task<string> requestBody)
{
var headers = request.Headers.ToDictionary(d => d.Key, d => d.Value.Join(", "));
// If header X-Forwarded-For is included,
// it means the request is coming from Azure API MGMT studio.
// Example header value: {[X-Forwarded-For, 123.45.67.891 (Mobile Device), 13.75.131.25:1795 (Azure API Mgmt)]}
var clientIp =
headers.ContainsKey("X-Forwarded-For")
? headers["X-Forwarded-For"].Split(',')[0]
: request.GetOwinContext().Request.RemoteIpAddress;
}

OKTA API not exporting Source address details

I have created an OKTA API using token and admin account url to export the events(logs) reffered to the activities done on my okta account.
i am able to export the events but the IP address details or the source IP (from where) info is not getting exported.
anything more need to added to API for the same. please advise.
Modify Okta API com.okta.sdk.models.event.Actor.java
Add a property:
private String ipAddress;
Add get/set funcitons.
Compile source code to a new Okta API jar, use this jar substitute the original one, then you will get your IpAddress attribute value in event.actor.ipAddress
The ipAddress depends on the Actor objectType. Events with a Client ObjectType will include the ipAddress as shown in the example below:
{
"id": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.65 Safari/537.36",
"displayName": "CHROME",
"ipAddress": "127.0.0.1",
"objectType": "Client"
}
One way to debug this would be to use the public Events API and filter the events to validate that for the ipAddress is getting captured for the appropriate Events. If the ipAddress is included in the JSON response but is not getting parsed in the CSV export, then you may have uncovered a bug. That said, I just tested this and it worked for me ;-)