Larry Steinle

June 28, 2014

Big Brother, Little Brother or No Bother?

Filed under: C,Security,VS.Net,Web — Larry Steinle @ 1:07 am
Tags: , , , ,

Ever see the message, “Your IP Address has been recorded?” In this article we will review what kind of information a web site can gather about you, why a web site may need this information and how to get the information using c#.

Do you want your rights to privacy protected or do you want your online information secure?

With the recent data breach at Target and the Edward Snowden incident, nearly everyone has become very concerned about the topics of security and privacy. As a programmer I find these two topics diametrically opposed and very frustrating.

Like everyone I value my privacy. I want to know that when I am online my personal information will be kept safe and confidential. Meanwhile I want confidence that any website I log into understands who I am so that my identity can’t be stolen.

That’s the crux of the security/privacy issue. A truly secure web site knows without any question who I am and therefore violates my privacy. And a truly private web site doesn’t have a clue who I am. You can’t have security and privacy. It’s simply not possible. So you have to choose, do you want confidence that someone can’t steel your identity or privacy in that nobody knows who you are?

I remember when Intel and Microsoft teamed up to introduce a unique number on the CPU that would be transmitted with each internet page request. Privacy advocates went crazy about the impact of how governments and business could track people. Yet, it was one of the best options to ensure secure authentication with a website. Privacy advocates won and the setting was disabled by default.

What is an IP Address anyway?

An IP Address is like a postal mailbox number or a phone number. Every computer connected to the internet has an IP Address. This is how computers talk with each other. When you connect to the internet there is a handshake between your personal computer and the internet provider. The internet provider’s computer (web gateway router) then communicates with other computers until you get to the specific web site you are requesting. Actually, the requesting website can only see your internet provider’s router. That’s because the internet provider copies your internal request and passes it off to another computer on the internet using an external IP Address that has nothing to do with your personal computer. To reduce the risk of IP Address conflicts the specific IP Address range for an internal network is different from that of an external network. When you jump from an internal network behind your Internet Providers network into the world wide web you go thru the Internet Providers external network address.

The only company that has access to your personal computer IP Address is the internet provider and the government (via your internet provider). Nobody else can see your personal computer IP Address because you are hidden behind the internet provider’s web gateway router.

So what a business is tracking isn’t even your personal IP Address. Instead it is the Internet Providers IP Address providing you with global internet access. If your computer is on a network inside a business then the global internet see’s your business router IP address instead of your personal computer IP address.

Why would a business want to track my provider’s IP Address?

While a company doesn’t have access to your specific IP Address it still can be helpful information.

A company can learn the following information from an IP Address:

  • The name of the internet provider or the name of the company from which the user is attempting to communicate,
  • The city, subdivision (state, province, territory, etc) and country from which the request originates, and
  • When the connection originates from a computer on an internal network (aka intranet) within the business or from an external user or company on the world-wide-web (aka internet).

Each web site tracks the requesting IP Address in a log file. This information can be used to help diagnose and resolve web site communication issues. Each company can decide how far back to maintain the history of request and response messages to track. The log file simply records the date and time of the event, the IP Address and the success or failure of each request. The actual contents of the message are not recorded in the log. For details on this topic search “IIS Log Files”.

Can I stop them from tracking my IP Address?

The only way to stop a web site from recording your IP Address is to unplug your computer from the internet. Any attempt to communicate with another machine implies that the two machines have to know where the other is located so that the request and response messages can be sent. Anytime you are on the internet you have to accept the fact that there is a loss of privacy. But in this context it is no different than a phone. You have to know the phone number of the person you want to communicate with in the same way. And, yes, the phone company tracks the same information about your phone call connections as web sites track about web page requests. Look at your phone bill and you can see the information the phone company tracks. In reality, the phone is less private than a computer because the receiver has access to your phone number.

I am a programmer and I need this information!

Recently I needed the ability to identify when a message originated internally from another employee, externally from another employee or externally from another business or customer. This requirement could only be achieved by taking advantage of the IP Address. Internal IP Addresses usually begin with 10, 172 or 192. Any other number and the address is from the internet. When the address is external I needed to know which company owned the IP Address.

The code sample below has four public functions that provide the needed information:

  • ClientHostAddress: Returns the IP Address from the client machine (the company or internet provider gateway).
  • IsExternalAddress: Identifies when the client IP Address originates from the internet.
  • IsInternalAddress: Identifies when the client IP Address originates from the intranet.
  • ReverseLookup: Returns the name of the company or internet provider.

Note that this articles requires code from my Web Information post.

using System;
using System.Net;
using System.Text.RegularExpressions;
using System.Web;

public class NetInfo
{
    /// <summary>Get a value that indicates when the requestor is from an external, internet address.</summary>
    public static bool IsExternalAddress
    {
        get { return !Regex.IsMatch(ClientHostAddress.ToString(), @"^((((10)|(172)|(192))(\.\d{1,3}){3})|(::1))$"); }
    }

    /// <summary>Get a value that indicates when the requestor is from an internal, intranet address.</summary>
    public static bool IsInternalAddress
    {
        get { return Regex.IsMatch(ClientHostAddress.ToString(), @"^((((10)|(172)|(192))(\.\d{1,3}){3})|(::1))$"); }
    }

