5 Replies Latest reply on Aug 17, 2011 5:57 AM by djarab3la

    proxy detection and cgi variables

    djarab3la

      Just want to ask you about something that is bothers me, For few weeks i have a strange situation for one of my projects for which my client insists that project should have a proxy detection mechanism in order to deny access to those visitors who's landing into website from behind a proxy server.

       

      Theoretically i know how to handle this; parsing browser request headers values in searching for specific proxy headers like:

      1. for normal transparent proxy it is enought that
      HTTP_X_FORWARDED_FOR exists.
      2. for anonymous and high-anonymous would be:
      HTTP_X_FORWARDED_FOR, HTTP_VIA, HTTP_X_PROXY_ID

      So, i put a proxy address in my browser and access a simple page that

       

      only dumps cgi scope variables.

       

      (<cfdump var="#cgi#" label="cgi variables" />

       

      But, no luck. None of those values from above seems to show up althought i see that remote_addr shows me the ip of proxy server confirming me that i use a proxy.

       

      So code like:

       

      <cfif IsDefined("CGI.HTTP_X_FORWARDED_FOR") AND CGI.HTTP_X_FORWARDED_FOR NEQ ''>

        proxy detected

      <cfelseif IsDefined("CGI.HTTP_VIA") AND CGI.HTTP_VIA NEQ ''>

      high-anon proxy detected

      <cfelse>

        you are clean

      </cfif>

       

      would not have any chance. I have used this simple line of code into ACF 7 MX (with apache 2.0.53 - mod_jrun20.so)  or into my laptop to ACF 9 developer edition ( with apache 1.3.41 mod-ssl / mod_jrun.so - calling page from another pc in the same network).

       

      Funny thing is that a php page via normal apache vhost gives me those variables leading me to think that it might not be an apache problem or at least i can not see it.

       

      srv#cat testp.php
      <?php
      if(isset($_SERVER['HTTP_X_FORWARDED_FOR']) ||
      ($_SERVER['HTTP_USER_AGENT']=='') || ($_SERVER['HTTP_VIA']!='')){

      die("Don't use proxies, please.");

      }

      ?>

       

      am i missing something? those $_SERVER variables from php does have other corespondent into ACF ?

       

      thanks very much for anybody time.

        • 1. Re: proxy detection and cgi variables
          Adam Cameron. Level 5

          The thing you're probably missing is how CGI variables are documented to work:

          http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-77 85.html

           

          CFDUMP only dumps a fixed list of common CGI variables, and all CGI variables always return "true" for isDefined() and structKeyExists().  This is stupid, but it's the way CF has always been.

           

          What you need to do is to test the LENGTH of the CGI variable you're thinking of using.

           

          --

          Adam

          1 person found this helpful
          • 2. Re: proxy detection and cgi variables
            djarab3la Level 1

            Hi, Adam

            Thank you very much for your tip. I have tried as you have suggested but still no luck.

             

            <cfif Len(cgi.HTTP_X_FORWARDED_FOR) NEQ 0>
                    proxy detected
            <cfelseif Len(cgi.HTTP_VIA) NEQ 0>
                    anon proxy detected
            <cfelseif Len(cgi.HTTP_CLIENT_IP) NEQ 0>
                    anon proxy detected
            <cfelseif Len(cgi.HTTP_PROXY_CONNECTION) NEQ 0>
                    anon proxy detected
            <cfelse>
                    it is ok
            </cfif>
            <br /><br />
            <cfoutput>
            Len of cgi.HTTP_X_FORWARDED_FOR is: #Len(cgi.HTTP_X_FORWARDED_FOR)# - #Left(cgi.HTTP_X_FORWARDED_FOR, 15)#<br />
            Len of cgi.HTTP_VIA is: #Len(cgi.HTTP_VIA)#  - #Left(cgi.HTTP_VIA, 10)#<br />
            Len of cgi.HTTP_CLIENT_IP is: #Len(cgi.HTTP_CLIENT_IP)# - #Left(cgi.HTTP_CLIENT_IP, 15)#<br />
            Len of cgi.HTTP_PROXY_CONNECTION is: #Len(cgi.HTTP_PROXY_CONNECTION)# - #Left(cgi.HTTP_PROXY_CONNECTION, 1)#<br />
            </cfoutput>

             

            I have put a print-screen of my test page at:

            http://www.thinktwice.ro/cgitest.jpg

             

            thanks

            best regards

            • 3. Re: proxy detection and cgi variables
              Adam Cameron. Level 5

              Dunno in that case mate, sorry.  I'm not too au fait with (or indeed "at all au fait with ~") the ins and outs of proxy servers and how CF's CGI variables are populated.

               

              :-(

               

              --

              Adam

              • 4. Re: proxy detection and cgi variables
                djarab3la Level 1

                Hi Adam, do not bother it is not the end of the world

                 

                I have some experience with squid proxy server so that i did take another way. Also i have posted into coldfusionjedi.com too (last night).

                 

                So, if i can not access header values for those variables via cgi dump  or via checking length of them what if we reverse the process ? We still have access to remote_addr  and remote_host values. Now, i just want to test if remote_addr ip it is  a proxy or not. How ? Trying to connect to it. Remember that a proxy  server must accept connection, right ? Well...

                 

                <!-- define function to check connection; it will return true or false if it could connect or not --->
                <cfscript>
                function checkMe(host,port) {
                connection = createObject("java", "java.net.Socket");
                connection.init(host, port);
                connected = connection.isConnected();
                return connected;
                }
                </cfscript>

                 

                <cftry>
                <cfoutput>
                <!--- define a variable whitch hold remote address and a variable for counting open ports --->
                <cfset ip="#CGI.REMOTE_ADDR#" />
                <cfparam name="q" default="0" />

                 

                <!--- checking remote ip connection within well-known range of ports --->
                <cfif checkMe(#ip#,80)>
                <cfset p1 = true />
                <cfset q = 1 />
                </cfif>

                 

                <cfif checkMe(#ip#,8080)>
                <cfset p2 = true />
                <cfset q =q+1 />
                </cfif>

                 

                <cfif checkMe(#ip#,3128)>
                <cfset p3 = true />
                <cfset q =q+1 />
                </cfif>
                </cfoutput>

                 

                <!--- here leave empty in case this is not a proxy not to show anything --->
                <cfcatch type="Any">

                 

                </cfcatch>
                </cftry>

                 

                <!--- display and parsing the results it is very basic in order to see on which port remote ip accept connection; only for debug
                --->
                <cfoutput>
                <cfif IsDefined("p1")>
                proxy on port 80: #p1#<br />
                <cfelse>
                no proxy on port 80<br />
                </cfif>
                <cfif IsDefined("p2")>
                proxy on port 8080: #p2#<br />
                <cfelse>
                no proxy on port 8080<br />
                </cfif>
                <cfif IsDefined("p3")>
                proxy on port 3128: #p3#<br />
                <cfelse>
                no proxy on port 3128<br />
                </cfif>
                </cfoutput>

                 

                <!--- then just logical detection which is it on top of any page or onRequest() from Application.cfc--->
                <cfif IsDefined("variables.q") AND variables.q NEQ 0>
                <h2>No proxy allowed here, mate!</h2>
                <cfelse>
                <!--- normal processing page code as visitor it is not using a proxy --->
                </cfif>

                 

                Obviously  this method could be more elaborate incorporated into a CFC where to  just pass only CGI.REMOTE_ADDR and wait for a boolen answer.

                 

                Downfall of this would be in case of proxy detected on port 80. Because if a visitor cames from a NATed linux gateway where on that linux gw is running an web server on port 80. maybe there is a chance to use

                q = createObject("java", "java.net.InetAddress") -> getByAddress(#CGI.REMOTE_ADDR#).. ??

                to be sure it is a client ip address and not server one.

                 

                thanks again for your time

                best regards

                • 5. Re: proxy detection and cgi variables
                  djarab3la Level 1

                  or just better one:

                   

                  from

                  <!--- then just logical detection which is it on top of any page or onRequest() from Application.cfc--->
                  <cfif IsDefined("variables.q") AND variables.q NEQ 0>
                  <h2>No proxy allowed here, mate!</h2>
                  <cfelse>
                  <!--- normal processing page code as visitor it is not using a proxy --->
                  </cfif>

                   

                  to:

                  <!--- then just logical detection which is it on top of any page or onRequest() from Application.cfc--->
                  <cfif IsDefined("variables.q") AND variables.q NEQ 0>
                  <h2>No proxy allowed here, mate!</h2>

                  <cfabort/>

                  </cfif>