For about 4 years now we've had a Docker productio...
# box-products
s
For about 4 years now we've had a Docker production swarm with a (non-Docker) NGINX in front. We cannablized some Ortus NGINX configs that would relay the 'actual' IP address in use to Lucee and this always 'just worked.' With one of the recent Commandbox updates (or else one of the more recent Lucee updates), around May 12,
cgi.remote_addr
is now the local network address of NGINX. for everybody
l
@bdw429s
b
Read the release notes 🙂
The section titled
X-Forwarded-For support disabled by default
@sknowlton @lmajano
s
I ain't never read no release notes befores and I sure as tarnation ain't gonna start now
😆 4
thank you. 🙂
👍 2
b
I don't like "breaking" changes in a minor release, but I make exceptions for security issues and just try to document them
s
unfortunately it coincded with a crap ton of esignature stuff we began doing right around then
just noticed it now
please add a prompt that detects me and forces me to read release notes
1
b
That could actually be a nice "post upgrade" feature to output a link in the console 🤔
A "what's new" sort of thing
s
we actually would still miss it because I just
docker pull ortussolutions/commandbox
and then our build process does the rest
👍 1
We don't pin to specific Docker images because we've never really had to
b
True, when it's just an ingredient buried in the sausage, it can slip in undetected.
t
I am english and at this point demand an "oh ah mrs" please refer to keneth wiliams as an RTFM
😆 1
w
So what’s the extra security here?
X-Forwarded-For support disabled by default
Just out of curiosity, what’s commandbox doing with this header?. I assume it is always passed from your proxy and available in your lucee instance behind the proxy. Is it fully blocked and not available anymore if you do
useProxyForwardedIP=false
? Not sure what the status is now, but there are quite some scenario’s where at least TWO different sources are trying to set a
X-Forwarded-For
header. For example we had a situation where both nginx and haproxy were trying to set this header. This resulted in a comma delimited string of ipadresses, so don’t think you are safe if you just trust the value set by your loadbalancer. A similar scenario can happen if you use some WAF or content delivery network.
s
It's populating the
remote_addr
value in the CGI scope with it. If
useProxyForwardedIP
is false, then the value is the 'actual' remote address ... of the proxy.
The frustrating thing about this is that it's only a security issue if you aren't already using it
Because if you are, then whatever the client is trying to spoof you with is going to get overwritten by nginx/haproxy/whatever
w
ah ok. So you are relying on something populating the remote_addr. We did this with some nginx and apache setup as well in the past, not specially related to cf. But in CF it was always different
we stole this snippet from cbsecurity
Copy code
string function getRealIP(){
        var headers = getHTTPRequestData( false ).headers;

        // When going through a proxy, the IP can be a delimtied list, thus we take the last one in the list

        if ( structKeyExists( headers, "x-cluster-client-ip" ) ) {
            return trim( listLast( headers[ "x-cluster-client-ip" ] ) );
        }
        if ( structKeyExists( headers, "X-Forwarded-For" ) ) {
            return trim( listFirst( headers[ "X-Forwarded-For" ] ) );
        }

        return len( cgi.remote_addr ) ? trim( listFirst( cgi.remote_addr ) ) : "127.0.0.1";
    }
s
woof, I don't want to be doing this in CF. that's what nginx is for
w
If you are in full control, yes I agree. But not every hosting company knows what they are doing, and it is quite simple to add. When I still owned a hosting company we had to tell customers how to get the real ip, because they hardly realized there was some proxy/loadbalancer in front of it. In those cases we still had to do some tricks to add the real ip in cgi.remote_addr. Not always fun, sometime adding extra modules to apache etcetera. It has become a lot easier nowadays. (I’ve done that work 20+ years…not anymore)
s
for sure, after nginx I hope to never see IIS or Apache again
b
So what’s the extra security here?
I'm not sure what "extra security" means 🙂 but it's more secure by default. Say, you configure your CF administrator, a server rule, or some code in your CF application to lock down access to a feature based on the IP address of the incoming request. If your server is not in front of a proxy which overrides the x-forwarded-for HTTP header, a hacker can simply set their own header that claims to have been forwarded on behalf of
127.0.0.1
and they just bypassed half of the IP-based restrictions out there.
So, since an x-forwarded-for header comes from whatever upstream client sent the HTTP request, it can only be trusted if you trust the upstream client (like a proxy you control).
Therefore, CommandBox will no longer trust the upstream client unless you tell it to trust it. You can always run the code you showed above and it will work just fine. But the behavior of actually swapping out the remote IP to be the IP that was proxied is disabled, which affects what you see in
cgi.remote_addr
w
I understand the security stuff. It it should really be secure you need more, not only some remote_addr or x-forwarded-for. Too easy to spoof