Open lambdafu opened 2 months ago
Thanks for the report, I'm looking into it.
It's worth observing that, even though we do reflect limited html contents in an IMAP tag, we at least won't reflect one with a trivially useful payload, because ()
aren't valid in IMAP tags:
* OK [CAPABILITY IMAP4rev1 IMAP4rev2 AUTH=PLAIN AUTH=LOGIN ENABLE ID LITERAL+ SASL_IR] debian Cyrus IMAP 3.11.0-alpha0-891-ga30e9a7cd server ready
<script>attack()</script> noop
* BAD Invalid tag
Thanks for looking into it! As for the payload, I'm not an expert, but if I google "xss bypass parenthesis" I get several pages with suggestions how to avoid parenthesis in XSS payloads. For example, this worked in courier:
<script>alert`XSS`</script> xxx
But I did not do extensive testing. Just wanted to point that out.
Sure, thanks, that's really appreciated. I did my own search and found a few interesting ways to inject a function call that from an untested visual examination I think would be valid tags according to the IMAP spec. So I'm thinking about violating the spec in order to be more restrictive in the tags we'll accept -- though that will take some care because I don't currently know what kinds of tags real IMAP clients are actually using.
So far I'm thinking of rejecting:
<
, >
, :
, maybe some carefully chosen others, perhaps even just any non-alphanumeric. This would prevent the reflections containing <script>
, and trivially treat HTTP headers as invalid commands (which I anticipate combining with a limit on consecutive invalid commands, after which the connection is dropped)POST
, PUT
, maybe some others -- any HTTP request method that takes a body I guess -- but these could cause seemingly random problems for hypothetical IMAP clients that use alphanumeric tags, which I don't know if those exist.It also seems important to drop the connection outright if the first command has a tag of POST
, PUT
, etc. There's a couple of ways I can think of to approach that and I'm not yet sure which I prefer:
I suppose a way to limit the impact of rejecting POST/PUT on IMAP clients might be to only reject those tags if the command was also invalid. That'd catch stuff like POST / HTTP/1.1
but won't affect stuff like POST select inbox
. I'm not sure if it's possible to trick a browser into sending something that looks like a valid IMAP command in the target resource field of an HTTP request... POST noop HTTP/1.1
would probably work and might be plausible, hmm. So actually, I think I've convinced myself we probably have to reject this tag regardless of whether the command was valid.
Restricting tags and blocking HTTP requests are solid application layer countermeasures. If you limit the HTTP detection to the first command, I recommend to make sure that this works correctly with STARTTLS. For example, "Sendmail only detects HTTP requests at the very start of a connection. If STARTTLS is used, the first command inside the connection can be sent by the attacker, bypassing the detection" (Section 6.3 of our paper).
Note that strict ALPN validation is a strong countermeasure, as all common browsers already send ALPN identifiers like "http/1.1". The ALPN identifier "imap" is reserved for IMAP, so any client sending an ALPN extension that does not contain "imap" could be blocked. Then we don't even get to the application layer protocol.
Thanks, that's a good observation about STARTTLS, I'll keep it in mind. I don't know anything about ALPN, this issue was the first I heard of it, but I'll have a look into that too.
I've had a skim of the Wikipedia article on ALPN, and the OpenSSL docs for using it. It seems reasonable to implement, but we'd probably tackle it as a separate PR, and implement it for all protocols we implement, ingoing and outgoing, in one fell swoop. So implementation of that might lag somewhat behind the basic mitigations I'm already adding.
Hi,
I am one of the authors of the ALPACA attack from 2021. I am currently revisiting the evaluated implementations to see how widespread our suggested countermeasures were. See the paper for details. In Table 4, we indicated that Cyrus IMAP 3.2.4 does not reject HTTP requests, allows an unlimited number of errors and has a reflection vector. We also indicate that Cyrus POP3 3.0.8 does not reject HTTP requests and allows an unlimited number of errors. In Table 5, we indicate that these versions of Cyrus were vulnerable for Download (IMAP and POP3) and Reflection (IMAP only) attacks. A reevaluation by Janik Hölling in 2022 found that Cyrus 3.4.2 behaved the same, and that it does not implement strict ALPN or SNI validation. You can find the exploits and docker container for the reevaluation in our artifacts.
I understand that sometimes Cyrus is used with a proxy server like Nginx. To my understanding, nginx implemented strict ALPN validation, so users of Cyrus who put it behind nginx might be fine without any changes in Cyrus.
However, for others, countermeasures native to Cyrus might be appreciated. Did you consider these countermeasures?