Fossil SCM

Add defenses against [http://en.wikipedia.org/wiki/Cross-site_request_forgery | cross-site request forgery] attacks.

drh 2008-10-18 12:55 trunk
Commit 0be54823ba2b5afe0b058e77376feaa1ff47751a
--- src/admin.c
+++ src/admin.c
@@ -76,15 +76,17 @@
7676
style_header("Admin SQL");
7777
@ <h2>SQL:</h2>
7878
@ You can enter only SELECT statements here, and some SQL-side functions
7979
@ are also restricted.<br/>
8080
@ <form action='' method='post'>
81
+ login_insert_csrf_secret();
8182
@ <textarea style='border:2px solid black' name='sql'
8283
@ cols='80' rows='5'>%h(zSql)</textarea>
8384
@ <br/><input type='submit' name='sql_submit'/> <input type='reset'/>
8485
@ </form>
8586
if( zSql[0] ){
87
+ login_verify_csrf_secret();
8688
sqlite3_set_authorizer(g.db, selectOnly, 0);
8789
db_generic_query_view(zSql, 0);
8890
sqlite3_set_authorizer(g.db, 0, 0);
8991
}
9092
style_footer();
9193
--- src/admin.c
+++ src/admin.c
@@ -76,15 +76,17 @@
76 style_header("Admin SQL");
77 @ <h2>SQL:</h2>
78 @ You can enter only SELECT statements here, and some SQL-side functions
79 @ are also restricted.<br/>
80 @ <form action='' method='post'>
 
81 @ <textarea style='border:2px solid black' name='sql'
82 @ cols='80' rows='5'>%h(zSql)</textarea>
83 @ <br/><input type='submit' name='sql_submit'/> <input type='reset'/>
84 @ </form>
85 if( zSql[0] ){
 
86 sqlite3_set_authorizer(g.db, selectOnly, 0);
87 db_generic_query_view(zSql, 0);
88 sqlite3_set_authorizer(g.db, 0, 0);
89 }
90 style_footer();
91
--- src/admin.c
+++ src/admin.c
@@ -76,15 +76,17 @@
76 style_header("Admin SQL");
77 @ <h2>SQL:</h2>
78 @ You can enter only SELECT statements here, and some SQL-side functions
79 @ are also restricted.<br/>
80 @ <form action='' method='post'>
81 login_insert_csrf_secret();
82 @ <textarea style='border:2px solid black' name='sql'
83 @ cols='80' rows='5'>%h(zSql)</textarea>
84 @ <br/><input type='submit' name='sql_submit'/> <input type='reset'/>
85 @ </form>
86 if( zSql[0] ){
87 login_verify_csrf_secret();
88 sqlite3_set_authorizer(g.db, selectOnly, 0);
89 db_generic_query_view(zSql, 0);
90 sqlite3_set_authorizer(g.db, 0, 0);
91 }
92 style_footer();
93
+2
--- src/info.c
+++ src/info.c
@@ -1022,10 +1022,11 @@
10221022
if( P("apply") ){
10231023
Blob ctrl;
10241024
char *zDate;
10251025
int nChng = 0;
10261026
1027
+ login_verify_csrf_secret();
10271028
blob_zero(&ctrl);
10281029
zDate = db_text(0, "SELECT datetime('now')");
10291030
zDate[10] = 'T';
10301031
blob_appendf(&ctrl, "D %s\n", zDate);
10311032
if( strcmp(zComment,zNewComment)!=0 ){
@@ -1055,10 +1056,11 @@
10551056
style_header("Edit Baseline [%s]", zUuid);
10561057
@ <p>Make changes to the User and Comment for baseline
10571058
@ [<a href="vinfo?name=%d(rid)">%s(zUuid)</a>] then press the
10581059
@ "Apply Changes" button.</p>
10591060
@ <form action="%s(g.zBaseURL)/vedit" method="POST">
1061
+ login_insert_csrf_secret();
10601062
@ <input type="hidden" name="r" value="%d(rid)">
10611063
@ <p>
10621064
@ <b>User:</b> <input type="text" name="u" size="20" value="%h(zNewUser)">
10631065
@ </p>
10641066
@ <p><b>Comment:</b></b><br />
10651067
--- src/info.c
+++ src/info.c
@@ -1022,10 +1022,11 @@
1022 if( P("apply") ){
1023 Blob ctrl;
1024 char *zDate;
1025 int nChng = 0;
1026
 
1027 blob_zero(&ctrl);
1028 zDate = db_text(0, "SELECT datetime('now')");
1029 zDate[10] = 'T';
1030 blob_appendf(&ctrl, "D %s\n", zDate);
1031 if( strcmp(zComment,zNewComment)!=0 ){
@@ -1055,10 +1056,11 @@
1055 style_header("Edit Baseline [%s]", zUuid);
1056 @ <p>Make changes to the User and Comment for baseline
1057 @ [<a href="vinfo?name=%d(rid)">%s(zUuid)</a>] then press the
1058 @ "Apply Changes" button.</p>
1059 @ <form action="%s(g.zBaseURL)/vedit" method="POST">
 
1060 @ <input type="hidden" name="r" value="%d(rid)">
1061 @ <p>
1062 @ <b>User:</b> <input type="text" name="u" size="20" value="%h(zNewUser)">
1063 @ </p>
1064 @ <p><b>Comment:</b></b><br />
1065
--- src/info.c
+++ src/info.c
@@ -1022,10 +1022,11 @@
1022 if( P("apply") ){
1023 Blob ctrl;
1024 char *zDate;
1025 int nChng = 0;
1026
1027 login_verify_csrf_secret();
1028 blob_zero(&ctrl);
1029 zDate = db_text(0, "SELECT datetime('now')");
1030 zDate[10] = 'T';
1031 blob_appendf(&ctrl, "D %s\n", zDate);
1032 if( strcmp(zComment,zNewComment)!=0 ){
@@ -1055,10 +1056,11 @@
1056 style_header("Edit Baseline [%s]", zUuid);
1057 @ <p>Make changes to the User and Comment for baseline
1058 @ [<a href="vinfo?name=%d(rid)">%s(zUuid)</a>] then press the
1059 @ "Apply Changes" button.</p>
1060 @ <form action="%s(g.zBaseURL)/vedit" method="POST">
1061 login_insert_csrf_secret();
1062 @ <input type="hidden" name="r" value="%d(rid)">
1063 @ <p>
1064 @ <b>User:</b> <input type="text" name="u" size="20" value="%h(zNewUser)">
1065 @ </p>
1066 @ <p><b>Comment:</b></b><br />
1067
+33 -6
--- src/login.c
+++ src/login.c
@@ -234,16 +234,16 @@
234234
** and is valid. If the login cookie checks out, it then sets
235235
** g.zUserUuid appropriately.
236236
**
237237
*/
238238
void login_check_credentials(void){
239
- int uid = 0;
240
- const char *zCookie;
241
- const char *zRemoteAddr;
242
- const char *zCap = 0;
243
- const char *zNcap;
244
- const char *zAcap;
239
+ int uid = 0; /* User id */
240
+ const char *zCookie; /* Text of the login cookie */
241
+ const char *zRemoteAddr; /* IP address of the requestor */
242
+ const char *zCap = 0; /* Capability string */
243
+ const char *zNcap; /* Capabilities of user "nobody" */
244
+ const char *zAcap; /* Capabllities of user "anonymous" */
245245
246246
/* Only run this check once. */
247247
if( g.userUid!=0 ) return;
248248
249249
@@ -255,10 +255,11 @@
255255
if( strcmp(zRemoteAddr, "127.0.0.1")==0 && db_get_int("localauth",0)==0 ){
256256
uid = db_int(0, "SELECT uid FROM user WHERE cap LIKE '%%s%%'");
257257
g.zLogin = db_text("?", "SELECT login FROM user WHERE uid=%d", uid);
258258
zCap = "s";
259259
g.noPswd = 1;
260
+ strcpy(g.zCsrfToken, "localhost");
260261
}
261262
262263
/* Check the login cookie to see if it matches a known valid user.
263264
*/
264265
if( uid==0 && (zCookie = P(login_cookie_name()))!=0 ){
@@ -272,18 +273,20 @@
272273
atoi(zCookie), zCookie, zRemoteAddr
273274
);
274275
}else if( zCookie[0]=='a' ){
275276
uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'");
276277
}
278
+ snprintf(g.zCsrfToken, sizeof(g.zCsrfToken), "%.10s", zCookie);
277279
}
278280
279281
if( uid==0 ){
280282
uid = db_int(0, "SELECT uid FROM user WHERE login='nobody'");
281283
if( uid==0 ){
282284
uid = -1;
283285
zCap = "";
284286
}
287
+ strcpy(g.zCsrfToken, "none");
285288
}
286289
if( zCap==0 ){
287290
if( uid ){
288291
Stmt s;
289292
db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid);
@@ -432,5 +435,29 @@
432435
@ <p>Many <font color="red">hyperlinks are disabled.</font><br />
433436
@ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a>
434437
@ to enable hyperlinks.</p>
435438
}
436439
}
440
+
441
+/*
442
+** While rendering a form, call this routine to add the Anti-CSRF token
443
+** as a hidden element of the form.
444
+*/
445
+void login_insert_csrf_secret(void){
446
+ @ <input type="hidden" name="csrf" value="%s(g.zCsrfToken)">
447
+}
448
+
449
+/*
450
+** Before using the results of a form, first call this routine to verify
451
+** that ths Anti-CSRF token is present and is valid. If the Anti-CSRF token
452
+** is missing or is incorrect, then this emits and error message and never
453
+** returns.
454
+*/
455
+void login_verify_csrf_secret(void){
456
+ const char *zCsrf; /* The CSRF secret */
457
+ if( g.okCsrf ) return;
458
+ if( (zCsrf = P("csrf"))!=0 && strcmp(zCsrf, g.zCsrfToken)==0 ){
459
+ g.okCsrf = 1;
460
+ return;
461
+ }
462
+ fossil_fatal("Cross-site request forgery attempt");
463
+}
437464
--- src/login.c
+++ src/login.c
@@ -234,16 +234,16 @@
234 ** and is valid. If the login cookie checks out, it then sets
235 ** g.zUserUuid appropriately.
236 **
237 */
238 void login_check_credentials(void){
239 int uid = 0;
240 const char *zCookie;
241 const char *zRemoteAddr;
242 const char *zCap = 0;
243 const char *zNcap;
244 const char *zAcap;
245
246 /* Only run this check once. */
247 if( g.userUid!=0 ) return;
248
249
@@ -255,10 +255,11 @@
255 if( strcmp(zRemoteAddr, "127.0.0.1")==0 && db_get_int("localauth",0)==0 ){
256 uid = db_int(0, "SELECT uid FROM user WHERE cap LIKE '%%s%%'");
257 g.zLogin = db_text("?", "SELECT login FROM user WHERE uid=%d", uid);
258 zCap = "s";
259 g.noPswd = 1;
 
260 }
261
262 /* Check the login cookie to see if it matches a known valid user.
263 */
264 if( uid==0 && (zCookie = P(login_cookie_name()))!=0 ){
@@ -272,18 +273,20 @@
272 atoi(zCookie), zCookie, zRemoteAddr
273 );
274 }else if( zCookie[0]=='a' ){
275 uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'");
276 }
 
277 }
278
279 if( uid==0 ){
280 uid = db_int(0, "SELECT uid FROM user WHERE login='nobody'");
281 if( uid==0 ){
282 uid = -1;
283 zCap = "";
284 }
 
285 }
286 if( zCap==0 ){
287 if( uid ){
288 Stmt s;
289 db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid);
@@ -432,5 +435,29 @@
432 @ <p>Many <font color="red">hyperlinks are disabled.</font><br />
433 @ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a>
434 @ to enable hyperlinks.</p>
435 }
436 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
437
--- src/login.c
+++ src/login.c
@@ -234,16 +234,16 @@
234 ** and is valid. If the login cookie checks out, it then sets
235 ** g.zUserUuid appropriately.
236 **
237 */
238 void login_check_credentials(void){
239 int uid = 0; /* User id */
240 const char *zCookie; /* Text of the login cookie */
241 const char *zRemoteAddr; /* IP address of the requestor */
242 const char *zCap = 0; /* Capability string */
243 const char *zNcap; /* Capabilities of user "nobody" */
244 const char *zAcap; /* Capabllities of user "anonymous" */
245
246 /* Only run this check once. */
247 if( g.userUid!=0 ) return;
248
249
@@ -255,10 +255,11 @@
255 if( strcmp(zRemoteAddr, "127.0.0.1")==0 && db_get_int("localauth",0)==0 ){
256 uid = db_int(0, "SELECT uid FROM user WHERE cap LIKE '%%s%%'");
257 g.zLogin = db_text("?", "SELECT login FROM user WHERE uid=%d", uid);
258 zCap = "s";
259 g.noPswd = 1;
260 strcpy(g.zCsrfToken, "localhost");
261 }
262
263 /* Check the login cookie to see if it matches a known valid user.
264 */
265 if( uid==0 && (zCookie = P(login_cookie_name()))!=0 ){
@@ -272,18 +273,20 @@
273 atoi(zCookie), zCookie, zRemoteAddr
274 );
275 }else if( zCookie[0]=='a' ){
276 uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'");
277 }
278 snprintf(g.zCsrfToken, sizeof(g.zCsrfToken), "%.10s", zCookie);
279 }
280
281 if( uid==0 ){
282 uid = db_int(0, "SELECT uid FROM user WHERE login='nobody'");
283 if( uid==0 ){
284 uid = -1;
285 zCap = "";
286 }
287 strcpy(g.zCsrfToken, "none");
288 }
289 if( zCap==0 ){
290 if( uid ){
291 Stmt s;
292 db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid);
@@ -432,5 +435,29 @@
435 @ <p>Many <font color="red">hyperlinks are disabled.</font><br />
436 @ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a>
437 @ to enable hyperlinks.</p>
438 }
439 }
440
441 /*
442 ** While rendering a form, call this routine to add the Anti-CSRF token
443 ** as a hidden element of the form.
444 */
445 void login_insert_csrf_secret(void){
446 @ <input type="hidden" name="csrf" value="%s(g.zCsrfToken)">
447 }
448
449 /*
450 ** Before using the results of a form, first call this routine to verify
451 ** that ths Anti-CSRF token is present and is valid. If the Anti-CSRF token
452 ** is missing or is incorrect, then this emits and error message and never
453 ** returns.
454 */
455 void login_verify_csrf_secret(void){
456 const char *zCsrf; /* The CSRF secret */
457 if( g.okCsrf ) return;
458 if( (zCsrf = P("csrf"))!=0 && strcmp(zCsrf, g.zCsrfToken)==0 ){
459 g.okCsrf = 1;
460 return;
461 }
462 fossil_fatal("Cross-site request forgery attempt");
463 }
464
+4
--- src/main.c
+++ src/main.c
@@ -119,10 +119,14 @@
119119
int okWrTkt; /* w: make changes to tickets via web */
120120
int okTktFmt; /* t: create new ticket report formats */
121121
int okRdAddr; /* e: read email addresses or other private data */
122122
int okZip; /* z: download zipped artifact via /zip URL */
123123
124
+ /* For defense against Cross-site Request Forgery attacks */
125
+ char zCsrfToken[12]; /* Value of the anti-CSRF token */
126
+ int okCsrf; /* Anti-CSRF token is present and valid */
127
+
124128
FILE *fDebug; /* Write debug information here, if the file exists */
125129
126130
/* Storage for the aux() and/or option() SQL function arguments */
127131
int nAux; /* Number of distinct aux() or option() values */
128132
const char *azAuxName[MX_AUX]; /* Name of each aux() or option() value */
129133
--- src/main.c
+++ src/main.c
@@ -119,10 +119,14 @@
119 int okWrTkt; /* w: make changes to tickets via web */
120 int okTktFmt; /* t: create new ticket report formats */
121 int okRdAddr; /* e: read email addresses or other private data */
122 int okZip; /* z: download zipped artifact via /zip URL */
123
 
 
 
 
124 FILE *fDebug; /* Write debug information here, if the file exists */
125
126 /* Storage for the aux() and/or option() SQL function arguments */
127 int nAux; /* Number of distinct aux() or option() values */
128 const char *azAuxName[MX_AUX]; /* Name of each aux() or option() value */
129
--- src/main.c
+++ src/main.c
@@ -119,10 +119,14 @@
119 int okWrTkt; /* w: make changes to tickets via web */
120 int okTktFmt; /* t: create new ticket report formats */
121 int okRdAddr; /* e: read email addresses or other private data */
122 int okZip; /* z: download zipped artifact via /zip URL */
123
124 /* For defense against Cross-site Request Forgery attacks */
125 char zCsrfToken[12]; /* Value of the anti-CSRF token */
126 int okCsrf; /* Anti-CSRF token is present and valid */
127
128 FILE *fDebug; /* Write debug information here, if the file exists */
129
130 /* Storage for the aux() and/or option() SQL function arguments */
131 int nAux; /* Number of distinct aux() or option() values */
132 const char *azAuxName[MX_AUX]; /* Name of each aux() or option() value */
133
--- src/report.c
+++ src/report.c
@@ -319,10 +319,11 @@
319319
zOwner = PD("w",g.zLogin);
320320
z = P("s");
321321
zSQL = z ? trim_string(z) : 0;
322322
zClrKey = trim_string(PD("k",""));
323323
if( rn>0 && P("del2") ){
324
+ login_verify_csrf_secret();
324325
db_multi_exec("DELETE FROM reportfmt WHERE rn=%d", rn);
325326
cgi_redirect("reportlist");
326327
return;
327328
}else if( rn>0 && P("del1") ){
328329
zTitle = db_text(0, "SELECT title FROM reportfmt "
@@ -335,10 +336,11 @@
335336
@ <strong>%h(zTitle)</strong> from
336337
@ the database. This is an irreversible operation. All records
337338
@ related to this report will be removed and cannot be recovered.</p>
338339
@
339340
@ <input type="hidden" name="rn" value="%d(rn)">
341
+ login_insert_csrf_secret();
340342
@ <input type="submit" name="del2" value="Delete The Report">
341343
@ <input type="submit" name="can" value="Cancel">
342344
@ </form>
343345
style_footer();
344346
return;
@@ -354,10 +356,11 @@
354356
zErr = "Please supply a title";
355357
}else{
356358
zErr = verify_sql_statement(zSQL);
357359
}
358360
if( zErr==0 ){
361
+ login_verify_csrf_secret();
359362
if( rn>0 ){
360363
db_multi_exec("UPDATE reportfmt SET title=%Q, sqlcode=%Q,"
361364
" owner=%Q, cols=%Q WHERE rn=%d",
362365
zTitle, zSQL, zOwner, zClrKey, rn);
363366
}else{
@@ -404,10 +407,11 @@
404407
@ <p>Report Title:<br>
405408
@ <input type="text" name="t" value="%h(zTitle)" size="60"></p>
406409
@ <p>Enter a complete SQL query statement against the "TICKET" table:<br>
407410
@ <textarea name="s" rows="20" cols="80">%h(zSQL)</textarea>
408411
@ </p>
412
+ login_insert_csrf_secret();
409413
if( g.okAdmin ){
410414
@ <p>Report owner:
411415
@ <input type="text" name="w" size="20" value="%h(zOwner)">
412416
@ </p>
413417
} else {
414418
--- src/report.c
+++ src/report.c
@@ -319,10 +319,11 @@
319 zOwner = PD("w",g.zLogin);
320 z = P("s");
321 zSQL = z ? trim_string(z) : 0;
322 zClrKey = trim_string(PD("k",""));
323 if( rn>0 && P("del2") ){
 
324 db_multi_exec("DELETE FROM reportfmt WHERE rn=%d", rn);
325 cgi_redirect("reportlist");
326 return;
327 }else if( rn>0 && P("del1") ){
328 zTitle = db_text(0, "SELECT title FROM reportfmt "
@@ -335,10 +336,11 @@
335 @ <strong>%h(zTitle)</strong> from
336 @ the database. This is an irreversible operation. All records
337 @ related to this report will be removed and cannot be recovered.</p>
338 @
339 @ <input type="hidden" name="rn" value="%d(rn)">
 
340 @ <input type="submit" name="del2" value="Delete The Report">
341 @ <input type="submit" name="can" value="Cancel">
342 @ </form>
343 style_footer();
344 return;
@@ -354,10 +356,11 @@
354 zErr = "Please supply a title";
355 }else{
356 zErr = verify_sql_statement(zSQL);
357 }
358 if( zErr==0 ){
 
359 if( rn>0 ){
360 db_multi_exec("UPDATE reportfmt SET title=%Q, sqlcode=%Q,"
361 " owner=%Q, cols=%Q WHERE rn=%d",
362 zTitle, zSQL, zOwner, zClrKey, rn);
363 }else{
@@ -404,10 +407,11 @@
404 @ <p>Report Title:<br>
405 @ <input type="text" name="t" value="%h(zTitle)" size="60"></p>
406 @ <p>Enter a complete SQL query statement against the "TICKET" table:<br>
407 @ <textarea name="s" rows="20" cols="80">%h(zSQL)</textarea>
408 @ </p>
 
409 if( g.okAdmin ){
410 @ <p>Report owner:
411 @ <input type="text" name="w" size="20" value="%h(zOwner)">
412 @ </p>
413 } else {
414
--- src/report.c
+++ src/report.c
@@ -319,10 +319,11 @@
319 zOwner = PD("w",g.zLogin);
320 z = P("s");
321 zSQL = z ? trim_string(z) : 0;
322 zClrKey = trim_string(PD("k",""));
323 if( rn>0 && P("del2") ){
324 login_verify_csrf_secret();
325 db_multi_exec("DELETE FROM reportfmt WHERE rn=%d", rn);
326 cgi_redirect("reportlist");
327 return;
328 }else if( rn>0 && P("del1") ){
329 zTitle = db_text(0, "SELECT title FROM reportfmt "
@@ -335,10 +336,11 @@
336 @ <strong>%h(zTitle)</strong> from
337 @ the database. This is an irreversible operation. All records
338 @ related to this report will be removed and cannot be recovered.</p>
339 @
340 @ <input type="hidden" name="rn" value="%d(rn)">
341 login_insert_csrf_secret();
342 @ <input type="submit" name="del2" value="Delete The Report">
343 @ <input type="submit" name="can" value="Cancel">
344 @ </form>
345 style_footer();
346 return;
@@ -354,10 +356,11 @@
356 zErr = "Please supply a title";
357 }else{
358 zErr = verify_sql_statement(zSQL);
359 }
360 if( zErr==0 ){
361 login_verify_csrf_secret();
362 if( rn>0 ){
363 db_multi_exec("UPDATE reportfmt SET title=%Q, sqlcode=%Q,"
364 " owner=%Q, cols=%Q WHERE rn=%d",
365 zTitle, zSQL, zOwner, zClrKey, rn);
366 }else{
@@ -404,10 +407,11 @@
407 @ <p>Report Title:<br>
408 @ <input type="text" name="t" value="%h(zTitle)" size="60"></p>
409 @ <p>Enter a complete SQL query statement against the "TICKET" table:<br>
410 @ <textarea name="s" rows="20" cols="80">%h(zSQL)</textarea>
411 @ </p>
412 login_insert_csrf_secret();
413 if( g.okAdmin ){
414 @ <p>Report owner:
415 @ <input type="text" name="w" size="20" value="%h(zOwner)">
416 @ </p>
417 } else {
418
+11 -1
--- src/setup.c
+++ src/setup.c
@@ -286,10 +286,11 @@
286286
@
287287
@ <p><a href="setup_uedit?id=%d(uid))>[Bummer]</a></p>
288288
style_footer();
289289
return;
290290
}
291
+ login_verify_csrf_secret();
291292
db_multi_exec(
292293
"REPLACE INTO user(uid,login,info,pw,cap) "
293294
"VALUES(nullif(%d,0),%Q,%Q,%Q,'%s')",
294295
uid, P("login"), P("info"), zPw, zCap
295296
);
@@ -340,10 +341,11 @@
340341
}else{
341342
style_header("Add A New User");
342343
}
343344
@ <table align="left" hspace="20" vspace="10"><tr><td>
344345
@ <form action="%s(g.zPath)" method="POST">
346
+ login_insert_csrf_secret();
345347
@ <table>
346348
@ <tr>
347349
@ <td align="right"><nobr>User ID:</nobr></td>
348350
if( uid ){
349351
@ <td>%d(uid) <input type="hidden" name="id" value="%d(uid)"></td>
@@ -543,10 +545,11 @@
543545
zQ = "off";
544546
}
545547
if( zQ ){
546548
int iQ = strcmp(zQ,"on")==0 || atoi(zQ);
547549
if( iQ!=iVal ){
550
+ login_verify_csrf_secret();
548551
db_set(zVar, iQ ? "1" : "0", 0);
549552
iVal = iQ;
550553
}
551554
}
552555
if( iVal ){
@@ -567,10 +570,11 @@
567570
char *zDflt /* Default value if VAR table entry does not exist */
568571
){
569572
const char *zVal = db_get(zVar, zDflt);
570573
const char *zQ = P(zQParm);
571574
if( zQ && strcmp(zQ,zVal)!=0 ){
575
+ login_verify_csrf_secret();
572576
db_set(zVar, zQ, 0);
573577
zVal = zQ;
574578
}
575579
@ <input type="text" name="%s(zQParm)" value="%h(zVal)" size="%d(width)">
576580
@ <b>%s(zLabel)</b>
@@ -588,10 +592,11 @@
588592
const char *zDflt /* Default value if VAR table entry does not exist */
589593
){
590594
const char *z = db_get(zVar, (char*)zDflt);
591595
const char *zQ = P(zQP);
592596
if( zQ && strcmp(zQ,z)!=0 ){
597
+ login_verify_csrf_secret();
593598
db_set(zVar, zQ, 0);
594599
z = zQ;
595600
}
596601
if( rows>0 && cols>0 ){
597602
@ <textarea name="%s(zQP)" rows="%d(rows)" cols="%d(cols)">%h(z)</textarea>
@@ -610,11 +615,11 @@
610615
}
611616
612617
style_header("Access Control Settings");
613618
db_begin_transaction();
614619
@ <form action="%s(g.zBaseURL)/setup_access" method="POST">
615
-
620
+ login_insert_csrf_secret();
616621
@ <hr>
617622
onoff_attribute("Require password for local access",
618623
"localauth", "localauth", 1);
619624
@ <p>When enabled, the password sign-in is required for
620625
@ web access coming from 127.0.0.1. When disabled, web access
@@ -661,10 +666,11 @@
661666
}
662667
663668
style_header("Timeline Display Preferences");
664669
db_begin_transaction();
665670
@ <form action="%s(g.zBaseURL)/setup_timeline" method="POST">
671
+ login_insert_csrf_secret();
666672
667673
@ <hr>
668674
onoff_attribute("Block markup in timeline",
669675
"timeline-block-markup", "tbm", 0);
670676
@ <p>In timeline displays, check-in comments can be displayed with or
@@ -693,10 +699,11 @@
693699
}
694700
695701
style_header("WWW Configuration");
696702
db_begin_transaction();
697703
@ <form action="%s(g.zBaseURL)/setup_config" method="POST">
704
+ login_insert_csrf_secret();
698705
@ <hr />
699706
entry_attribute("Project Name", 60, "project-name", "pn", "");
700707
@ <p>Give your project a name so visitors know what this site is about.
701708
@ The project name will also be used as the RSS feed title.</p>
702709
@ <hr />
@@ -735,10 +742,11 @@
735742
if( !g.okSetup ){
736743
login_needed();
737744
}
738745
style_header("Edit CSS");
739746
@ <form action="%s(g.zBaseURL)/setup_editcss" method="POST">
747
+ login_insert_csrf_secret();
740748
@ Edit the CSS:<br />
741749
textarea_attribute("", 40, 80, "css", "css", zDefaultCSS);
742750
@ <br />
743751
@ <input type="submit" name="submit" value="Apply Changes">
744752
@ </form>
@@ -765,10 +773,11 @@
765773
}else{
766774
textarea_attribute(0, 0, 0, "header", "header", zDefaultHeader);
767775
}
768776
style_header("Edit Page Header");
769777
@ <form action="%s(g.zBaseURL)/setup_header" method="POST">
778
+ login_insert_csrf_secret();
770779
@ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to
771780
@ generate the beginning of every page through start of the main
772781
@ menu.</p>
773782
textarea_attribute("", 40, 80, "header", "header", zDefaultHeader);
774783
@ <br />
@@ -799,10 +808,11 @@
799808
}else{
800809
textarea_attribute(0, 0, 0, "footer", "footer", zDefaultFooter);
801810
}
802811
style_header("Edit Page Footer");
803812
@ <form action="%s(g.zBaseURL)/setup_footer" method="POST">
813
+ login_insert_csrf_secret();
804814
@ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to
805815
@ generate the end of every page.</p>
806816
textarea_attribute("", 20, 80, "footer", "footer", zDefaultFooter);
807817
@ <br />
808818
@ <input type="submit" name="submit" value="Apply Changes">
809819
--- src/setup.c
+++ src/setup.c
@@ -286,10 +286,11 @@
286 @
287 @ <p><a href="setup_uedit?id=%d(uid))>[Bummer]</a></p>
288 style_footer();
289 return;
290 }
 
291 db_multi_exec(
292 "REPLACE INTO user(uid,login,info,pw,cap) "
293 "VALUES(nullif(%d,0),%Q,%Q,%Q,'%s')",
294 uid, P("login"), P("info"), zPw, zCap
295 );
@@ -340,10 +341,11 @@
340 }else{
341 style_header("Add A New User");
342 }
343 @ <table align="left" hspace="20" vspace="10"><tr><td>
344 @ <form action="%s(g.zPath)" method="POST">
 
345 @ <table>
346 @ <tr>
347 @ <td align="right"><nobr>User ID:</nobr></td>
348 if( uid ){
349 @ <td>%d(uid) <input type="hidden" name="id" value="%d(uid)"></td>
@@ -543,10 +545,11 @@
543 zQ = "off";
544 }
545 if( zQ ){
546 int iQ = strcmp(zQ,"on")==0 || atoi(zQ);
547 if( iQ!=iVal ){
 
548 db_set(zVar, iQ ? "1" : "0", 0);
549 iVal = iQ;
550 }
551 }
552 if( iVal ){
@@ -567,10 +570,11 @@
567 char *zDflt /* Default value if VAR table entry does not exist */
568 ){
569 const char *zVal = db_get(zVar, zDflt);
570 const char *zQ = P(zQParm);
571 if( zQ && strcmp(zQ,zVal)!=0 ){
 
572 db_set(zVar, zQ, 0);
573 zVal = zQ;
574 }
575 @ <input type="text" name="%s(zQParm)" value="%h(zVal)" size="%d(width)">
576 @ <b>%s(zLabel)</b>
@@ -588,10 +592,11 @@
588 const char *zDflt /* Default value if VAR table entry does not exist */
589 ){
590 const char *z = db_get(zVar, (char*)zDflt);
591 const char *zQ = P(zQP);
592 if( zQ && strcmp(zQ,z)!=0 ){
 
593 db_set(zVar, zQ, 0);
594 z = zQ;
595 }
596 if( rows>0 && cols>0 ){
597 @ <textarea name="%s(zQP)" rows="%d(rows)" cols="%d(cols)">%h(z)</textarea>
@@ -610,11 +615,11 @@
610 }
611
612 style_header("Access Control Settings");
613 db_begin_transaction();
614 @ <form action="%s(g.zBaseURL)/setup_access" method="POST">
615
616 @ <hr>
617 onoff_attribute("Require password for local access",
618 "localauth", "localauth", 1);
619 @ <p>When enabled, the password sign-in is required for
620 @ web access coming from 127.0.0.1. When disabled, web access
@@ -661,10 +666,11 @@
661 }
662
663 style_header("Timeline Display Preferences");
664 db_begin_transaction();
665 @ <form action="%s(g.zBaseURL)/setup_timeline" method="POST">
 
666
667 @ <hr>
668 onoff_attribute("Block markup in timeline",
669 "timeline-block-markup", "tbm", 0);
670 @ <p>In timeline displays, check-in comments can be displayed with or
@@ -693,10 +699,11 @@
693 }
694
695 style_header("WWW Configuration");
696 db_begin_transaction();
697 @ <form action="%s(g.zBaseURL)/setup_config" method="POST">
 
698 @ <hr />
699 entry_attribute("Project Name", 60, "project-name", "pn", "");
700 @ <p>Give your project a name so visitors know what this site is about.
701 @ The project name will also be used as the RSS feed title.</p>
702 @ <hr />
@@ -735,10 +742,11 @@
735 if( !g.okSetup ){
736 login_needed();
737 }
738 style_header("Edit CSS");
739 @ <form action="%s(g.zBaseURL)/setup_editcss" method="POST">
 
740 @ Edit the CSS:<br />
741 textarea_attribute("", 40, 80, "css", "css", zDefaultCSS);
742 @ <br />
743 @ <input type="submit" name="submit" value="Apply Changes">
744 @ </form>
@@ -765,10 +773,11 @@
765 }else{
766 textarea_attribute(0, 0, 0, "header", "header", zDefaultHeader);
767 }
768 style_header("Edit Page Header");
769 @ <form action="%s(g.zBaseURL)/setup_header" method="POST">
 
770 @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to
771 @ generate the beginning of every page through start of the main
772 @ menu.</p>
773 textarea_attribute("", 40, 80, "header", "header", zDefaultHeader);
774 @ <br />
@@ -799,10 +808,11 @@
799 }else{
800 textarea_attribute(0, 0, 0, "footer", "footer", zDefaultFooter);
801 }
802 style_header("Edit Page Footer");
803 @ <form action="%s(g.zBaseURL)/setup_footer" method="POST">
 
804 @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to
805 @ generate the end of every page.</p>
806 textarea_attribute("", 20, 80, "footer", "footer", zDefaultFooter);
807 @ <br />
808 @ <input type="submit" name="submit" value="Apply Changes">
809
--- src/setup.c
+++ src/setup.c
@@ -286,10 +286,11 @@
286 @
287 @ <p><a href="setup_uedit?id=%d(uid))>[Bummer]</a></p>
288 style_footer();
289 return;
290 }
291 login_verify_csrf_secret();
292 db_multi_exec(
293 "REPLACE INTO user(uid,login,info,pw,cap) "
294 "VALUES(nullif(%d,0),%Q,%Q,%Q,'%s')",
295 uid, P("login"), P("info"), zPw, zCap
296 );
@@ -340,10 +341,11 @@
341 }else{
342 style_header("Add A New User");
343 }
344 @ <table align="left" hspace="20" vspace="10"><tr><td>
345 @ <form action="%s(g.zPath)" method="POST">
346 login_insert_csrf_secret();
347 @ <table>
348 @ <tr>
349 @ <td align="right"><nobr>User ID:</nobr></td>
350 if( uid ){
351 @ <td>%d(uid) <input type="hidden" name="id" value="%d(uid)"></td>
@@ -543,10 +545,11 @@
545 zQ = "off";
546 }
547 if( zQ ){
548 int iQ = strcmp(zQ,"on")==0 || atoi(zQ);
549 if( iQ!=iVal ){
550 login_verify_csrf_secret();
551 db_set(zVar, iQ ? "1" : "0", 0);
552 iVal = iQ;
553 }
554 }
555 if( iVal ){
@@ -567,10 +570,11 @@
570 char *zDflt /* Default value if VAR table entry does not exist */
571 ){
572 const char *zVal = db_get(zVar, zDflt);
573 const char *zQ = P(zQParm);
574 if( zQ && strcmp(zQ,zVal)!=0 ){
575 login_verify_csrf_secret();
576 db_set(zVar, zQ, 0);
577 zVal = zQ;
578 }
579 @ <input type="text" name="%s(zQParm)" value="%h(zVal)" size="%d(width)">
580 @ <b>%s(zLabel)</b>
@@ -588,10 +592,11 @@
592 const char *zDflt /* Default value if VAR table entry does not exist */
593 ){
594 const char *z = db_get(zVar, (char*)zDflt);
595 const char *zQ = P(zQP);
596 if( zQ && strcmp(zQ,z)!=0 ){
597 login_verify_csrf_secret();
598 db_set(zVar, zQ, 0);
599 z = zQ;
600 }
601 if( rows>0 && cols>0 ){
602 @ <textarea name="%s(zQP)" rows="%d(rows)" cols="%d(cols)">%h(z)</textarea>
@@ -610,11 +615,11 @@
615 }
616
617 style_header("Access Control Settings");
618 db_begin_transaction();
619 @ <form action="%s(g.zBaseURL)/setup_access" method="POST">
620 login_insert_csrf_secret();
621 @ <hr>
622 onoff_attribute("Require password for local access",
623 "localauth", "localauth", 1);
624 @ <p>When enabled, the password sign-in is required for
625 @ web access coming from 127.0.0.1. When disabled, web access
@@ -661,10 +666,11 @@
666 }
667
668 style_header("Timeline Display Preferences");
669 db_begin_transaction();
670 @ <form action="%s(g.zBaseURL)/setup_timeline" method="POST">
671 login_insert_csrf_secret();
672
673 @ <hr>
674 onoff_attribute("Block markup in timeline",
675 "timeline-block-markup", "tbm", 0);
676 @ <p>In timeline displays, check-in comments can be displayed with or
@@ -693,10 +699,11 @@
699 }
700
701 style_header("WWW Configuration");
702 db_begin_transaction();
703 @ <form action="%s(g.zBaseURL)/setup_config" method="POST">
704 login_insert_csrf_secret();
705 @ <hr />
706 entry_attribute("Project Name", 60, "project-name", "pn", "");
707 @ <p>Give your project a name so visitors know what this site is about.
708 @ The project name will also be used as the RSS feed title.</p>
709 @ <hr />
@@ -735,10 +742,11 @@
742 if( !g.okSetup ){
743 login_needed();
744 }
745 style_header("Edit CSS");
746 @ <form action="%s(g.zBaseURL)/setup_editcss" method="POST">
747 login_insert_csrf_secret();
748 @ Edit the CSS:<br />
749 textarea_attribute("", 40, 80, "css", "css", zDefaultCSS);
750 @ <br />
751 @ <input type="submit" name="submit" value="Apply Changes">
752 @ </form>
@@ -765,10 +773,11 @@
773 }else{
774 textarea_attribute(0, 0, 0, "header", "header", zDefaultHeader);
775 }
776 style_header("Edit Page Header");
777 @ <form action="%s(g.zBaseURL)/setup_header" method="POST">
778 login_insert_csrf_secret();
779 @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to
780 @ generate the beginning of every page through start of the main
781 @ menu.</p>
782 textarea_attribute("", 40, 80, "header", "header", zDefaultHeader);
783 @ <br />
@@ -799,10 +808,11 @@
808 }else{
809 textarea_attribute(0, 0, 0, "footer", "footer", zDefaultFooter);
810 }
811 style_header("Edit Page Footer");
812 @ <form action="%s(g.zBaseURL)/setup_footer" method="POST">
813 login_insert_csrf_secret();
814 @ <p>Edit HTML text with embedded TH1 (a TCL dialect) that will be used to
815 @ generate the end of every page.</p>
816 textarea_attribute("", 20, 80, "footer", "footer", zDefaultFooter);
817 @ <br />
818 @ <input type="submit" name="submit" value="Apply Changes">
819
+4
--- src/shun.c
+++ src/shun.c
@@ -65,10 +65,11 @@
6565
zUuid = zCanonical;
6666
}
6767
}
6868
style_header("Shunned Artifacts");
6969
if( zUuid && P("sub") ){
70
+ login_verify_csrf_secret();
7071
db_multi_exec("DELETE FROM shun WHERE uuid='%s'", zUuid);
7172
if( db_exists("SELECT 1 FROM blob WHERE uuid='%s'", zUuid) ){
7273
@ <p><font color="blue">Artifact
7374
@ <a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a> is no
7475
@ longer being shunned.</font></p>
@@ -79,10 +80,11 @@
7980
@ <b>fossil rebuild</b> command-line before the artifact content
8081
@ can pulled in from other respositories.</font></p>
8182
}
8283
}
8384
if( zUuid && P("add") ){
85
+ login_verify_csrf_secret();
8486
db_multi_exec("INSERT OR IGNORE INTO shun VALUES('%s')", zUuid);
8587
@ <p><font color="blue">Artifact
8688
@ <a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a> has been
8789
@ shunned. It will no longer be pushed.
8890
@ It will be removed from the repository the next time the respository
@@ -124,10 +126,11 @@
124126
@ of the repository. Do not shun artifacts merely to remove them from
125127
@ sight - set the "hidden" tag on such artifacts instead.</p>
126128
@
127129
@ <blockquote>
128130
@ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
131
+ login_insert_csrf_secret();
129132
@ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50">
130133
@ <input type="submit" name="add" value="Shun">
131134
@ </form>
132135
@ </blockquote>
133136
@
@@ -137,10 +140,11 @@
137140
@ the formerly shunned artifact will be accepted on subsequent sync
138141
@ operations.</p>
139142
@
140143
@ <blockquote>
141144
@ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
145
+ login_insert_csrf_secret();
142146
@ <input type="text" name="uuid" size="50">
143147
@ <input type="submit" name="sub" value="Accept">
144148
@ </form>
145149
@ </blockquote>
146150
style_footer();
147151
--- src/shun.c
+++ src/shun.c
@@ -65,10 +65,11 @@
65 zUuid = zCanonical;
66 }
67 }
68 style_header("Shunned Artifacts");
69 if( zUuid && P("sub") ){
 
70 db_multi_exec("DELETE FROM shun WHERE uuid='%s'", zUuid);
71 if( db_exists("SELECT 1 FROM blob WHERE uuid='%s'", zUuid) ){
72 @ <p><font color="blue">Artifact
73 @ <a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a> is no
74 @ longer being shunned.</font></p>
@@ -79,10 +80,11 @@
79 @ <b>fossil rebuild</b> command-line before the artifact content
80 @ can pulled in from other respositories.</font></p>
81 }
82 }
83 if( zUuid && P("add") ){
 
84 db_multi_exec("INSERT OR IGNORE INTO shun VALUES('%s')", zUuid);
85 @ <p><font color="blue">Artifact
86 @ <a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a> has been
87 @ shunned. It will no longer be pushed.
88 @ It will be removed from the repository the next time the respository
@@ -124,10 +126,11 @@
124 @ of the repository. Do not shun artifacts merely to remove them from
125 @ sight - set the "hidden" tag on such artifacts instead.</p>
126 @
127 @ <blockquote>
128 @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
 
129 @ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50">
130 @ <input type="submit" name="add" value="Shun">
131 @ </form>
132 @ </blockquote>
133 @
@@ -137,10 +140,11 @@
137 @ the formerly shunned artifact will be accepted on subsequent sync
138 @ operations.</p>
139 @
140 @ <blockquote>
141 @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
 
142 @ <input type="text" name="uuid" size="50">
143 @ <input type="submit" name="sub" value="Accept">
144 @ </form>
145 @ </blockquote>
146 style_footer();
147
--- src/shun.c
+++ src/shun.c
@@ -65,10 +65,11 @@
65 zUuid = zCanonical;
66 }
67 }
68 style_header("Shunned Artifacts");
69 if( zUuid && P("sub") ){
70 login_verify_csrf_secret();
71 db_multi_exec("DELETE FROM shun WHERE uuid='%s'", zUuid);
72 if( db_exists("SELECT 1 FROM blob WHERE uuid='%s'", zUuid) ){
73 @ <p><font color="blue">Artifact
74 @ <a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a> is no
75 @ longer being shunned.</font></p>
@@ -79,10 +80,11 @@
80 @ <b>fossil rebuild</b> command-line before the artifact content
81 @ can pulled in from other respositories.</font></p>
82 }
83 }
84 if( zUuid && P("add") ){
85 login_verify_csrf_secret();
86 db_multi_exec("INSERT OR IGNORE INTO shun VALUES('%s')", zUuid);
87 @ <p><font color="blue">Artifact
88 @ <a href="%s(g.zBaseURL)/artifact/%s(zUuid)">%s(zUuid)</a> has been
89 @ shunned. It will no longer be pushed.
90 @ It will be removed from the repository the next time the respository
@@ -124,10 +126,11 @@
126 @ of the repository. Do not shun artifacts merely to remove them from
127 @ sight - set the "hidden" tag on such artifacts instead.</p>
128 @
129 @ <blockquote>
130 @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
131 login_insert_csrf_secret();
132 @ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50">
133 @ <input type="submit" name="add" value="Shun">
134 @ </form>
135 @ </blockquote>
136 @
@@ -137,10 +140,11 @@
140 @ the formerly shunned artifact will be accepted on subsequent sync
141 @ operations.</p>
142 @
143 @ <blockquote>
144 @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
145 login_insert_csrf_secret();
146 @ <input type="text" name="uuid" size="50">
147 @ <input type="submit" name="sub" value="Accept">
148 @ </form>
149 @ </blockquote>
150 style_footer();
151
+3
--- src/tkt.c
+++ src/tkt.c
@@ -384,10 +384,11 @@
384384
const char *zUuid;
385385
int i;
386386
int rid;
387387
Blob tktchng, cksum;
388388
389
+ login_verify_csrf_secret();
389390
zUuid = (const char *)pUuid;
390391
blob_zero(&tktchng);
391392
zDate = db_text(0, "SELECT datetime('now')");
392393
zDate[10] = 'T';
393394
blob_appendf(&tktchng, "D %s\n", zDate);
@@ -467,10 +468,11 @@
467468
ticket_init();
468469
getAllTicketFields();
469470
initializeVariablesFromDb();
470471
initializeVariablesFromCGI();
471472
@ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
473
+ login_insert_csrf_secret();
472474
zScript = ticket_newpage_code();
473475
Th_Store("login", g.zLogin);
474476
Th_Store("date", db_text(0, "SELECT datetime('now')"));
475477
Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd,
476478
(void*)&zNewUuid, 0);
@@ -528,10 +530,11 @@
528530
getAllTicketFields();
529531
initializeVariablesFromCGI();
530532
initializeVariablesFromDb();
531533
@ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
532534
@ <input type="hidden" name="name" value="%s(zName)">
535
+ login_insert_csrf_secret();
533536
zScript = ticket_editpage_code();
534537
Th_Store("login", g.zLogin);
535538
Th_Store("date", db_text(0, "SELECT datetime('now')"));
536539
Th_CreateCommand(g.interp, "append_field", appendRemarkCmd, 0, 0);
537540
Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, (void*)&zName,0);
538541
--- src/tkt.c
+++ src/tkt.c
@@ -384,10 +384,11 @@
384 const char *zUuid;
385 int i;
386 int rid;
387 Blob tktchng, cksum;
388
 
