Use cgi.server_name? Be careful
So I just had a random, stray thought. One thing I've done in the past is sniff the current server to determine behavior aspects of my site. So for example, my error handler may do something like this:
<cfif findNoCase("dev.", cgi.server_name)>
<cfdump var="#exception#">
<cfelse>
<p>
Something went wrong. Quick - reboot the Tandy.
</p>
</cfif>
While this works nice, I just ran across a problem with it. If you hit this file on my site:
http://www.coldfusionjedi.com/test4.cfm
You will see I print out cgi.server_name. Now if you go into your HOSTS file and do:
67.59.153.214 baloneypants.com
And then hit the file with:
http://baloneypants.com/test4.cfm
You will notice that the CGI variable now says baloneypants. No big surprise there I guess. But obviously if I knew your code did this, and if I added dev.x.com for x.com, I could use it as a way to "sniff" out differences based on that CGI variable.
Unfortunately I can't think of a nice solution. Sniffing the servername is a handy way to dynamically load settings based on environment. If you can't trust cgi.server_name than you need to do something else - like perhaps sniff something on the machine itself.
Any suggestions?
Comments
Additionally, I think there are commands that you can execute from the command line that will tell you what host you are on but they too are dependent on OS.
<cfset inet = CreateObject("java", "java.net.InetAddress") />
<cfset hostName = inet.getByName(inet.getLocalHost().getHostAddress()).getHostName()>
<cfoutput>#hostName#</cfoutput>
IIRC, you'll return the machine name back. I just tried it on a server that uses Apache virtual hosts and it returned servername.host.com which is the machine name.
I ran into this issue when using SSL on a cluster. I wanted to switch to https when doing a user login, then back to http upon success, for performance reasons. I figured I could construct the URL using cgi.server_name, cgi.script_name, etc, but no dice. Eventually, I stored the server name that I wanted to use in an XML file and loaded it as part of the configuration, then constructed the URL using that name.
I think I read somewhere a while back that as a security practice, you should prevent direct access to your web site's IP address if you can.
<cfsavecontent variable="application.ServerName"><cfinclude template="/shared/server_name.txt"></cfsavecontent>
So expandPath('/../sites/orders.ini') goes down below the site root and then back up into the sites folder.
This lets me place sever/site specific information there where it won't get clobbered by site file updates, syncs, and so on. It's also outside of the site root so it can't get downloaded by potentially malicious users.
This way, if you tried to access the server by IP or a spoofed URL, you would get the standard browser login and would be denied access.
Then, we would create separate web sites with explicit host names defined which would respond only to the valid domains.
This worked rather well, and I noticed a decrease in hack attempts since most malicious attacks are targeted at IP addresses.
I know this approach can be done in Apache and Sun One as well.
I use source control on the config files, but only for a _template_ of the config file, with sensitive details (like passwords, etc) that I wouldn't want in the repository, removed.
So if my config file is config.xml, I'd have a config-template.xml in the repo. Then server backups keep me safe from losing the exact settings on the server.
This is nice, because usually right before I deploy to production, I want to run the app completely in production mode, but before I put it ON the production server.
And a nice compromise between the two approaches... I have many times had a "Mode" setting as one of my configs, with either a "Production" or "Development" value, so I just have a cfif application.mode is "Development" condition for places where I want my cfdumps.
Just some thoughts.
serverName = CreateObject("java", "java.net.InetAddress").getLocalHost().getHostName();
@Peter +2
:)
Yours has an extra couple method calls I don't think you need
On a Windows host cfregistry can get you the machine name, which is alright if you can guarantee your code will always run on a windows box.
-
Maybe I'm in the minority, but I can't imagine cfregistry being enabled on a production environment? That scares me heh.
At any rate, it's an easy way for me to tell what environment I'm in without having to rely on URLs.
<cfscript>
host = CreateObject("java", "java.net.InetAddress").getLocalHost().getHostName();
cfserv = createObject("java","jrunx.kernel.JRun").getServerName();
</cfscript>
if cfserv contains 'dev' or 'test' or 'staging' I know I'm not on a production box; if host contains 1 or 2 I know which box in the cluster I'm on.
We've generally been using coldspring and modelglue for our newer sites. Our controllers are managed by CS and use the ModelGlue.Bean.CommonBeans.SimpleConfig class. In the application.cfc we set up a parent bean factory for MG. Then, in the controllers, there is a setBeanFactory method which also pulls the configuration bean so it is available throughout the application.
We also use ANT build scripts that can deploy to different environments.
<code>
<cfif FileExists("C:\dev.txt")>
<cfdump var="#exception#">
<cfelse>
<p>
Something went wrong. Quick - do a 'LOAD "*",8,1'.
</p>
</cfif>
</code>
I think someone else further up the list mentioned this as well.
