Diff
Not logged in

Differences From:

File src/login.c part of check-in [5fb14b9a0f] - Include non-sym- tags in tagview web page. Also merge mainline into tagview branch. by eric on 2008-08-21 20:59:01. Also file src/login.c part of check-in [018b6050af] - Include 'z' in login_has_capability() by eric on 2008-08-21 19:57:18. [view]

To:

File src/login.c part of check-in [0be54823ba] - Add defenses against cross-site request forgery attacks. by drh on 2008-10-18 12:55:44. [view]

@@ -235,14 +235,14 @@
 ** g.zUserUuid appropriately.
 **
 */
 void login_check_credentials(void){
-  int uid = 0;
-  const char *zCookie;
-  const char *zRemoteAddr;
-  const char *zCap = 0;
-  const char *zNcap;
-  const char *zAcap;
+  int uid = 0;                  /* User id */
+  const char *zCookie;          /* Text of the login cookie */
+  const char *zRemoteAddr;      /* IP address of the requestor */
+  const char *zCap = 0;         /* Capability string */
+  const char *zNcap;            /* Capabilities of user "nobody" */
+  const char *zAcap;            /* Capabllities of user "anonymous" */
 
   /* Only run this check once.  */
   if( g.userUid!=0 ) return;
 
@@ -256,8 +256,9 @@
     uid = db_int(0, "SELECT uid FROM user WHERE cap LIKE '%%s%%'");
     g.zLogin = db_text("?", "SELECT login FROM user WHERE uid=%d", uid);
     zCap = "s";
     g.noPswd = 1;
+    strcpy(g.zCsrfToken, "localhost");
   }
 
   /* Check the login cookie to see if it matches a known valid user.
   */
@@ -273,8 +274,9 @@
          );
     }else if( zCookie[0]=='a' ){
       uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'");
     }
+    snprintf(g.zCsrfToken, sizeof(g.zCsrfToken), "%.10s", zCookie);
   }
 
   if( uid==0 ){
     uid = db_int(0, "SELECT uid FROM user WHERE login='nobody'");
@@ -281,8 +283,9 @@
     if( uid==0 ){
       uid = -1;
       zCap = "";
     }
+    strcpy(g.zCsrfToken, "none");
   }
   if( zCap==0 ){
     if( uid ){
       Stmt s;
@@ -432,5 +435,29 @@
     @ <p>Many <font color="red">hyperlinks are disabled.</font><br />
     @ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a>
     @ to enable hyperlinks.</p>
   }
+}
+
+/*
+** While rendering a form, call this routine to add the Anti-CSRF token
+** as a hidden element of the form.
+*/
+void login_insert_csrf_secret(void){
+  @ <input type="hidden" name="csrf" value="%s(g.zCsrfToken)">
+}
+
+/*
+** Before using the results of a form, first call this routine to verify
+** that ths Anti-CSRF token is present and is valid.  If the Anti-CSRF token
+** is missing or is incorrect, then this emits and error message and never
+** returns.
+*/
+void login_verify_csrf_secret(void){
+  const char *zCsrf;            /* The CSRF secret */
+  if( g.okCsrf ) return;
+  if( (zCsrf = P("csrf"))!=0 && strcmp(zCsrf, g.zCsrfToken)==0 ){
+    g.okCsrf = 1;
+    return;
+  }
+  fossil_fatal("Cross-site request forgery attempt");
 }