-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 John,
On 7/25/15 9:03 AM, John Baker wrote: > Hello, > >> Anything in particular? Plumbing code is always not terribly >> pretty. >> >> It's kept up-to-date and generally supports more features than >> mod_proxy_ajp. > > Well, there was a point where 64bit windows builds didn't even work > - which tells me there's not a lot of testing going on. I'm not sure how long ago that was, but I don't live in the Windows world. I would have thought that someone at Apache Lounge would have balked if a release was broken. Were you building a release version, or trunk? > And having got involved and contributed a few years ago, I recall > the code being somewhat in need of refurbishment, as does pretty > much all 15+ year old C/Java/.... Last time I checked, C code pretty much compiled the same way it did 25 years ago. I don't see a particular need to go in there and change a whole lot of stuff. Are there more efficient ways to dereference pointers these days? Is all the new-fangled stuff compatible with APR and httpd? >>> I see your point regarding the ajp protocol but equally, HTTP >>> is everywhere and if every other part of a web stack is HTTP, >>> there seems little value in doing anything different between >>> Apache & Tomcat. >> >> There are some slight optimizations in comparison to AJP. When >> HTTPS/2 (which is very much like AJP) hits, you'll see less of a >> difference. > > I don't think there's any good reason to use AJP over HTTP with > respect to web performance. Pretty much any bottleneck exists in > the application, or the plethora of components it uses, not the > transport layer. Agreed. > AJP is merely obscuring a request that in many (commercially > deployed) solutions originated from a device with a number of > other solutions in-between it and Apache/IIS, ie the F5, an Akami > layer, BlueCothe protocol that one can't get away from; that > everyone understands and can easily debug with telnet/etc)at, etc. Nobody is making anyone use AJP. But it does offer a side-channel that allows information like HTTPS client to come across in a way that won't be confused with HTTP request headers. HTTP doesn't offer anything like that, of course, so some other mechanism would have to be invented. Probably some meta-information passed-through in HTTP headers. It would work, but it would be a pain, and it would be more difficult to hide those implementation details from the application. >>> AJP has various load balancing features/etc and if that's what >>> one wants, fine, but most organisations have hardware load >>> balancers etc to do this for them now-a-days. >> >> Also, mod_proxy_* does load-balancing. This is not a feature of >> the protocol, but of the tool. > > Yes, I appreciate that, but mod_proxy/mod_jk LB is not used in your > day to day commercial solution that - rightly or wrongly - > consider Apache/Tomcat as one (often, people don't even know the > difference!) and do the load balancing in the corporate wide > solution. I'm not sure I agree with that, but it's largely irrelevant either way. >>> Going back to my request, I note the Servlet Specification API >>> docs state that getRemoteUser should return the CGI variable >>> REMOTE_USER: >>> >>> http://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/htt p/ >> >>> HttpServletRequest.html#getRemoteUser() >>> >>> But as I've highlighted, it does not, so Tomcat is in breach >>> of the spec. How can this be raised as a bug? >> >> REMOTE_USER is not an HTTP header... it's the "REMOTE_USER" CGI >> variable > > Yet they are used interchangeably. Are they? I've never written a Perl script that expected to find REMOTE_USER in the HTTP request headers, and I suspect nobody else has, either. > And we're not discussing mod_[fast]cgi, but a completely different > architecture/solution. Right, and so the rules are a bit muddy. >> So, your proposed implementation is incorrect and represents a >> security vulnerability. > > It does not represent a security vulnerability. Sure it does: a client can supply a forged REMOTE_USER header quite easily. > Any application that trusts a user via REMOTE_USER, whether via > the HTTP or AJP connector is doing so knowingly. And in such a > case, a pen-test would fail unless there were extra measures in > place (Tomcat's AJP or HTTP connector listening on localhost; > restricted access to the host), but they are no substitute for > authenticating within Tomcat. So, how is Tomcat supposed to know that the request has been properly-sanitized? At least with AJP, one expects that a nearby web server is making the request and that the user knows what they are doing. Nobody sets up a one-box-wonder in production with the AJP port publicly available. But people do that all the time with port 80 available publicly. > Apache authenticating on behalf of Tomcat is a bad decision, but a > decision still forced upon some because of vendors not providing > Java authentication solutions out of the box (ie CA SiteMinder, RSA > Access Manger, Tivoli, etc). If the vendor pushes and only actively > supports an Apache front end, one has to use an Apache front end. > > Setting up mod_proxy_http is easier than mod_[proxy_]jk. Everyone > understands HTTP, and I'd like Tomcat to more easily integrate > with Apache (and the various authentication modules) using HTTP. Okay, so what does the metaprotocol over HTTP look like? You just want to take an HTTP header confusingly called REMOTE_USER and use that as your user principal? No problem: write a Valve that does that and insert it into your Valve chain. Problem solved. Should Tomcat support this directly? Well, it does so for the AJP connector as you point out (albeit using a different technique... specifically, it doesn't use HTTP headers), so perhaps it's appropriate to extend that support to the HTTP connectors. Care to file a Bugzilla enhancement for that? I don't like your proposed implementation, but that doesn't mean that it could work similar to the way you've described it. For one thing, it should be a configuration option that is off *by default*. >> Tomcat is compliant insofar as there is no standard that covers >> where the REMOTE_USER CGI variable should be set or what its >> value should be. When a user is logged-into a web application, >> request.getRemoteUser returns the name of the >> currently-logged-in user. When no user is logged-in, it returns >> null. That seems to be compliant to me. > > Well, admitting there's no standard and then stating is compliant > is an interesting conclusion :) What I'm saying is that Tomcat is compliant with the Java Servlet spec which only refers to CGI environment variables. Since those don't really exist, the references to those are more informational than normative. HttpServletRequest.getRemoteUser should return what you'd normally expect to be in the REMOTE_USER CGI environment variable. Since Tomcat does its own authentication, there is no such variable, but the semantics are pretty much what most people would expect: calling that gets you the username of the currently logged-in user. As far as Tomcat is concerned, there is no currently logged-in user in your case, so it's behaving consistently with the specification. >> How do you want it to behave instead? > > It should be consistent with the AJP Interface. Either they both > return a user on getRemoteUser() or they don't. The > tomcatAuthentication flag on the AJP connector tells Tomcat to > trust the REMOTE_USER header/CGI variable/whatever we wish to call > it. With a simple change to the HTTP connector, it can do the same. > Rename REMOTE_USER to X_UNTRUSTED_USER if you wish, but this no > more or no less secure than the AJP connector because one has to > 'opt in' to the security issue. I would agree that the "tomcatAuthentication" setting should be supported on other connectors, but you'll also have to make sure that the client (e.g. mod_proxy_http) either natively knows how to proxy those values over the connection or use something like mod_headers to do it. What I'm trying to say is that this isn't merely a failing of Tomcat's connectors: you'll have to do some work on the httpd side already, because "REMOTE_USER" is not, as far as I know, automatically sent via mod_proxy_http to the origin server as an HTTP header. You'll have to make that happen yourself. > I would also like to see Tomcat reporting the obvious security hole > when this approach is used (for either AJP or HTTP) by reporting to > the logs if the connector is not bound to localhost/etc. I'm amazed > at how often I find Apache+Tomcat deployed with zero security on > the AJP connector and no-one appearing to understand the issue. Just "localhost"? What about "127.0.0.1"? "::"? Aliases of "::"? 192.168.x.y? 10.x.y.z? 172.x.y.z? How many things should be white-listed, or should you be required to set not only the "tomcatAuthentication" flag but also the "shutUpIKnowWhatImDoing" flag? >> If you want to have the web server report the REMOTE_USER CGI >> variable to Tomcat, you'll have to arrange that for yourself. > > And indeed it's not hard to do so, but if one wants to get rid of > AJP and stick with pure HTTP, then a Tomcat Valve is required to > set the Principal when REMOTE_USER is passed as an HTTP header from > Apache. It's an extra level of effort that people can do without. Fair enough. > So in summary: > > * There's no security issue with my proposal above and beyond what > is already considered an issue with AJP. One caveat: (a) if the web server is not configured correctly, this is a security vulnerability and (b) if Tomcat is publicly-reachable, then this is a security vulnerability. (Note that the same is true with a publicly-accessible AJP port). > * Tomcat should provide much more informative reporting when > security issues are opened up through the use of AJP and > tomcatAuthentication="false". Well, the use of AJP should be irrelevant, if the connectors are to have feature-parity. > * If we really don't like the idea of getRemoteUser() returning > REMOTE_USER (set as an HTTP Header or provided by mod_jk) then > maybe a Valve can be included by default that wraps up both the > logging and functionality (I'm happy to write it). I think this might be more easily coded at a higher level, though a Valve in the meantime would suffice. - -chris -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIcBAEBCAAGBQJVtqGgAAoJEBzwKT+lPKRYLfoP/iw2V1XCUeUKIngZ4lBsIFuc 8dOq3avRfKAaY+pf8aXVEDMramsqwrn9QDLFhBzhAhj4kj1uSMXKZHa4xbF1Cqgl F0/pI+/xNbYUw0mTounetMFR7xOkjjsOUwUmSiY0bExVdLTvmWRSO8ECwe+0dDr5 cjuwUKZj1MI31VWe9YlZqAcRnlulGrk4FwW1rPXKWU31OyKuFLCYrCWt76LSO674 5MUFX7/LimP6V+rQHUIQ3wsUh8rxUti333tl9h0Qk1hPtaMOXC5h/s+eEHTKC+bw ZE1i41sQPTSkzbrgO+URWWIpOEDEOvNFgjdTlOYtspe6NN0OeHHN4NYK0dlaJ9kb cpQP5IKt0ZhcP+jCd7gS5+eN0l8WlYPCBHXhoOKWG8hwTq/XIKxLkp3LXOG8Dkba mksAnrm07OZynevmi6LKJL1j3r5ksIBw4/pI7UurzBiomo+iRTiMD8BjDYqpgEu2 cTFjoB4Dsb5zV8Ls3/XmwlXoLHsHw9+QmUz/sLJkzlS3pdMNORUMALRYKcFzvyLd F3qfXplips4fUYIIK+4k+xnCLapSZPQv6Ee5h5mBUXwmmFwlmszjckE7t3ZjWegN g1isZAtjuw23vnXrNT/8x00x7UM0umBWqFpzj0IQhMF2SCt6q5eed6jjQUNjY5MT V5D9gqOTUU1clqr8Gj83 =9cBj -----END PGP SIGNATURE----- --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org