Fossil SCM

All /fileedit/ajax requests now do a CSRF check and fail with 403 if CSRF seems likely.

stephan 2020-05-18 03:24 fileedit-ajaxify
Commit 88a69253cd7aa0d8000715fdfa2421eb9bb036c3cacd945ed9015adf089a1ee9
2 files changed +12 -7 +8
+12 -7
--- src/fileedit.c
+++ src/fileedit.c
@@ -1071,18 +1071,23 @@
10711071
/*
10721072
** Performs bootstrapping common to the /fileedit_xyz AJAX routes.
10731073
** Returns 0 if bootstrapping fails (wrong permissions), in which
10741074
** case it has reported the error and the route should immediately
10751075
** return. Returns true on success.
1076
+**
1077
+** Must be passed true if the request being set up requires POST,
1078
+** else false.
10761079
*/
1077
-static int fileedit_ajax_boostrap(void){
1080
+static int fileedit_ajax_boostrap(int requirePost){
10781081
login_check_credentials();
10791082
if( !g.perm.Write ){
10801083
fileedit_ajax_error(403,"Write permissions required.");
10811084
return 0;
1085
+ }else if(0==cgi_csrf_safe(requirePost)){
1086
+ fileedit_ajax_error(403, "CSRF violation?");
1087
+ return 0;
10821088
}
1083
-
10841089
return 1;
10851090
}
10861091
/*
10871092
** Returns true if the current user is allowed to edit the given
10881093
** filename, as determined by fileedit_is_editable(), else false,
@@ -1213,11 +1218,11 @@
12131218
int vid, frid;
12141219
Blob content = empty_blob;
12151220
const char * zMime;
12161221
12171222
fileedit_get_fnci_args( &zFilename, &zRev );
1218
- if(!fileedit_ajax_boostrap()
1223
+ if(!fileedit_ajax_boostrap(0)
12191224
|| !fileedit_ajax_setup_filerev(zRev, 0, &vid,
12201225
zFilename, &frid)){
12211226
return;
12221227
}
12231228
zMime = mimetype_from_name(zFilename);
@@ -1287,11 +1292,11 @@
12871292
int ln = atoi(PD("ln","0"));
12881293
int iframeHeight = atoi(PD("iframe_height","40"));
12891294
Blob content = empty_blob;
12901295
const char * zRenderMode = 0;
12911296
fileedit_get_fnci_args( &zFilename, 0 );
1292
- if(!fileedit_ajax_boostrap()
1297
+ if(!fileedit_ajax_boostrap(1)
12931298
|| !fileedit_ajax_check_filename(zFilename)){
12941299
return;
12951300
}
12961301
cgi_set_content_type("text/html");
12971302
blob_init(&content, zContent, -1);
@@ -1370,11 +1375,11 @@
13701375
}else if(1==iFlag){
13711376
diffFlags |= DIFF_IGNORE_EOLWS;
13721377
}
13731378
diffFlags |= DIFF_STRIP_EOLCR;
13741379
fileedit_get_fnci_args( &zFilename, &zRev );
1375
- if(!fileedit_ajax_boostrap()
1380
+ if(!fileedit_ajax_boostrap(1)
13761381
|| !fileedit_ajax_setup_filerev(zRev, &zRevUuid, &vid,
13771382
zFilename, &frid)){
13781383
return;
13791384
}
13801385
if(!zContent){
@@ -1557,11 +1562,11 @@
15571562
const char * zCi = PD("checkin",P("ci"));
15581563
Blob sql = empty_blob;
15591564
Stmt q = empty_Stmt;
15601565
int i = 0;
15611566
1562
- if(!fileedit_ajax_boostrap()){
1567
+ if(!fileedit_ajax_boostrap(0)){
15631568
return;
15641569
}
15651570
cgi_set_content_type("application/json");
15661571
if(zCi!=0){
15671572
char * zCiFull = 0;
@@ -1661,11 +1666,11 @@
16611666
int newVid = 0; /* new version's RID */
16621667
char * zNewUuid = 0; /* newVid's UUID */
16631668
char const * zMimetype;
16641669
char * zBranch = 0;
16651670
1666
- if(!fileedit_ajax_boostrap()){
1671
+ if(!fileedit_ajax_boostrap(1)){
16671672
return;
16681673
}
16691674
db_begin_transaction();
16701675
CheckinMiniInfo_init(&cimi);
16711676
rc = fileedit_setup_cimi_from_p(&cimi, &err, 0);
16721677
--- src/fileedit.c
+++ src/fileedit.c
@@ -1071,18 +1071,23 @@
1071 /*
1072 ** Performs bootstrapping common to the /fileedit_xyz AJAX routes.
1073 ** Returns 0 if bootstrapping fails (wrong permissions), in which
1074 ** case it has reported the error and the route should immediately
1075 ** return. Returns true on success.
 
 
 
1076 */
1077 static int fileedit_ajax_boostrap(void){
1078 login_check_credentials();
1079 if( !g.perm.Write ){
1080 fileedit_ajax_error(403,"Write permissions required.");
1081 return 0;
 
 
 
1082 }
1083
1084 return 1;
1085 }
1086 /*
1087 ** Returns true if the current user is allowed to edit the given
1088 ** filename, as determined by fileedit_is_editable(), else false,
@@ -1213,11 +1218,11 @@
1213 int vid, frid;
1214 Blob content = empty_blob;
1215 const char * zMime;
1216
1217 fileedit_get_fnci_args( &zFilename, &zRev );
1218 if(!fileedit_ajax_boostrap()
1219 || !fileedit_ajax_setup_filerev(zRev, 0, &vid,
1220 zFilename, &frid)){
1221 return;
1222 }
1223 zMime = mimetype_from_name(zFilename);
@@ -1287,11 +1292,11 @@
1287 int ln = atoi(PD("ln","0"));
1288 int iframeHeight = atoi(PD("iframe_height","40"));
1289 Blob content = empty_blob;
1290 const char * zRenderMode = 0;
1291 fileedit_get_fnci_args( &zFilename, 0 );
1292 if(!fileedit_ajax_boostrap()
1293 || !fileedit_ajax_check_filename(zFilename)){
1294 return;
1295 }
1296 cgi_set_content_type("text/html");
1297 blob_init(&content, zContent, -1);
@@ -1370,11 +1375,11 @@
1370 }else if(1==iFlag){
1371 diffFlags |= DIFF_IGNORE_EOLWS;
1372 }
1373 diffFlags |= DIFF_STRIP_EOLCR;
1374 fileedit_get_fnci_args( &zFilename, &zRev );
1375 if(!fileedit_ajax_boostrap()
1376 || !fileedit_ajax_setup_filerev(zRev, &zRevUuid, &vid,
1377 zFilename, &frid)){
1378 return;
1379 }
1380 if(!zContent){
@@ -1557,11 +1562,11 @@
1557 const char * zCi = PD("checkin",P("ci"));
1558 Blob sql = empty_blob;
1559 Stmt q = empty_Stmt;
1560 int i = 0;
1561
1562 if(!fileedit_ajax_boostrap()){
1563 return;
1564 }
1565 cgi_set_content_type("application/json");
1566 if(zCi!=0){
1567 char * zCiFull = 0;
@@ -1661,11 +1666,11 @@
1661 int newVid = 0; /* new version's RID */
1662 char * zNewUuid = 0; /* newVid's UUID */
1663 char const * zMimetype;
1664 char * zBranch = 0;
1665
1666 if(!fileedit_ajax_boostrap()){
1667 return;
1668 }
1669 db_begin_transaction();
1670 CheckinMiniInfo_init(&cimi);
1671 rc = fileedit_setup_cimi_from_p(&cimi, &err, 0);
1672
--- src/fileedit.c
+++ src/fileedit.c
@@ -1071,18 +1071,23 @@
1071 /*
1072 ** Performs bootstrapping common to the /fileedit_xyz AJAX routes.
1073 ** Returns 0 if bootstrapping fails (wrong permissions), in which
1074 ** case it has reported the error and the route should immediately
1075 ** return. Returns true on success.
1076 **
1077 ** Must be passed true if the request being set up requires POST,
1078 ** else false.
1079 */
1080 static int fileedit_ajax_boostrap(int requirePost){
1081 login_check_credentials();
1082 if( !g.perm.Write ){
1083 fileedit_ajax_error(403,"Write permissions required.");
1084 return 0;
1085 }else if(0==cgi_csrf_safe(requirePost)){
1086 fileedit_ajax_error(403, "CSRF violation?");
1087 return 0;
1088 }
 
1089 return 1;
1090 }
1091 /*
1092 ** Returns true if the current user is allowed to edit the given
1093 ** filename, as determined by fileedit_is_editable(), else false,
@@ -1213,11 +1218,11 @@
1218 int vid, frid;
1219 Blob content = empty_blob;
1220 const char * zMime;
1221
1222 fileedit_get_fnci_args( &zFilename, &zRev );
1223 if(!fileedit_ajax_boostrap(0)
1224 || !fileedit_ajax_setup_filerev(zRev, 0, &vid,
1225 zFilename, &frid)){
1226 return;
1227 }
1228 zMime = mimetype_from_name(zFilename);
@@ -1287,11 +1292,11 @@
1292 int ln = atoi(PD("ln","0"));
1293 int iframeHeight = atoi(PD("iframe_height","40"));
1294 Blob content = empty_blob;
1295 const char * zRenderMode = 0;
1296 fileedit_get_fnci_args( &zFilename, 0 );
1297 if(!fileedit_ajax_boostrap(1)
1298 || !fileedit_ajax_check_filename(zFilename)){
1299 return;
1300 }
1301 cgi_set_content_type("text/html");
1302 blob_init(&content, zContent, -1);
@@ -1370,11 +1375,11 @@
1375 }else if(1==iFlag){
1376 diffFlags |= DIFF_IGNORE_EOLWS;
1377 }
1378 diffFlags |= DIFF_STRIP_EOLCR;
1379 fileedit_get_fnci_args( &zFilename, &zRev );
1380 if(!fileedit_ajax_boostrap(1)
1381 || !fileedit_ajax_setup_filerev(zRev, &zRevUuid, &vid,
1382 zFilename, &frid)){
1383 return;
1384 }
1385 if(!zContent){
@@ -1557,11 +1562,11 @@
1562 const char * zCi = PD("checkin",P("ci"));
1563 Blob sql = empty_blob;
1564 Stmt q = empty_Stmt;
1565 int i = 0;
1566
1567 if(!fileedit_ajax_boostrap(0)){
1568 return;
1569 }
1570 cgi_set_content_type("application/json");
1571 if(zCi!=0){
1572 char * zCiFull = 0;
@@ -1661,11 +1666,11 @@
1666 int newVid = 0; /* new version's RID */
1667 char * zNewUuid = 0; /* newVid's UUID */
1668 char const * zMimetype;
1669 char * zBranch = 0;
1670
1671 if(!fileedit_ajax_boostrap(1)){
1672 return;
1673 }
1674 db_begin_transaction();
1675 CheckinMiniInfo_init(&cimi);
1676 rc = fileedit_setup_cimi_from_p(&cimi, &err, 0);
1677
--- src/style.c
+++ src/style.c
@@ -1590,10 +1590,18 @@
15901590
get_version(), g.zTop);
15911591
/* fossil.config = {...various config-level options...} */
15921592
CX("window.fossil.config = {"
15931593
"hashDigits: %d, hashDigitsUrl: %d"
15941594
"};\n", hash_digits(0), hash_digits(1));
1595
+#if 0
1596
+ /* Is it safe to emit the CSRF token here? Some pages add it
1597
+ ** as a hidden form field. */
1598
+ if(g.zCsrfToken[0]!=0){
1599
+ CX("window.fossil.csrfToken = %!j;\n",
1600
+ g.zCsrfToken);
1601
+ }
1602
+#endif
15951603
/*
15961604
** fossil.page holds info about the current page. This is also
15971605
** where the current page "should" store any of its own
15981606
** page-specific state, and it is reserved for that purpose.
15991607
*/
16001608
--- src/style.c
+++ src/style.c
@@ -1590,10 +1590,18 @@
1590 get_version(), g.zTop);
1591 /* fossil.config = {...various config-level options...} */
1592 CX("window.fossil.config = {"
1593 "hashDigits: %d, hashDigitsUrl: %d"
1594 "};\n", hash_digits(0), hash_digits(1));
 
 
 
 
 
 
 
 
1595 /*
1596 ** fossil.page holds info about the current page. This is also
1597 ** where the current page "should" store any of its own
1598 ** page-specific state, and it is reserved for that purpose.
1599 */
1600
--- src/style.c
+++ src/style.c
@@ -1590,10 +1590,18 @@
1590 get_version(), g.zTop);
1591 /* fossil.config = {...various config-level options...} */
1592 CX("window.fossil.config = {"
1593 "hashDigits: %d, hashDigitsUrl: %d"
1594 "};\n", hash_digits(0), hash_digits(1));
1595 #if 0
1596 /* Is it safe to emit the CSRF token here? Some pages add it
1597 ** as a hidden form field. */
1598 if(g.zCsrfToken[0]!=0){
1599 CX("window.fossil.csrfToken = %!j;\n",
1600 g.zCsrfToken);
1601 }
1602 #endif
1603 /*
1604 ** fossil.page holds info about the current page. This is also
1605 ** where the current page "should" store any of its own
1606 ** page-specific state, and it is reserved for that purpose.
1607 */
1608

Keyboard Shortcuts

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