389 zUuid = (const char *)pUuid;
390 blob_zero(&tktchng);
391 zDate = db_text(0, "SELECT datetime('now')");
392 zDate[10] = 'T';
393 blob_appendf(&tktchng, "D %s\n", zDate);
@@ -467,10 +468,11 @@
467 ticket_init();
468 getAllTicketFields();
469 initializeVariablesFromDb();
470 initializeVariablesFromCGI();
471 @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
 
472 zScript = ticket_newpage_code();
473 Th_Store("login", g.zLogin);
474 Th_Store("date", db_text(0, "SELECT datetime('now')"));
475 Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd,
476 (void*)&zNewUuid, 0);
@@ -528,10 +530,11 @@
528 getAllTicketFields();
529 initializeVariablesFromCGI();
530 initializeVariablesFromDb();
531 @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
532 @ <input type="hidden" name="name" value="%s(zName)">
 
533 zScript = ticket_editpage_code();
534 Th_Store("login", g.zLogin);
535 Th_Store("date", db_text(0, "SELECT datetime('now')"));
536 Th_CreateCommand(g.interp, "append_field", appendRemarkCmd, 0, 0);
537 Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, (void*)&zName,0);
538
--- src/tkt.c
+++ src/tkt.c
@@ -384,10 +384,11 @@
384 const char *zUuid;
385 int i;
386 int rid;
387 Blob tktchng, cksum;
388
389 login_verify_csrf_secret();
390 zUuid = (const char *)pUuid;
391 blob_zero(&tktchng);
392 zDate = db_text(0, "SELECT datetime('now')");
393 zDate[10] = 'T';
394 blob_appendf(&tktchng, "D %s\n", zDate);
@@ -467,10 +468,11 @@
468 ticket_init();
469 getAllTicketFields();
470 initializeVariablesFromDb();
471 initializeVariablesFromCGI();
472 @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
473 login_insert_csrf_secret();
474 zScript = ticket_newpage_code();
475 Th_Store("login", g.zLogin);
476 Th_Store("date", db_text(0, "SELECT datetime('now')"));
477 Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd,
478 (void*)&zNewUuid, 0);
@@ -528,10 +530,11 @@
530 getAllTicketFields();
531 initializeVariablesFromCGI();
532 initializeVariablesFromDb();
533 @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
534 @ <input type="hidden" name="name" value="%s(zName)">
535 login_insert_csrf_secret();
536 zScript = ticket_editpage_code();
537 Th_Store("login", g.zLogin);
538 Th_Store("date", db_text(0, "SELECT datetime('now')"));
539 Th_CreateCommand(g.interp, "append_field", appendRemarkCmd, 0, 0);
540 Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, (void*)&zName,0);
541
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -119,24 +119,27 @@
119119
if( z==0 ){
120120
z = db_get(zDbField, (char*)zDfltValue);
121121
}
122122
style_header("Edit %s", zTitle);
123123
if( P("clear")!=0 ){
124
+ login_verify_csrf_secret();
124125
db_unset(zDbField, 0);
125126
if( xRebuild ) xRebuild();
126127
z = zDfltValue;
127128
}else if( isSubmit ){
128129
char *zErr = 0;
130
+ login_verify_csrf_secret();
129131
if( xText && (zErr = xText(z))!=0 ){
130132
@ <p><font color="red"><b>ERROR: %h(zErr)</b></font></p>
131133
}else{
132134
db_set(zDbField, z, 0);
133135
if( xRebuild ) xRebuild();
134136
cgi_redirect("tktsetup");
135137
}
136138
}
137139
@ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="POST">
140
+ login_insert_csrf_secret();
138141
@ <p>%s(zDesc)</p>
139142
@ <textarea name="x" rows="%d(height)" cols="80">%h(z)</textarea>
140143
@ <blockquote>
141144
@ <input type="submit" name="submit" value="Apply Changes">
142145
@ <input type="submit" name="clear" value="Revert To Default">
@@ -634,10 +637,11 @@
634637
cgi_redirect("tktsetup");
635638
}
636639
style_header("Ticket Display On Timelines");
637640
db_begin_transaction();
638641
@ <form action="%s(g.zBaseURL)/tktsetup_timeline" method="POST">
642
+ login_insert_csrf_secret();
639643
640644
@ <hr>
641645
entry_attribute("Ticket Title", 40, "ticket-title-expr", "t", "title");
642646
@ <p>An SQL expression in a query against the TICKET table that will
643647
@ return the title of the ticket for display purposes after hyperlinks to
644648
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -119,24 +119,27 @@
119 if( z==0 ){
120 z = db_get(zDbField, (char*)zDfltValue);
121 }
122 style_header("Edit %s", zTitle);
123 if( P("clear")!=0 ){
 
124 db_unset(zDbField, 0);
125 if( xRebuild ) xRebuild();
126 z = zDfltValue;
127 }else if( isSubmit ){
128 char *zErr = 0;
 
129 if( xText && (zErr = xText(z))!=0 ){
130 @ <p><font color="red"><b>ERROR: %h(zErr)</b></font></p>
131 }else{
132 db_set(zDbField, z, 0);
133 if( xRebuild ) xRebuild();
134 cgi_redirect("tktsetup");
135 }
136 }
137 @ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="POST">
 
