Undocumented inconsistent CGI ColdFusion area / structure behavior

I originally posted this as an answer to this question earlier regarding Empty CGI.REDIRECT_URL at ColdFusion 2016 . Thinking about it, I thought about it better, since technically I did not answer the OP question. Instead, I decided to ask a separate question, although this is more a comment than a question. Although this may not technically meet the full requirements of a minimal, complete and verifiable example , and people can throw me downvotes, I decided that it still stands in the hope that it will become easier to find for future CFers that may run into this. Thus, preventing them from banging their heads on the wall regarding this peculiar behavior of the CGI structure / area.

With that said, the structure / region of the CGI has some undocumented inconsistent behavior of other structures / regions. Please note that I personally do not accept responsibility for this discovery, as it happened some time after I read this post on the Ben Nadel blog . So, all the information that I publish here is already described in detail there, but I wanted to write a good resume here on SO.

Undocumented behavior 1 - Unlike other structures, if a key element of the CGI structure does not exist, it will not cause an error when accessing it.

In the original OP) question, he wondered why cgi.REDIRECT_URL exists, but it is empty. As he eventually found out, he never existed. As a separate example, you can execute this line of code without throwing an error. Not what you expect, huh?

 <cfoutout>#cgi.THIS_IS_A_FAKE_KEY#</cfoutout> 

So what to do CFER? Check for a key.

 <cfif structKeyExists( CGI, 'THIS_IS_A_FAKE_KEY' )> THIS_IS_A_FAKE_KEY exists <cfelse> THIS_IS_A_FAKE_KEY doesn't exist </cfif> 

Undocumented behavior 2 - Unlike other structures, if you reset the CGI structure, it will not display all key / value pairs, it will display only a specific set of keys.

In the case of OP , it had a custom CGI Apache variable cgi.REDIRECT_URL , which was used in its code before upgrading to CF2016 and could refer to it directly. However, I assume that if he ejects the cgi structure, it will not appear in the dump. In the case of Ben Nadel , he also had a custom cgi variable called cgi.document_root , which was passed from the load balancer and was able to refer to it directly, but he also could not see the key when dumping the cgi contents.

So what to do CFER? Understand this and keep it deep down so you don't bite when you dump the contents of cgi and the key / value pair does not exist. Other than that, no more.

+5
source share
2 answers

I entered the cfusion.jar ColdFusion file. What I found was a bit confusing.

The CGI domain does not have a form of hope that can be hoped for.

Here's how the CGI variable call is handled. e.g. <cfoutout>#cgi.THIS_IS_A_FAKE_KEY#</cfoutout>

  • The normal valid CGI scope variables are those on this list, and by default they will be initialized to "" .

     private static final String[] names ="AUTH_PASSWORD","AUTH_TYPE","AUTH_USER","CERT_COOKIE","CERT_FLAGS","CERT_ISSUER","CERT_KEYSIZE","CERT_SECRETKEYSIZE","CERT_SERIALNUMBER","CERT_SERVER_ISSUER","CERT_SERVER_SUBJECT","CERT_SUBJECT","CF_TEMPLATE_PATH","CONTENT_LENGTH","CONTENT_TYPE","CONTEXT_PATH","GATEWAY_INTERFACE","HTTP_ACCEPT","HTTP_ACCEPT_ENCODING","HTTP_ACCEPT_LANGUAGE","HTTP_CONNECTION","HTTP_COOKIE","HTTP_HOST","HTTP_USER_AGENT","HTTP_REFERER","HTTP_URL","HTTPS","HTTPS_KEYSIZE","HTTPS_SECRETKEYSIZE","HTTPS_SERVER_ISSUER","HTTPS_SERVER_SUBJECT","LOCAL_ADDR","PATH_INFO","PATH_TRANSLATED","QUERY_STRING","REMOTE_ADDR","REMOTE_HOST","REMOTE_USER","REQUEST_METHOD","SCRIPT_NAME","SERVER_NAME","SERVER_PORT","SERVER_PORT_SECURE","SERVER_PROTOCOL","SERVER_SOFTWARE","WEB_SERVER_API" };` 

    Also, all these values ​​also come from various java libraries javax.servlet , HttpServletRequest , etc.

  • If the requested variable is not one of them after several checks, ColdFusion goes to the request headers. You can see them with getHttpRequestData().headers . Then it searches for the key there with hyphens ( - ) instead of the underscore ( _ ) in the cgi key request. (If the key starts with http_ , then the key in the request headers will be absent, as this http_x_forward in the request header will be x-forward )

     value = request.getHeader(name.replace('_', '-')); 

From what I understand about ColdFusion, the keys mentioned in the first paragraph are recognized as part of the CGI domain. But when there is additional information transferred from the Apache load balancer server to ColdFusion, they fall into the request headers. Since java getHeader simply returns an empty string (or something with an undefined data type) instead of an undefined error, ColdFusion does not determine which key is defined or not .

So, if the key THIS_IS_A_FAKE_KEY sent to ColdFusion from an intermediary, such as an Apache server. You will find this in getHttpRequestData().headers['THIS-IS-A-FAKE-KEY'] , but not on a dump of the cgi .

It seems to me that my personal opinion is that it is better to check directly in getHttpRequestData().headers for custom CGI variables, except in the scope itself.

+7
source

EDIT . Thanks to Ageax, to indicate one of my test cases was incorrect in my previous version of this post.

Great detective work RRK! Therefore, I decided to conduct an experiment to test your discovery by creating two cycles. The first cycle displays the key / value pairs from getHttpRequestData().headers , and the second cycle does the same, using the corresponding key / value pairs from the cgi , replacing it with _ . Voila! as RRK reports, we can see how you can get the values ​​using any of these methods. I made an updated gist and posted here for anyone interested.

 <cfset httpHeaders = getHttpRequestData().headers> <h3>getHttpRequestData().headers</h3> <cfloop collection="#httpHeaders#" item="key" > <cfoutput><strong>#Key#</strong> : #httpHeaders[key]#<br></cfoutput> </cfloop> <h3>cgi keys dash to underscore</h3> <cfloop collection="#httpHeaders#" item="key" > <cfset keyUnderscore = replace(key, "-", "_", "all")> <cfoutput><strong>#keyUnderscore#</strong> : #cgi[keyUnderscore]#<br></cfoutput> </cfloop> 
+7
source

Source: https://habr.com/ru/post/1275366/


All Articles