What is the easiest way to obtain the user's host/domain name, if available?
Or is there a function to lookup the IP address of the user to see if it is bound to a named address? (i.e. gethostbyaddr() in PHP)
HttpRequest.get_host() only returns the IP address of the user.
You can't rely on it, but you can try the request.META['REMOTE_HOST'] or request.META['HTTP_HOST'] from the META dictionary of the request :
A standard Python dictionary containing all available HTTP headers. Available headers depend on the client and server, but here are some examples:
- REMOTE_HOST -- The hostname of the client.
- HTTP_HOST -- The HTTP Host header sent by the client.
You can use socket.gethostbyaddr()
You can just print HttpRequest.META and find what you want and I think req.META['HTTP_ORIGIN'] is the thing you need, It's the same as the browser address bar value.
Related
I am using Flask and need to get the user's IP address. This is usually done through request.remote_addr but since this app is hosted at a 3rd party (and using cloudflare) it just returns the localhost.
Flask suggests getting the X-Forwarded-Host but then they immediately say it is a security risk. Is there a safe way to get the client's real ip?
The Problem
The issue here is not that the ProxyFix itself will cause the user to get access to your system, but rather the fact that the ProxyFix will take what was once mostly reliable information and replace it instead with potentially unreliable information.
For starters, when you don't use ProxyFix, the REMOTE_ADDR attribute is most likely retrieved from the source IP address in the TCP packets. While not impossible, the source IP address in TCP packets are tough to spoof. Therefore, if you need a reliable way to retrieve the user's IP address, REMOTE_ADDR is a good way to do it; in most cases, you can rely on it to provide you something that is accurate when you do request.remote_addr.
The problem is, of course, in a reverse-proxy situation the TCP connection is not coming from the end user; instead, the end user makes a TCP connection with the reverse proxy, and the reverse proxy then makes a second TCP connection with your web app. Therefore, the request.remote_addr in your app will have the IP address of the reverse proxy rather than the original user.
A Potential Solution
ProxyFix is supposed to solve this problem so that you can make request.remote_addr have the user's IP address rather than the proxy. It does this by looking at the typical HTTP header that remote proxies (like Apache and Nginx) add into the HTTP header (X-Forwarded-For) and use the user's IP address it finds there. Note that Cloudflare uses a different HTTP Header, so ProxyFix probably won't help you; you'll need to write your own implementation of this middleware to get request.remote_addr to use the original client's IP address. However, in the rest of this answer I will continue to refer to that fix as "ProxyFix".
This solution, however, is problematic. The problem is that while the TCP header is mostly reliable, the HTTP headers are not; if a user can bypass your reverse proxy and send data right to the server, they can put whatever they want in the HTTP header. For example, they can make the IP address in the HTTP header the IP address of someone else! If you use the IP address for authentication, the user can spoof that authentication mechanism. If you store the IP address in your database and then display it in your application to another user in HTML, the user could inject SQL or Javascript into the header, potentially causing SQL injection or XSS vulnerabilities.
So, to summarize; ProxyFix takes a known mostly-safe solution to retrieve the user's IP address from a TCP packet and switches it to using the not-very-safe-by-itself solution of parsing an easily-spoofed HTTP header.
Therefore, the recomendation to use ProxyFix ONLY in reverse proxy situations means just that: don't use this if you accept connections from places that are NOT the proxy. This is often means have the reverse proxy (like Nginx or Apache) handle all your incoming traffic and have your application that actually uses ProxyFix safe behind a firewall.
You should also read this post which explains how ProxyFix was broken in the past (although is now fixed). This will also explains how ProxyFix works, and give you ideas on how to set your num_proxies argument.
A Better Solution
Let's say your user is at point A, they send the request to Cloudflare (B) which eventually sends the request to your final application (point C). Cloudflare will send the IP address of A in the CF-Connecting-IP header.
As explained above, if the user finds the IP address to point C, they could send a specially crafted HTTP request directly to point C which includes any header info they want. ProxyFix will use its logic to determine what the IP address is from the HTTP header, which of course is problematic if you rely on that value for, well, mostly anything.
Therefore, you might want to look at using something like mod_cloudflare, which allows you to do these proxy fixes directly in the Apache mod, but only when the HTTP connection comes from Cloudflare IP addresses (as defined by the TCP IP source). You can also have it only accept connections from Cloudflare. See How do I restore original visitor IP to my server logs for more info on this and help doing this with other servers (like Nginx).
This should give you a start. However, keep in mind that you're still not "safe": you've only shut down one possible attack vector, and that attack vector assumed that the attacker knew the IP address of your actual application. In that case, the malicious user could try to do a TCP attack with a spoofed Cloudflare IP address, although this would be extremely difficult. More likely, if they wanted to cause havoc, they would just DDOS your source server since they've bypassed Cloudflare. So, there are plenty more things to think about in securing, your application. Hopefully this helps you with understanding how to make one part slightly safer.
I am running my own DNS name server which I have developed in python. I have a registered domain name say "abc.in". The name servers of the domain are set to my computer's IP address (given by ISP). Now whenever anyone access the domain name I am getting the visitor's ISP's IP address. I want to get the visitor's IP address. Actually I want to make a small CDN like project, also I am not able to find any good source of information. Is it possible to get the visitor's IP address, I am developing it in Python ?
I had read in CloudFlare's blog that they get the visitor's geographic information (IP address) from the initial DNS lookups.
You can use socket function in python. Like following.
>>> socket.getaddrinfo
What you're trying is simply not possible. You'll always get the connection from the resolver, not the final client.
How can we identify distinct computers/devices on an intranet?
This is possible using cookies but that is not foolproof.
I am expecting something on the lines of finding local ip address.
It would be great if you mention some tools(libraries) required to integrate it with an intranet application. The application is designed in Python(Django).
You can get the client (computer connecting to your web server) IP address from the HttpRequest object. If your Django view is def MyView(request): you can get the IP from request.META.get('REMOTE_ADDR'). Is that what you're looking for?
You could take a look at the HttpRequest documentation on Django: https://docs.djangoproject.com/en/dev/ref/request-response/
There you'll find that you can know the remote IP address of the user with the request object on your view or middleware using request.META["REMOTE_ADDR"]
I use this in a multihomed server where the requests for the internal LAN come to a local IP Address and the public requests goes to a public IP Address, there comparing the REMOTE_ADDR to the beginning of my internal LAN address i can know if it is an internal request or not.
I am trying to identify users that access my website. I know of assigning a cookie to them & identifying them that way. But is it also possible to use their IP address to identify them?
I know of IP subclassing (is that the correct term) so if many users on the same network access my site & have subclassing, they will all have the same IP address but thats ok, I dont want my IP identification to be exact, its just a backup if the user has no cookie.
If I have a HTTP request can I get the ip address of the requester/sender? For example to get the browser type I check the HTTP (header?) user-agent. With my little knowledge of Data Communications, if the HTTP request does contain an IP address, wont it have the IP address of the last hop(router/switch) or am I thinking of TCP?
I am using Python & cgi; so is there a way to determine the HTTP requesters IP address either by looking at the HTTP request, or maybe TCP packets(I never worked with TCP in python, how could I look at data packets in python?).
Sure. Use cgi, and os. The client's IP address is located in the environ variable with a title of REMOTE_ADDR. For example, the following will print out the client's ip address:
import cgi
import os
print "Content-type: text/html"
print ""
print cgi.escape(os.environ["REMOTE_ADDR"])
I want my Python script to access a URL through an IP specified in the script instead of through the default DNS for the domain. Basically I want the equivalent of adding an entry to my /etc/hosts file, but I want the change to apply only to my script instead of globally on the whole server. Any ideas?
Whether this works or not will depend on whether the far end site is using HTTP/1.1 named-based virtual hosting or not.
If they're not, you can simply replace the hostname part of the URL with their IP address, per #Greg's answer.
If they are, however, you have to ensure that the correct Host: header is sent as part of the HTTP request. Without that, a virtual hosting web server won't know which site's content to give you. Refer to your HTTP client API (Curl?) to see if you can add or change default request headers.
You can use an explicit IP number to connect to a specific machine by embedding that into the URL: http://127.0.0.1/index.html is equivalent to http://localhost/index.html
That said, it isn't a good idea to use IP numbers instead of DNS entries. IPs change a lot more often than DNS entries, meaning your script has a greater chance of breaking if you hard-code the address instead of letting it resolve normally.