138 @ <p>%s(zDesc)</p>
139 @ <textarea name="x" rows="%d(height)" cols="80">%h(z)</textarea>
140 @ <blockquote>
141 @ <input type="submit" name="submit" value="Apply Changes">
142 @ <input type="submit" name="clear" value="Revert To Default">
@@ -634,10 +637,11 @@
634 cgi_redirect("tktsetup");
635 }
636 style_header("Ticket Display On Timelines");
637 db_begin_transaction();
638 @ <form action="%s(g.zBaseURL)/tktsetup_timeline" method="POST">
 
639
640 @ <hr>
641 entry_attribute("Ticket Title", 40, "ticket-title-expr", "t", "title");
642 @ <p>An SQL expression in a query against the TICKET table that will
643 @ return the title of the ticket for display purposes after hyperlinks to
644
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -119,24 +119,27 @@
119 if( z==0 ){
120 z = db_get(zDbField, (char*)zDfltValue);
121 }
122 style_header("Edit %s", zTitle);
123 if( P("clear")!=0 ){
124 login_verify_csrf_secret();
125 db_unset(zDbField, 0);
126 if( xRebuild ) xRebuild();
127 z = zDfltValue;
128 }else if( isSubmit ){
129 char *zErr = 0;
130 login_verify_csrf_secret();
131 if( xText && (zErr = xText(z))!=0 ){
132 @ <p><font color="red"><b>ERROR: %h(zErr)</b></font></p>
133 }else{
134 db_set(zDbField, z, 0);
135 if( xRebuild ) xRebuild();
136 cgi_redirect("tktsetup");
137 }
138 }
139 @ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="POST">
140 login_insert_csrf_secret();
141 @ <p>%s(zDesc)</p>
142 @ <textarea name="x" rows="%d(height)" cols="80">%h(z)</textarea>
143 @ <blockquote>
144 @ <input type="submit" name="submit" value="Apply Changes">
145 @ <input type="submit" name="clear" value="Revert To Default">
@@ -634,10 +637,11 @@
637 cgi_redirect("tktsetup");
638 }
639 style_header("Ticket Display On Timelines");
640 db_begin_transaction();
641 @ <form action="%s(g.zBaseURL)/tktsetup_timeline" method="POST">
642 login_insert_csrf_secret();
643
644 @ <hr>
645 entry_attribute("Ticket Title", 40, "ticket-title-expr", "t", "title");
646 @ <p>An SQL expression in a query against the TICKET table that will
647 @ return the title of the ticket for display purposes after hyperlinks to
648
+4
--- src/wiki.c
+++ src/wiki.c
@@ -251,10 +251,11 @@
251251
blob_zero(&wiki);
252252
db_begin_transaction();
253253
if( isSandbox ){
254254
db_set("sandbox",zBody,0);
255255
}else{
256
+ login_verify_csrf_secret();
256257
zDate = db_text(0, "SELECT datetime('now')");
257258
zDate[10] = 'T';
258259
blob_appendf(&wiki, "D %s\n", zDate);
259260
free(zDate);
260261
blob_appendf(&wiki, "L %F\n", zPageName);
@@ -300,10 +301,11 @@
300301
if( z[0]=='\n' ) n++;
301302
}
302303
if( n<20 ) n = 20;
303304
if( n>40 ) n = 40;
304305
@ <form method="POST" action="%s(g.zBaseURL)/wikiedit">
306
+ login_insert_csrf_secret();
305307
@ <input type="hidden" name="name" value="%h(zPageName)">
306308
@ <textarea name="w" class="wikiedit" cols="80"
307309
@ rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
308310
@ <br>
309311
@ <input type="submit" name="preview" value="Preview Your Changes">
@@ -384,10 +386,11 @@
384386
if( isSandbox ){
385387
blob_appendf(&body, db_get("sandbox",""));
386388
appendRemark(&body);
387389
db_set("sandbox", blob_str(&body), 0);
388390
}else{
391
+ login_verify_csrf_secret();
389392
content_get(rid, &content);
390393
manifest_parse(&m, &content);
391394
if( m.type==CFTYPE_WIKI ){
392395
blob_append(&body, m.zWiki, -1);
393396
}
@@ -435,10 +438,11 @@
435438
@ <hr>
436439
blob_reset(&preview);
437440
}
438441
zUser = PD("u", g.zLogin);
439442
@ <form method="POST" action="%s(g.zBaseURL)/wikiappend">
443
+ login_insert_csrf_secret();
440444
@ <input type="hidden" name="name" value="%h(zPageName)">
441445
@ Your Name:
442446
@ <input type="text" name="u" size="20" value="%h(zUser)"><br>
443447
@ Comment to append:<br>
444448
@ <textarea name="r" class="wikiedit" cols="80"
445449
--- src/wiki.c
+++ src/wiki.c
@@ -251,10 +251,11 @@
251 blob_zero(&wiki);
252 db_begin_transaction();
253 if( isSandbox ){
254 db_set("sandbox",zBody,0);
255 }else{
 
256 zDate = db_text(0, "SELECT datetime('now')");
257 zDate[10] = 'T';
258 blob_appendf(&wiki, "D %s\n", zDate);
259 free(zDate);
260 blob_appendf(&wiki, "L %F\n", zPageName);
@@ -300,10 +301,11 @@
300 if( z[0]=='\n' ) n++;
301 }
302 if( n<20 ) n = 20;
303 if( n>40 ) n = 40;
304 @ <form method="POST" action="%s(g.zBaseURL)/wikiedit">
 