    /// <summary>Get the client host IP Address with the company domain or computer name when available.</summary>
    /// <remarks>Supports both IPv4 and IPv6 communication standards.</remarks>
    /// <example>
    /// <list>
    /// <item>Local Host Example = Address: ::1; Name: USERNAME.domain.com</item>
    /// <item>Intranet Example = Address: 72.185.239.20; Name: 72.185.239.20</item>
    /// <item>Internet Example = Address: 209.181.8.234; Name: d209-181-8-234.wispwest.net</item>
    /// </list>
    /// </example>
    public static string ReverseLookup()
    {
        var ip = WebInfo.InWebContext ? ClientHostAddress : null;
        IPHostEntry host = null;
        try { if (ip != null) host = System.Net.Dns.GetHostEntry(ip); }
        catch { host = null; }
        return string.Format("Address: {0}; Name: {1}", ip, (host == null) ? ip.ToString() : host.HostName);
    }

    /// <summary>Get original client IP Address.</summary>
    /// <returns>Attempts to locate the original requesting IP Address by traversing thru proxies. When none found then UserHostAddress (Remote_Addr) is returned.</returns>
    /// <remarks>Supports both IPv4 and IPv6 communication standards.</remarks>
    /// <example>
    /// <list>
    /// <item>Local Host Example = ::1</item>
    /// <item>Intranet Example = 72.185.239.20</item>
    /// <item>Internet Example = 209.181.8.234</item>
    /// </list>
    /// </example>
    public static IPAddress ClientHostAddress
    {
        get
        {
            foreach (var varKey in new string[] { "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED", "HTTP_X_CLUSTER_CLIENT_IP", "HTTP_FORWARDED_FOR", "HTTP_FORWARDED" })
                if (IsServerVariableIpAddressType(varKey))
                    return GetIpAddressFromServerVariable(varKey);
            return StringToIpAddress(WebInfo.Request.UserHostAddress);
        }
    }

    /// <summary>Get a value that indicates when the specified Server Variable contains an IP Address.</summary>
    /// <param name="key">A string value representing the server variable key to query.</param>
    /// <returns>Returns true when the server variable contains a valid IP Address; otherwise false.</returns>
    /// <remarks>Supports both IPv4 and IPv6 communication standards.</remarks>
    private static bool IsServerVariableIpAddressType(string key)
    {
        return StringToIpAddress(GetFirstValueFromServerVariable(key)) != null;
    }

    /// <summary>Get an IP Address from the specified server variable.</summary>
    /// <param name="key">A string value representing the server variable key to query.</param>
    /// <returns>The IP Address when the server variable contains a valid IP Address; otherwise null.</returns>
    /// <remarks>Supports both IPv4 and IPv6 communication standards.</remarks>
    private static System.Net.IPAddress GetIpAddressFromServerVariable(string key)
    {
        return StringToIpAddress(GetFirstValueFromServerVariable(key));
    }

    /// <summary>Returns the first value from the server variable using a comma for the separator.</summary>
    /// <param name="key">A string value representing the server variable key to query.</param>
    /// <returns>Returns the first value assigned to the server variable when availalbe; otherwise an empty string.</returns>
    private static string GetFirstValueFromServerVariable(string key)
    {
        return GetFirstValueFromServerVariable(key, ',');
    }

    /// <summary>Returns the first value from the server variable.</summary>
    /// <param name="key">A string value representing the server variable key to query.</param>
    /// <param name="separator">The char value that delimites the string list.</param>
    /// <returns>Returns the first value assigned to the server variable when availalbe; otherwise an empty string.</returns>
    private static string GetFirstValueFromServerVariable(string key, char separator)
    {
        return !string.IsNullOrWhiteSpace(WebInfo.ServerVariables[key]) ? WebInfo.ServerVariables[key].Split(',')[0] : string.Empty;
    }

    /// <summary>Attempts to convert the string value to an IPAddress object type.</summary>
    /// <param name="value">A string value representing the IP Address to convert.</param>
    /// <returns>Returns an instance of an IPAddress object when conversion is successful; otherwise a null value.</returns>
    private static IPAddress StringToIpAddress(string value)
    {
        if (string.IsNullOrEmpty(value) || value.Trim().Length == 0) return null;
        IPAddress ipAddr = null;
        return IPAddress.TryParse(value.Trim(), out ipAddr) ? ipAddr : null;
    }
}

Summary

In this article we learned how privacy and security are conflicting requirements. We learned that the internet is more private than postal mail and phone calls because companies don’t have direct access to our home computer address like the post office or people we call enjoy. And, for the tech-savvy developer we now have a new tool in our tool-belt to help us distinguish between internal and external connection requests.

Happy coding!

Advertisements

1 Comment »

  1. I’ve run into issues with this if IPv6 is enabled. I added a function that converts, using DNS, the WebInfo.Request.UserHostAddress to IPv4.

    Comment by Dwight Funk — June 4, 2015 @ 10:06 am | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: