Mass exploitation of Atlassian Confluence CVE-2021-26084
twitter.com
twitter.com
Only applies to public servers... Still should patch, but not as critical.
> Our Securities Team has since reviewed the wording on the Confluence Security Advisory CVE-2021-26084 - OGNL injection - 2021-08-25 and have removed the ambiguity generated by: The vulnerable endpoints can be accessed by a non-administrator user or unauthenticated user if ‘Allow people to sign up to create their account’ is enabled. To check whether this is enabled go to. There are additional endpoints identified that still expose Confluence to the CVE-2021-26084 Confluence Server Webwork OGNL injection and applying the workaround script will assist in temporarily mitigating against all known vulnerable endpoints until the application is upgraded to the fixed version. The temporary workaround script must be run even if Confluence Administration > User management > User Signup Options > Allow people to sign up to create their account is not enabled.
https://github.com/httpvoid/writeups/blob/main/Confluence-RC...
It isn't quite as stupid as they just executed code blindly, and this also highlights the difficulty of this approach. It is extremely difficult to get this approach to work correctly, to the point that it's probably reasonable to just treat it as impossible and reject it.
It is also likely that "they" is actually at least two sets of people; one who invoked this evaluation code on the "queryString" variable, and another who created the evaluation library, and these are probably not in the same company because it reads to me like this code evaluation is part of a external-to-Atlassian library. Would appreciate confirmation or denial of that from people more familiar with the Java ecosystem than I am.
And that further highlights the difficulties of maintaining, or indeed even communicating, security dependencies across entities like that. I suspect that whoever wrote $!queryString, either didn't really understand what that ! was doing, or assumed that behind that ! was some sort of safer kind of execution than turned out to actually be there. (It would be interesting to know if Atlassian needed to do anything else to deal with the fact this is technically an API change, or if the ! was never necessary in the first place.)
Upshot, I wouldn't call this "one dumb mistake, obviously never execute user input lol", it looks to me like a serious of issues crossing between many subsystems and probably several entities. I'd call this less obviously a problem with a particular developer or Atlassian per se, and rather more of a good demonstration of the sort of pervasive, systemic issues we face trying to keep things secure in a world of imperfect developers trying to wrangle hundreds of thousands and millions of lines worth of code and keep it secure. As I examine this I'm finding my reaction is less "lol" and more a sobering reminder of how little it takes to screw up this badly and how hard this can all be.
Programming is just so much easier when you don't need to worry about security.
The dubious sanitizing looks pretty bad, though. At bare minimum, Confluence should be executing in a sandbox that doesn't allow to call the exec method on the runtime instance. I can't imagine why Confluence would ever need shell access. Pretty good reason to run self-hosted Confluence in a distroless container with access to nothing but a JVM and whatever config files it requires.
A scarier thing is I believe Confluence, and all Atlassian products, store their DB credentials in a plain-text .properties file with a well-known standard path. Instead of trying to get a shell, this code could have just tried to read the expected path and print out the contents and it's pretty likely you could get a raw connection to the Confluence database.
I don't use Java to be familiar with how the underlying OGNL library does things; it's obviously there to make property access patterns and chaining on objects easier within template languages. But I think a thing like this is easy to pass a code review because the difference between $ and $! is minimal. If it had a name like eval it would be easier to spot and make a reviewer think for a second. That would be more likely to be caught even in an environment where there is the pressing urge to push out code fast.
I can only assume that a developer that is not in a hurry could have done something like (inventing Velocity template syntax here)
$someobject.handle($queryString)
Where the underlying object associated with $someobject has a handle method with a switch statement that based $queryString values does the proper property chain access. As much as PHP is harped on so often, this was the most important lesson PHP developers had to learn early, to run a switch statement on query strings when including files. (in the days before routing was a solved problem)https://confluence.atlassian.com/doc/confluence-security-adv...