swat: Use additional nonce on XSRF protection samba-3.5.21
authorKai Blin <kai@samba.org>
Mon, 28 Jan 2013 22:13:43 +0000 (23:13 +0100)
committerKarolin Seeger <kseeger@samba.org>
Tue, 29 Jan 2013 09:52:38 +0000 (10:52 +0100)
If the user had a weak password on the root account of a machine running
SWAT, there still was a chance of being targetted by an XSRF on a
malicious web site targetting the SWAT setup.

Use a random nonce stored in secrets.tdb to close this possible attack
window. Thanks to Jann Horn for reporting this issue.

Signed-off-by: Kai Blin <kai@samba.org>
Fix bug #9577: CVE-2013-0214: Potential XSRF in SWAT.

source3/web/cgi.c
source3/web/swat.c
source3/web/swat_proto.h

index 0c8e9cbe55bbc009a4a266cd9f63ffda15c15120..afa2e63c513fa46b702105e9360c09e42a7785f1 100644 (file)
@@ -45,6 +45,7 @@ static const char *baseurl;
 static char *pathinfo;
 static char *C_user;
 static char *C_pass;
+static char *C_nonce;
 static bool inetd_server;
 static bool got_request;
 
@@ -326,19 +327,7 @@ static void cgi_web_auth(void)
        C_user = SMB_STRDUP(user);
 
        if (!setuid(0)) {
-               C_pass = secrets_fetch_generic("root", "SWAT");
-               if (C_pass == NULL) {
-                       char *tmp_pass = NULL;
-                       tmp_pass = generate_random_str(talloc_tos(), 16);
-                       if (tmp_pass == NULL) {
-                               printf("%sFailed to create random nonce for "
-                                      "SWAT session\n<br>%s\n", head, tail);
-                               exit(0);
-                       }
-                       secrets_store_generic("root", "SWAT", tmp_pass);
-                       C_pass = SMB_STRDUP(tmp_pass);
-                       TALLOC_FREE(tmp_pass);
-               }
+               C_pass = SMB_STRDUP(cgi_nonce());
        }
        setuid(pwd->pw_uid);
        if (geteuid() != pwd->pw_uid || getuid() != pwd->pw_uid) {
@@ -450,6 +439,30 @@ char *cgi_user_pass(void)
         return(C_pass);
 }
 
+/***************************************************************************
+return a ptr to the nonce
+  ***************************************************************************/
+char *cgi_nonce(void)
+{
+       const char *head = "Content-Type: text/html\r\n\r\n<HTML><BODY><H1>SWAT installation Error</H1>\n";
+       const char *tail = "</BODY></HTML>\r\n";
+       C_nonce = secrets_fetch_generic("root", "SWAT");
+       if (C_nonce == NULL) {
+               char *tmp_pass = NULL;
+               tmp_pass = generate_random_str(talloc_tos(), 16);
+               if (tmp_pass == NULL) {
+                       printf("%sFailed to create random nonce for "
+                              "SWAT session\n<br>%s\n", head, tail);
+                       exit(0);
+               }
+               secrets_store_generic("root", "SWAT", tmp_pass);
+               C_nonce = SMB_STRDUP(tmp_pass);
+               TALLOC_FREE(tmp_pass);
+       }
+       return(C_nonce);
+}
+
+
 /***************************************************************************
 handle a file download
   ***************************************************************************/
index d2bbee40c342abba0e15d464f0bb5cfeeee222a8..25a041f621ebb741267a55f781f03074c6400418 100644 (file)
@@ -148,6 +148,7 @@ void get_xsrf_token(const char *username, const char *pass,
        struct MD5Context md5_ctx;
        uint8_t token[16];
        int i;
+       char *nonce = cgi_nonce();
 
        token_str[0] = '\0';
        ZERO_STRUCT(md5_ctx);
@@ -161,6 +162,7 @@ void get_xsrf_token(const char *username, const char *pass,
        if (pass != NULL) {
                MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
        }
+       MD5Update(&md5_ctx, (uint8_t *)nonce, strlen(nonce));
 
        MD5Final(token, &md5_ctx);
 
index 424a3af545f47c83677b9ff59f6fde31de439e8b..fe51b1f80adeec169527bb048c7a277c16c80cb7 100644 (file)
@@ -32,6 +32,7 @@ const char *cgi_variable_nonull(const char *name);
 bool am_root(void);
 char *cgi_user_name(void);
 char *cgi_user_pass(void);
+char *cgi_nonce(void);
 void cgi_setup(const char *rootdir, int auth_required);
 const char *cgi_baseurl(void);
 const char *cgi_pathinfo(void);