]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap-login: Don't allow IMAP command tags that have invalid characters.
authorTimo Sirainen <tss@iki.fi>
Fri, 8 Apr 2011 17:21:58 +0000 (20:21 +0300)
committerTimo Sirainen <tss@iki.fi>
Fri, 8 Apr 2011 17:21:58 +0000 (20:21 +0300)
This simply attempts to prevent HTTP requests from replying with any
potentially danerous data that some web browsers might execute, e.g.:

curl --request POST -F 'x="<script>alert(1)</script>"' http://localhost:143/

The above command probably doesn't work, because max. bad commands is
reached earlier. But if it isn't, this change makes sure it doesn't return
back anything, because '"' and '(' aren't allowed characters. Even if '"'
weren't required, there hopefully isn't much to be done without being able
to call any functions.

src/imap-login/client.c

index f559e2bf4a1b195c069343d7b4442a97d77e255a..eb64c076c82b22c3e9d1cbfe85df5894765c69f7 100644 (file)
@@ -199,6 +199,33 @@ static int client_command_execute(struct imap_client *client, const char *cmd,
        return -2;
 }
 
+static bool imap_is_valid_tag(const char *tag)
+{
+       for (; *tag != '\0'; tag++) {
+               switch (*tag) {
+               case '+':
+               /* atom-specials: */
+               case '(':
+               case ')':
+               case '{':
+               case '/':
+               case ' ':
+               /* list-wildcards: */
+               case '%':
+               case '*':
+               /* quoted-specials: */
+               case '"':
+               case '\\':
+                       return FALSE;
+               default:
+                       if (*tag < ' ') /* CTL */
+                               return FALSE;
+                       break;
+               }
+       }
+       return TRUE;
+}
+
 static bool client_handle_input(struct imap_client *client)
 {
        const struct imap_arg *args;
@@ -230,6 +257,13 @@ static bool client_handle_input(struct imap_client *client)
                 client->cmd_tag = imap_parser_read_word(client->parser);
                if (client->cmd_tag == NULL)
                        return FALSE; /* need more data */
+               if (!imap_is_valid_tag(client->cmd_tag)) {
+                       /* the tag is invalid, don't allow it and don't
+                          send it back. this attempts to prevent any
+                          potentially dangerous replies in case someone tries
+                          to access us using HTTP protocol. */
+                       client->cmd_tag = "";
+               }
        }
 
        if (client->cmd_name == NULL) {