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");
}