305 @ <input type="hidden" name="name" value="%h(zPageName)">
306 @ <textarea name="w" class="wikiedit" cols="80"
307 @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
308 @ <br>
309 @ <input type="submit" name="preview" value="Preview Your Changes">
@@ -384,10 +386,11 @@
384 if( isSandbox ){
385 blob_appendf(&body, db_get("sandbox",""));
386 appendRemark(&body);
387 db_set("sandbox", blob_str(&body), 0);
388 }else{
 
389 content_get(rid, &content);
390 manifest_parse(&m, &content);
391 if( m.type==CFTYPE_WIKI ){
392 blob_append(&body, m.zWiki, -1);
393 }
@@ -435,10 +438,11 @@
435 @ <hr>
436 blob_reset(&preview);
437 }
438 zUser = PD("u", g.zLogin);
439 @ <form method="POST" action="%s(g.zBaseURL)/wikiappend">
 
440 @ <input type="hidden" name="name" value="%h(zPageName)">
441 @ Your Name:
442 @ <input type="text" name="u" size="20" value="%h(zUser)"><br>
443 @ Comment to append:<br>
444 @ <textarea name="r" class="wikiedit" cols="80"
445
--- src/wiki.c
+++ src/wiki.c
@@ -251,10 +251,11 @@
251 blob_zero(&wiki);
252 db_begin_transaction();
253 if( isSandbox ){
254 db_set("sandbox",zBody,0);
255 }else{
256 login_verify_csrf_secret();
257 zDate = db_text(0, "SELECT datetime('now')");
258 zDate[10] = 'T';
259 blob_appendf(&wiki, "D %s\n", zDate);
260 free(zDate);
261 blob_appendf(&wiki, "L %F\n", zPageName);
@@ -300,10 +301,11 @@
301 if( z[0]=='\n' ) n++;
302 }
303 if( n<20 ) n = 20;
304 if( n>40 ) n = 40;
305 @ <form method="POST" action="%s(g.zBaseURL)/wikiedit">
306 login_insert_csrf_secret();
307 @ <input type="hidden" name="name" value="%h(zPageName)">
308 @ <textarea name="w" class="wikiedit" cols="80"
309 @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
310 @ <br>
311 @ <input type="submit" name="preview" value="Preview Your Changes">
@@ -384,10 +386,11 @@
386 if( isSandbox ){
387 blob_appendf(&body, db_get("sandbox",""));
388 appendRemark(&body);
389 db_set("sandbox", blob_str(&body), 0);
390 }else{
391 login_verify_csrf_secret();
392 content_get(rid, &content);
393 manifest_parse(&m, &content);
394 if( m.type==CFTYPE_WIKI ){
395 blob_append(&body, m.zWiki, -1);
396 }
@@ -435,10 +438,11 @@
438 @ <hr>
439 blob_reset(&preview);
440 }
441 zUser = PD("u", g.zLogin);
442 @ <form method="POST" action="%s(g.zBaseURL)/wikiappend">
443 login_insert_csrf_secret();
444 @ <input type="hidden" name="name" value="%h(zPageName)">
445 @ Your Name:
446 @ <input type="text" name="u" size="20" value="%h(zUser)"><br>
447 @ Comment to append:<br>
448 @ <textarea name="r" class="wikiedit" cols="80"
449

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button