Fossil SCM

Improved defense against denial-of-service caused by hackers pounding Fossil with repeated requests that contain SQL injection attempts. If SQL injection is attempted, return a "Begone, Knave!" page with status code 418.

drh 2023-07-18 13:36 trunk merge
Commit 57f1e8725425e34fd092dc672dfa7fd5b480ed8aa5364b76645136bafa10a446
--- src/branch.c
+++ src/branch.c
@@ -858,10 +858,11 @@
858858
new_brlist_page();
859859
return;
860860
}
861861
login_check_credentials();
862862
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
863
+ cgi_check_for_malice();
863864
if( colorTest ){
864865
showClosed = 0;
865866
showAll = 1;
866867
}
867868
if( showAll ) brFlags = BRL_BOTH;
@@ -986,10 +987,11 @@
986987
style_set_current_feature("branch");
987988
style_header("Branches");
988989
style_submenu_element("List", "brlist");
989990
login_anonymous_available();
990991
timeline_ss_submenu();
992
+ cgi_check_for_malice();
991993
@ <h2>The initial check-in for each branch:</h2>
992994
blob_append(&sql, timeline_query_for_www(), -1);
993995
blob_append_sql(&sql,
994996
"AND blob.rid IN (SELECT rid FROM tagxref"
995997
" WHERE tagtype>0 AND tagid=%d AND srcid!=0)", TAG_BRANCH);
996998
--- src/branch.c
+++ src/branch.c
@@ -858,10 +858,11 @@
858 new_brlist_page();
859 return;
860 }
861 login_check_credentials();
862 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
 
863 if( colorTest ){
864 showClosed = 0;
865 showAll = 1;
866 }
867 if( showAll ) brFlags = BRL_BOTH;
@@ -986,10 +987,11 @@
986 style_set_current_feature("branch");
987 style_header("Branches");
988 style_submenu_element("List", "brlist");
989 login_anonymous_available();
990 timeline_ss_submenu();
 
991 @ <h2>The initial check-in for each branch:</h2>
992 blob_append(&sql, timeline_query_for_www(), -1);
993 blob_append_sql(&sql,
994 "AND blob.rid IN (SELECT rid FROM tagxref"
995 " WHERE tagtype>0 AND tagid=%d AND srcid!=0)", TAG_BRANCH);
996
--- src/branch.c
+++ src/branch.c
@@ -858,10 +858,11 @@
858 new_brlist_page();
859 return;
860 }
861 login_check_credentials();
862 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
863 cgi_check_for_malice();
864 if( colorTest ){
865 showClosed = 0;
866 showAll = 1;
867 }
868 if( showAll ) brFlags = BRL_BOTH;
@@ -986,10 +987,11 @@
987 style_set_current_feature("branch");
988 style_header("Branches");
989 style_submenu_element("List", "brlist");
990 login_anonymous_available();
991 timeline_ss_submenu();
992 cgi_check_for_malice();
993 @ <h2>The initial check-in for each branch:</h2>
994 blob_append(&sql, timeline_query_for_www(), -1);
995 blob_append_sql(&sql,
996 "AND blob.rid IN (SELECT rid FROM tagxref"
997 " WHERE tagtype>0 AND tagid=%d AND srcid!=0)", TAG_BRANCH);
998
--- src/browse.c
+++ src/browse.c
@@ -209,10 +209,11 @@
209209
fossil_free(zHeader);
210210
style_adunit_config(ADUNIT_RIGHT_OK);
211211
sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
212212
pathelementFunc, 0, 0);
213213
url_initialize(&sURI, "dir");
214
+ cgi_check_for_malice();
214215
cgi_query_parameters_to_url(&sURI);
215216
216217
/* Compute the title of the page */
217218
if( zD ){
218219
Blob dirname;
@@ -705,10 +706,11 @@
705706
zRE = P("re");
706707
if( zRE ){
707708
re_compile(&pRE, zRE, 0);
708709
zREx = mprintf("&re=%T", zRE);
709710
}
711
+ cgi_check_for_malice();
710712
711713
/* If the name= parameter is an empty string, make it a NULL pointer */
712714
if( zD && strlen(zD)==0 ){ zD = 0; }
713715
714716
/* If a specific check-in is requested, fetch and parse it. If the
@@ -1109,10 +1111,11 @@
11091111
zNow = db_text("", "SELECT datetime(mtime,toLocal()) FROM event"
11101112
" WHERE objid=%d", rid);
11111113
style_submenu_element("Tree-View", "%R/tree?ci=%T&mtime=1&type=tree", zName);
11121114
style_header("File Ages");
11131115
zGlob = P("glob");
1116
+ cgi_check_for_malice();
11141117
compute_fileage(rid,zGlob);
11151118
db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);");
11161119
11171120
if( fossil_strcmp(zName,"tip")==0 ){
11181121
@ <h1>Files in the %z(href("%R/info?name=tip"))latest check-in</a>
11191122
--- src/browse.c
+++ src/browse.c
@@ -209,10 +209,11 @@
209 fossil_free(zHeader);
210 style_adunit_config(ADUNIT_RIGHT_OK);
211 sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
212 pathelementFunc, 0, 0);
213 url_initialize(&sURI, "dir");
 
214 cgi_query_parameters_to_url(&sURI);
215
216 /* Compute the title of the page */
217 if( zD ){
218 Blob dirname;
@@ -705,10 +706,11 @@
705 zRE = P("re");
706 if( zRE ){
707 re_compile(&pRE, zRE, 0);
708 zREx = mprintf("&re=%T", zRE);
709 }
 
710
711 /* If the name= parameter is an empty string, make it a NULL pointer */
712 if( zD && strlen(zD)==0 ){ zD = 0; }
713
714 /* If a specific check-in is requested, fetch and parse it. If the
@@ -1109,10 +1111,11 @@
1109 zNow = db_text("", "SELECT datetime(mtime,toLocal()) FROM event"
1110 " WHERE objid=%d", rid);
1111 style_submenu_element("Tree-View", "%R/tree?ci=%T&mtime=1&type=tree", zName);
1112 style_header("File Ages");
1113 zGlob = P("glob");
 
1114 compute_fileage(rid,zGlob);
1115 db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);");
1116
1117 if( fossil_strcmp(zName,"tip")==0 ){
1118 @ <h1>Files in the %z(href("%R/info?name=tip"))latest check-in</a>
1119
--- src/browse.c
+++ src/browse.c
@@ -209,10 +209,11 @@
209 fossil_free(zHeader);
210 style_adunit_config(ADUNIT_RIGHT_OK);
211 sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
212 pathelementFunc, 0, 0);
213 url_initialize(&sURI, "dir");
214 cgi_check_for_malice();
215 cgi_query_parameters_to_url(&sURI);
216
217 /* Compute the title of the page */
218 if( zD ){
219 Blob dirname;
@@ -705,10 +706,11 @@
706 zRE = P("re");
707 if( zRE ){
708 re_compile(&pRE, zRE, 0);
709 zREx = mprintf("&re=%T", zRE);
710 }
711 cgi_check_for_malice();
712
713 /* If the name= parameter is an empty string, make it a NULL pointer */
714 if( zD && strlen(zD)==0 ){ zD = 0; }
715
716 /* If a specific check-in is requested, fetch and parse it. If the
@@ -1109,10 +1111,11 @@
1111 zNow = db_text("", "SELECT datetime(mtime,toLocal()) FROM event"
1112 " WHERE objid=%d", rid);
1113 style_submenu_element("Tree-View", "%R/tree?ci=%T&mtime=1&type=tree", zName);
1114 style_header("File Ages");
1115 zGlob = P("glob");
1116 cgi_check_for_malice();
1117 compute_fileage(rid,zGlob);
1118 db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);");
1119
1120 if( fossil_strcmp(zName,"tip")==0 ){
1121 @ <h1>Files in the %z(href("%R/info?name=tip"))latest check-in</a>
1122
+55 -11
--- src/cgi.c
+++ src/cgi.c
@@ -749,10 +749,11 @@
749749
const char *zName; /* Parameter or cookie name */
750750
const char *zValue; /* Value of the query parameter or cookie */
751751
int seq; /* Order of insertion */
752752
char isQP; /* True for query parameters */
753753
char cTag; /* Tag on query parameters */
754
+ char isFetched; /* 1 if the var is requested via P/PD() */
754755
} *aParamQP; /* An array of all parameters and cookies */
755756
756757
/*
757758
** Add another query parameter or cookie to the parameter set.
758759
** zName is the name of the query parameter or cookie and zValue
@@ -776,10 +777,11 @@
776777
fprintf(stderr, "# cgi: %s = [%s]\n", zName, zValue);
777778
}
778779
aParamQP[nUsedQP].seq = seqQP++;
779780
aParamQP[nUsedQP].isQP = isQP;
780781
aParamQP[nUsedQP].cTag = 0;
782
+ aParamQP[nUsedQP].isFetched = 0;
781783
nUsedQP++;
782784
sortQP = 1;
783785
}
784786
785787
/*
@@ -1503,10 +1505,11 @@
15031505
while( lo<=hi ){
15041506
mid = (lo+hi)/2;
15051507
c = fossil_strcmp(aParamQP[mid].zName, zName);
15061508
if( c==0 ){
15071509
CGIDEBUG(("mem-match [%s] = [%s]\n", zName, aParamQP[mid].zValue));
1510
+ aParamQP[mid].isFetched = 1;
15081511
return aParamQP[mid].zValue;
15091512
}else if( c>0 ){
15101513
hi = mid-1;
15111514
}else{
15121515
lo = mid+1;
@@ -1530,24 +1533,27 @@
15301533
}
15311534
15321535
/*
15331536
** Renders the "begone, spider" page and exits.
15341537
*/
1535
-static void cgi_begone_spider(void){
1538
+static void cgi_begone_spider(const char *zName){
15361539
Blob content = empty_blob;
1537
-
15381540
cgi_set_content(&content);
15391541
style_set_current_feature("test");
1542
+ style_submenu_enable(0);
15401543
style_header("Malicious Query Detected");
1541
- @ <h2>Begone, Fiend!</h2>
1542
- @ <p>This page was generated because Fossil believes it has
1543
- @ detected an SQL injection attack. If you believe you are seeing
1544
- @ this in error, contact the developers on the Fossil-SCM Forum. Type
1544
+ @ <h2>Begone, Knave!</h2>
1545
+ @ <p>This page was generated because Fossil detected an (unsuccessful)
1546
+ @ SQL injection attack or other nefarious content in your HTTP request.
1547
+ @
1548
+ @ <p>If you believe you are innocent and have reached this page in error,
1549
+ @ contact the Fossil developers on the Fossil-SCM Forum. Type
15451550
@ "fossil-scm forum" into any search engine to locate the Fossil-SCM Forum.
15461551
style_finish_page();
1547
- cgi_set_status(404,"Robot Attack Detected");
1552
+ cgi_set_status(418,"I'm a teapot");
15481553
cgi_reply();
1554
+ fossil_errorlog("possible hack attempt - 418 response on \"%s\"", zName);
15491555
exit(0);
15501556
}
15511557
15521558
/*
15531559
** If looks_like_sql_injection() returns true for the given string, calls
@@ -1563,13 +1569,13 @@
15631569
** the server with dozens or hundreds of SQL injection attempts per second
15641570
** against pages (such as /vdiff) that are expensive to compute. In other
15651571
** words, this is an effort to reduce the CPU load imposed by malicious
15661572
** spiders. It is not an effect defense against SQL injection vulnerabilities.
15671573
*/
1568
-void cgi_value_spider_check(const char *zTxt){
1574
+void cgi_value_spider_check(const char *zTxt, const char *zName){
15691575
if( g.zLogin==0 && looks_like_sql_injection(zTxt) ){
1570
- cgi_begone_spider();
1576
+ cgi_begone_spider(zName);
15711577
}
15721578
}
15731579
15741580
/*
15751581
** A variant of cgi_parameter() with the same semantics except that if
@@ -1578,11 +1584,11 @@
15781584
*/
15791585
const char *cgi_parameter_nosql(const char *zName, const char *zDefault){
15801586
const char *zTxt = cgi_parameter(zName, zDefault);
15811587
15821588
if( zTxt!=zDefault ){
1583
- cgi_value_spider_check(zTxt);
1589
+ cgi_value_spider_check(zTxt, zName);
15841590
}
15851591
return zTxt;
15861592
}
15871593
15881594
/*
@@ -1770,11 +1776,11 @@
17701776
switch( eDest ){
17711777
case 0: {
17721778
cgi_printf("%h = %h <br>\n", zName, aParamQP[i].zValue);
17731779
break;
17741780
}
1775
- case 1: {
1781
+ case 1: {
17761782
fossil_trace("%s = %s\n", zName, aParamQP[i].zValue);
17771783
break;
17781784
}
17791785
case 2: {
17801786
cgi_debug("%s = %s\n", zName, aParamQP[i].zValue);
@@ -2704,5 +2710,43 @@
27042710
const char *zAgent = P("HTTP_USER_AGENT");
27052711
if( zAgent==0 ) return 0;
27062712
if( sqlite3_strglob("*iPad*", zAgent)==0 ) return 0;
27072713
return sqlite3_strlike("%mobile%", zAgent, 0)==0;
27082714
}
2715
+
2716
+/*
2717
+** Look for query or POST parameters that:
2718
+**
2719
+** (1) Have not been used
2720
+** (2) Appear to be malicious attempts to break into or otherwise
2721
+** harm the system, for example via SQL injection
2722
+**
2723
+** If any such parameters are seen, a 418 ("I'm a teapot") return is
2724
+** generated and processing aborts - this routine does not return.
2725
+**
2726
+** When Fossil is launched via CGI from althttpd, the 418 return signals
2727
+** the webserver to put the requestor IP address into "timeout", blocking
2728
+** subsequent requests for 5 minutes.
2729
+**
2730
+** Fossil is not subject to any SQL injections, as far as anybody knows.
2731
+** This routine is not necessary for the security of the system (though
2732
+** an extra layer of security never hurts). The main purpose here is
2733
+** to shutdown malicious attack spiders and prevent them from burning
2734
+** lots of CPU cycles and bogging down the website. In other words, the
2735
+** objective of this routine is to help prevent denial-of-service.
2736
+**
2737
+** Usage Hint: Put a call to this routine as late in the webpage
2738
+** implementation as possible, ideally just before it begins doing
2739
+** potentially CPU-intensive computations and after all query parameters
2740
+** have been consulted.
2741
+*/
2742
+void cgi_check_for_malice(void){
2743
+ struct QParam * pParam;
2744
+ int i;
2745
+ for(i = 0; i < nUsedQP; ++i){
2746
+ pParam = &aParamQP[i];
2747
+ if(0 == pParam->isFetched
2748
+ && fossil_islower(pParam->zName[0])){
2749
+ cgi_value_spider_check(pParam->zValue, pParam->zName);
2750
+ }
2751
+ }
2752
+}
27092753
--- src/cgi.c
+++ src/cgi.c
@@ -749,10 +749,11 @@
749 const char *zName; /* Parameter or cookie name */
750 const char *zValue; /* Value of the query parameter or cookie */
751 int seq; /* Order of insertion */
752 char isQP; /* True for query parameters */
753 char cTag; /* Tag on query parameters */
 
754 } *aParamQP; /* An array of all parameters and cookies */
755
756 /*
757 ** Add another query parameter or cookie to the parameter set.
758 ** zName is the name of the query parameter or cookie and zValue
@@ -776,10 +777,11 @@
776 fprintf(stderr, "# cgi: %s = [%s]\n", zName, zValue);
777 }
778 aParamQP[nUsedQP].seq = seqQP++;
779 aParamQP[nUsedQP].isQP = isQP;
780 aParamQP[nUsedQP].cTag = 0;
 
781 nUsedQP++;
782 sortQP = 1;
783 }
784
785 /*
@@ -1503,10 +1505,11 @@
1503 while( lo<=hi ){
1504 mid = (lo+hi)/2;
1505 c = fossil_strcmp(aParamQP[mid].zName, zName);
1506 if( c==0 ){
1507 CGIDEBUG(("mem-match [%s] = [%s]\n", zName, aParamQP[mid].zValue));
 
1508 return aParamQP[mid].zValue;
1509 }else if( c>0 ){
1510 hi = mid-1;
1511 }else{
1512 lo = mid+1;
@@ -1530,24 +1533,27 @@
1530 }
1531
1532 /*
1533 ** Renders the "begone, spider" page and exits.
1534 */
1535 static void cgi_begone_spider(void){
1536 Blob content = empty_blob;
1537
1538 cgi_set_content(&content);
1539 style_set_current_feature("test");
 
1540 style_header("Malicious Query Detected");
1541 @ <h2>Begone, Fiend!</h2>
1542 @ <p>This page was generated because Fossil believes it has
1543 @ detected an SQL injection attack. If you believe you are seeing
1544 @ this in error, contact the developers on the Fossil-SCM Forum. Type
 
 
1545 @ "fossil-scm forum" into any search engine to locate the Fossil-SCM Forum.
1546 style_finish_page();
1547 cgi_set_status(404,"Robot Attack Detected");
1548 cgi_reply();
 
1549 exit(0);
1550 }
1551
1552 /*
1553 ** If looks_like_sql_injection() returns true for the given string, calls
@@ -1563,13 +1569,13 @@
1563 ** the server with dozens or hundreds of SQL injection attempts per second
1564 ** against pages (such as /vdiff) that are expensive to compute. In other
1565 ** words, this is an effort to reduce the CPU load imposed by malicious
1566 ** spiders. It is not an effect defense against SQL injection vulnerabilities.
1567 */
1568 void cgi_value_spider_check(const char *zTxt){
1569 if( g.zLogin==0 && looks_like_sql_injection(zTxt) ){
1570 cgi_begone_spider();
1571 }
1572 }
1573
1574 /*
1575 ** A variant of cgi_parameter() with the same semantics except that if
@@ -1578,11 +1584,11 @@
1578 */
1579 const char *cgi_parameter_nosql(const char *zName, const char *zDefault){
1580 const char *zTxt = cgi_parameter(zName, zDefault);
1581
1582 if( zTxt!=zDefault ){
1583 cgi_value_spider_check(zTxt);
1584 }
1585 return zTxt;
1586 }
1587
1588 /*
@@ -1770,11 +1776,11 @@
1770 switch( eDest ){
1771 case 0: {
1772 cgi_printf("%h = %h <br>\n", zName, aParamQP[i].zValue);
1773 break;
1774 }
1775 case 1: {
1776 fossil_trace("%s = %s\n", zName, aParamQP[i].zValue);
1777 break;
1778 }
1779 case 2: {
1780 cgi_debug("%s = %s\n", zName, aParamQP[i].zValue);
@@ -2704,5 +2710,43 @@
2704 const char *zAgent = P("HTTP_USER_AGENT");
2705 if( zAgent==0 ) return 0;
2706 if( sqlite3_strglob("*iPad*", zAgent)==0 ) return 0;
2707 return sqlite3_strlike("%mobile%", zAgent, 0)==0;
2708 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2709
--- src/cgi.c
+++ src/cgi.c
@@ -749,10 +749,11 @@
749 const char *zName; /* Parameter or cookie name */
750 const char *zValue; /* Value of the query parameter or cookie */
751 int seq; /* Order of insertion */
752 char isQP; /* True for query parameters */
753 char cTag; /* Tag on query parameters */
754 char isFetched; /* 1 if the var is requested via P/PD() */
755 } *aParamQP; /* An array of all parameters and cookies */
756
757 /*
758 ** Add another query parameter or cookie to the parameter set.
759 ** zName is the name of the query parameter or cookie and zValue
@@ -776,10 +777,11 @@
777 fprintf(stderr, "# cgi: %s = [%s]\n", zName, zValue);
778 }
779 aParamQP[nUsedQP].seq = seqQP++;
780 aParamQP[nUsedQP].isQP = isQP;
781 aParamQP[nUsedQP].cTag = 0;
782 aParamQP[nUsedQP].isFetched = 0;
783 nUsedQP++;
784 sortQP = 1;
785 }
786
787 /*
@@ -1503,10 +1505,11 @@
1505 while( lo<=hi ){
1506 mid = (lo+hi)/2;
1507 c = fossil_strcmp(aParamQP[mid].zName, zName);
1508 if( c==0 ){
1509 CGIDEBUG(("mem-match [%s] = [%s]\n", zName, aParamQP[mid].zValue));
1510 aParamQP[mid].isFetched = 1;
1511 return aParamQP[mid].zValue;
1512 }else if( c>0 ){
1513 hi = mid-1;
1514 }else{
1515 lo = mid+1;
@@ -1530,24 +1533,27 @@
1533 }
1534
1535 /*
1536 ** Renders the "begone, spider" page and exits.
1537 */
1538 static void cgi_begone_spider(const char *zName){
1539 Blob content = empty_blob;
 
1540 cgi_set_content(&content);
1541 style_set_current_feature("test");
1542 style_submenu_enable(0);
1543 style_header("Malicious Query Detected");
1544 @ <h2>Begone, Knave!</h2>
1545 @ <p>This page was generated because Fossil detected an (unsuccessful)
1546 @ SQL injection attack or other nefarious content in your HTTP request.
1547 @
1548 @ <p>If you believe you are innocent and have reached this page in error,
1549 @ contact the Fossil developers on the Fossil-SCM Forum. Type
1550 @ "fossil-scm forum" into any search engine to locate the Fossil-SCM Forum.
1551 style_finish_page();
1552 cgi_set_status(418,"I'm a teapot");
1553 cgi_reply();
1554 fossil_errorlog("possible hack attempt - 418 response on \"%s\"", zName);
1555 exit(0);
1556 }
1557
1558 /*
1559 ** If looks_like_sql_injection() returns true for the given string, calls
@@ -1563,13 +1569,13 @@
1569 ** the server with dozens or hundreds of SQL injection attempts per second
1570 ** against pages (such as /vdiff) that are expensive to compute. In other
1571 ** words, this is an effort to reduce the CPU load imposed by malicious
1572 ** spiders. It is not an effect defense against SQL injection vulnerabilities.
1573 */
1574 void cgi_value_spider_check(const char *zTxt, const char *zName){
1575 if( g.zLogin==0 && looks_like_sql_injection(zTxt) ){
1576 cgi_begone_spider(zName);
1577 }
1578 }
1579
1580 /*
1581 ** A variant of cgi_parameter() with the same semantics except that if
@@ -1578,11 +1584,11 @@
1584 */
1585 const char *cgi_parameter_nosql(const char *zName, const char *zDefault){
1586 const char *zTxt = cgi_parameter(zName, zDefault);
1587
1588 if( zTxt!=zDefault ){
1589 cgi_value_spider_check(zTxt, zName);
1590 }
1591 return zTxt;
1592 }
1593
1594 /*
@@ -1770,11 +1776,11 @@
1776 switch( eDest ){
1777 case 0: {
1778 cgi_printf("%h = %h <br>\n", zName, aParamQP[i].zValue);
1779 break;
1780 }
1781 case 1: {
1782 fossil_trace("%s = %s\n", zName, aParamQP[i].zValue);
1783 break;
1784 }
1785 case 2: {
1786 cgi_debug("%s = %s\n", zName, aParamQP[i].zValue);
@@ -2704,5 +2710,43 @@
2710 const char *zAgent = P("HTTP_USER_AGENT");
2711 if( zAgent==0 ) return 0;
2712 if( sqlite3_strglob("*iPad*", zAgent)==0 ) return 0;
2713 return sqlite3_strlike("%mobile%", zAgent, 0)==0;
2714 }
2715
2716 /*
2717 ** Look for query or POST parameters that:
2718 **
2719 ** (1) Have not been used
2720 ** (2) Appear to be malicious attempts to break into or otherwise
2721 ** harm the system, for example via SQL injection
2722 **
2723 ** If any such parameters are seen, a 418 ("I'm a teapot") return is
2724 ** generated and processing aborts - this routine does not return.
2725 **
2726 ** When Fossil is launched via CGI from althttpd, the 418 return signals
2727 ** the webserver to put the requestor IP address into "timeout", blocking
2728 ** subsequent requests for 5 minutes.
2729 **
2730 ** Fossil is not subject to any SQL injections, as far as anybody knows.
2731 ** This routine is not necessary for the security of the system (though
2732 ** an extra layer of security never hurts). The main purpose here is
2733 ** to shutdown malicious attack spiders and prevent them from burning
2734 ** lots of CPU cycles and bogging down the website. In other words, the
2735 ** objective of this routine is to help prevent denial-of-service.
2736 **
2737 ** Usage Hint: Put a call to this routine as late in the webpage
2738 ** implementation as possible, ideally just before it begins doing
2739 ** potentially CPU-intensive computations and after all query parameters
2740 ** have been consulted.
2741 */
2742 void cgi_check_for_malice(void){
2743 struct QParam * pParam;
2744 int i;
2745 for(i = 0; i < nUsedQP; ++i){
2746 pParam = &aParamQP[i];
2747 if(0 == pParam->isFetched
2748 && fossil_islower(pParam->zName[0])){
2749 cgi_value_spider_check(pParam->zValue, pParam->zName);
2750 }
2751 }
2752 }
2753
--- src/clone.c
+++ src/clone.c
@@ -398,10 +398,11 @@
398398
** Provide a simple page that enables newbies to download the latest tarball or
399399
** ZIP archive, and provides instructions on how to clone.
400400
*/
401401
void download_page(void){
402402
login_check_credentials();
403
+ cgi_check_for_malice();
403404
style_header("Download Page");
404405
if( !g.perm.Zip ){
405406
@ <p>Bummer. You do not have permission to download.
406407
if( g.zLogin==0 || g.zLogin[0]==0 ){
407408
@ Maybe it would work better if you
408409
--- src/clone.c
+++ src/clone.c
@@ -398,10 +398,11 @@
398 ** Provide a simple page that enables newbies to download the latest tarball or
399 ** ZIP archive, and provides instructions on how to clone.
400 */
401 void download_page(void){
402 login_check_credentials();
 
403 style_header("Download Page");
404 if( !g.perm.Zip ){
405 @ <p>Bummer. You do not have permission to download.
406 if( g.zLogin==0 || g.zLogin[0]==0 ){
407 @ Maybe it would work better if you
408
--- src/clone.c
+++ src/clone.c
@@ -398,10 +398,11 @@
398 ** Provide a simple page that enables newbies to download the latest tarball or
399 ** ZIP archive, and provides instructions on how to clone.
400 */
401 void download_page(void){
402 login_check_credentials();
403 cgi_check_for_malice();
404 style_header("Download Page");
405 if( !g.perm.Zip ){
406 @ <p>Bummer. You do not have permission to download.
407 if( g.zLogin==0 || g.zLogin[0]==0 ){
408 @ Maybe it would work better if you
409
--- src/descendants.c
+++ src/descendants.c
@@ -576,10 +576,11 @@
576576
}
577577
if( showClosed || showAll ){
578578
style_submenu_element("Open", "%s", url_render(&url, 0, 0, 0, 0));
579579
}
580580
url_reset(&url);
581
+ cgi_check_for_malice();
581582
style_set_current_feature("leaves");
582583
style_header("Leaves");
583584
login_anonymous_available();
584585
timeline_ss_submenu();
585586
#if 0
586587
--- src/descendants.c
+++ src/descendants.c
@@ -576,10 +576,11 @@
576 }
577 if( showClosed || showAll ){
578 style_submenu_element("Open", "%s", url_render(&url, 0, 0, 0, 0));
579 }
580 url_reset(&url);
 
581 style_set_current_feature("leaves");
582 style_header("Leaves");
583 login_anonymous_available();
584 timeline_ss_submenu();
585 #if 0
586
--- src/descendants.c
+++ src/descendants.c
@@ -576,10 +576,11 @@
576 }
577 if( showClosed || showAll ){
578 style_submenu_element("Open", "%s", url_render(&url, 0, 0, 0, 0));
579 }
580 url_reset(&url);
581 cgi_check_for_malice();
582 style_set_current_feature("leaves");
583 style_header("Leaves");
584 login_anonymous_available();
585 timeline_ss_submenu();
586 #if 0
587
+1
--- src/diff.c
+++ src/diff.c
@@ -3581,10 +3581,11 @@
35813581
zLimit = P("limit");
35823582
showLog = PB("log");
35833583
fileVers = PB("filevers");
35843584
ignoreWs = PB("w");
35853585
if( ignoreWs ) annFlags |= DIFF_IGNORE_ALLWS;
3586
+ cgi_check_for_malice();
35863587
35873588
/* compute the annotation */
35883589
annotate_file(&ann, zFilename, zRevision, zLimit, zOrigin, annFlags);
35893590
zCI = ann.aVers[0].zMUuid;
35903591
35913592
--- src/diff.c
+++ src/diff.c
@@ -3581,10 +3581,11 @@
3581 zLimit = P("limit");
3582 showLog = PB("log");
3583 fileVers = PB("filevers");
3584 ignoreWs = PB("w");
3585 if( ignoreWs ) annFlags |= DIFF_IGNORE_ALLWS;
 
3586
3587 /* compute the annotation */
3588 annotate_file(&ann, zFilename, zRevision, zLimit, zOrigin, annFlags);
3589 zCI = ann.aVers[0].zMUuid;
3590
3591
--- src/diff.c
+++ src/diff.c
@@ -3581,10 +3581,11 @@
3581 zLimit = P("limit");
3582 showLog = PB("log");
3583 fileVers = PB("filevers");
3584 ignoreWs = PB("w");
3585 if( ignoreWs ) annFlags |= DIFF_IGNORE_ALLWS;
3586 cgi_check_for_malice();
3587
3588 /* compute the annotation */
3589 annotate_file(&ann, zFilename, zRevision, zLimit, zOrigin, annFlags);
3590 zCI = ann.aVers[0].zMUuid;
3591
3592
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1221,10 +1221,11 @@
12211221
*/
12221222
void vpatch_page(void){
12231223
const char *zFrom = P("from");
12241224
const char *zTo = P("to");
12251225
DiffConfig DCfg;
1226
+ cgi_check_for_malice();
12261227
login_check_credentials();
12271228
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
12281229
if( zFrom==0 || zTo==0 ) fossil_redirect_home();
12291230
12301231
fossil_nice_default();
12311232
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1221,10 +1221,11 @@
1221 */
1222 void vpatch_page(void){
1223 const char *zFrom = P("from");
1224 const char *zTo = P("to");
1225 DiffConfig DCfg;
 
1226 login_check_credentials();
1227 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1228 if( zFrom==0 || zTo==0 ) fossil_redirect_home();
1229
1230 fossil_nice_default();
1231
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1221,10 +1221,11 @@
1221 */
1222 void vpatch_page(void){
1223 const char *zFrom = P("from");
1224 const char *zTo = P("to");
1225 DiffConfig DCfg;
1226 cgi_check_for_malice();
1227 login_check_credentials();
1228 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1229 if( zFrom==0 || zTo==0 ) fossil_redirect_home();
1230
1231 fossil_nice_default();
1232
+2 -1
--- src/dispatch.c
+++ src/dispatch.c
@@ -813,15 +813,16 @@
813813
*/
814814
void help_page(void){
815815
const char *zCmd = P("cmd");
816816
817817
if( zCmd==0 ) zCmd = P("name");
818
+ cgi_check_for_malice();
818819
if( zCmd && *zCmd ){
819820
int rc;
820821
const CmdOrPage *pCmd = 0;
821822
822
- style_set_current_feature("tkt");
823
+ style_set_current_feature("tkt");
823824
style_header("Help: %s", zCmd);
824825
825826
style_submenu_element("Command-List", "%R/help");
826827
rc = dispatch_name_search(zCmd, CMDFLAG_ANY|CMDFLAG_PREFIX, &pCmd);
827828
if( *zCmd=='/' ){
828829
--- src/dispatch.c
+++ src/dispatch.c
@@ -813,15 +813,16 @@
813 */
814 void help_page(void){
815 const char *zCmd = P("cmd");
816
817 if( zCmd==0 ) zCmd = P("name");
 
818 if( zCmd && *zCmd ){
819 int rc;
820 const CmdOrPage *pCmd = 0;
821
822 style_set_current_feature("tkt");
823 style_header("Help: %s", zCmd);
824
825 style_submenu_element("Command-List", "%R/help");
826 rc = dispatch_name_search(zCmd, CMDFLAG_ANY|CMDFLAG_PREFIX, &pCmd);
827 if( *zCmd=='/' ){
828
--- src/dispatch.c
+++ src/dispatch.c
@@ -813,15 +813,16 @@
813 */
814 void help_page(void){
815 const char *zCmd = P("cmd");
816
817 if( zCmd==0 ) zCmd = P("name");
818 cgi_check_for_malice();
819 if( zCmd && *zCmd ){
820 int rc;
821 const CmdOrPage *pCmd = 0;
822
823 style_set_current_feature("tkt");
824 style_header("Help: %s", zCmd);
825
826 style_submenu_element("Command-List", "%R/help");
827 rc = dispatch_name_search(zCmd, CMDFLAG_ANY|CMDFLAG_PREFIX, &pCmd);
828 if( *zCmd=='/' ){
829
+2
--- src/doc.c
+++ src/doc.c
@@ -1051,10 +1051,11 @@
10511051
Th_Store("doc_version", db_text(0, "SELECT '[' || substr(uuid,1,10) || ']'"
10521052
" FROM blob WHERE rid=%d", vid));
10531053
Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
10541054
" WHERE objid=%d AND type='ci'", vid));
10551055
}
1056
+ cgi_check_for_malice();
10561057
document_render(&filebody, zMime, zDfltTitle, zName);
10571058
if( nMiss>=count(azSuffix) ) cgi_set_status(404, "Not Found");
10581059
db_end_transaction(0);
10591060
return;
10601061
@@ -1242,8 +1243,9 @@
12421243
*/
12431244
void doc_search_page(void){
12441245
const int isSearch = P("s")!=0;
12451246
login_check_credentials();
12461247
style_header("Document Search%s", isSearch ? " Results" : "");
1248
+ cgi_check_for_malice();
12471249
search_screen(SRCH_DOC, 0);
12481250
style_finish_page();
12491251
}
12501252
--- src/doc.c
+++ src/doc.c
@@ -1051,10 +1051,11 @@
1051 Th_Store("doc_version", db_text(0, "SELECT '[' || substr(uuid,1,10) || ']'"
1052 " FROM blob WHERE rid=%d", vid));
1053 Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
1054 " WHERE objid=%d AND type='ci'", vid));
1055 }
 
1056 document_render(&filebody, zMime, zDfltTitle, zName);
1057 if( nMiss>=count(azSuffix) ) cgi_set_status(404, "Not Found");
1058 db_end_transaction(0);
1059 return;
1060
@@ -1242,8 +1243,9 @@
1242 */
1243 void doc_search_page(void){
1244 const int isSearch = P("s")!=0;
1245 login_check_credentials();
1246 style_header("Document Search%s", isSearch ? " Results" : "");
 
1247 search_screen(SRCH_DOC, 0);
1248 style_finish_page();
1249 }
1250
--- src/doc.c
+++ src/doc.c
@@ -1051,10 +1051,11 @@
1051 Th_Store("doc_version", db_text(0, "SELECT '[' || substr(uuid,1,10) || ']'"
1052 " FROM blob WHERE rid=%d", vid));
1053 Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
1054 " WHERE objid=%d AND type='ci'", vid));
1055 }
1056 cgi_check_for_malice();
1057 document_render(&filebody, zMime, zDfltTitle, zName);
1058 if( nMiss>=count(azSuffix) ) cgi_set_status(404, "Not Found");
1059 db_end_transaction(0);
1060 return;
1061
@@ -1242,8 +1243,9 @@
1243 */
1244 void doc_search_page(void){
1245 const int isSearch = P("s")!=0;
1246 login_check_credentials();
1247 style_header("Document Search%s", isSearch ? " Results" : "");
1248 cgi_check_for_malice();
1249 search_screen(SRCH_DOC, 0);
1250 style_finish_page();
1251 }
1252
--- src/event.c
+++ src/event.c
@@ -129,10 +129,11 @@
129129
}
130130
verboseFlag = (zVerbose!=0) && !is_false(zVerbose);
131131
132132
/* Extract the event content.
133133
*/
134
+ cgi_check_for_malice();
134135
pTNote = manifest_get(rid, CFTYPE_EVENT, 0);
135136
if( pTNote==0 ){
136137
fossil_fatal("Object #%d is not a tech-note", rid);
137138
}
138139
zMimetype = wiki_filter_mimetypes(PD("mimetype",pTNote->zMimetype));
139140
--- src/event.c
+++ src/event.c
@@ -129,10 +129,11 @@
129 }
130 verboseFlag = (zVerbose!=0) && !is_false(zVerbose);
131
132 /* Extract the event content.
133 */
 
134 pTNote = manifest_get(rid, CFTYPE_EVENT, 0);
135 if( pTNote==0 ){
136 fossil_fatal("Object #%d is not a tech-note", rid);
137 }
138 zMimetype = wiki_filter_mimetypes(PD("mimetype",pTNote->zMimetype));
139
--- src/event.c
+++ src/event.c
@@ -129,10 +129,11 @@
129 }
130 verboseFlag = (zVerbose!=0) && !is_false(zVerbose);
131
132 /* Extract the event content.
133 */
134 cgi_check_for_malice();
135 pTNote = manifest_get(rid, CFTYPE_EVENT, 0);
136 if( pTNote==0 ){
137 fossil_fatal("Object #%d is not a tech-note", rid);
138 }
139 zMimetype = wiki_filter_mimetypes(PD("mimetype",pTNote->zMimetype));
140
--- src/finfo.c
+++ src/finfo.c
@@ -423,10 +423,11 @@
423423
}else{
424424
compute_direct_ancestors(ridFrom);
425425
}
426426
}
427427
url_add_parameter(&url, "name", zFilename);
428
+ cgi_check_for_malice();
428429
blob_zero(&sql);
429430
if( ridCi ){
430431
/* If we will be tracking changes across renames, some extra temp
431432
** tables (implemented as CTEs) are required */
432433
blob_append_sql(&sql,
433434
--- src/finfo.c
+++ src/finfo.c
@@ -423,10 +423,11 @@
423 }else{
424 compute_direct_ancestors(ridFrom);
425 }
426 }
427 url_add_parameter(&url, "name", zFilename);
 
428 blob_zero(&sql);
429 if( ridCi ){
430 /* If we will be tracking changes across renames, some extra temp
431 ** tables (implemented as CTEs) are required */
432 blob_append_sql(&sql,
433
--- src/finfo.c
+++ src/finfo.c
@@ -423,10 +423,11 @@
423 }else{
424 compute_direct_ancestors(ridFrom);
425 }
426 }
427 url_add_parameter(&url, "name", zFilename);
428 cgi_check_for_malice();
429 blob_zero(&sql);
430 if( ridCi ){
431 /* If we will be tracking changes across renames, some extra temp
432 ** tables (implemented as CTEs) are required */
433 blob_append_sql(&sql,
434
--- src/forum.c
+++ src/forum.c
@@ -1155,10 +1155,11 @@
11551155
return;
11561156
}
11571157
if( zName==0 ){
11581158
webpage_error("Missing \"name=\" query parameter");
11591159
}
1160
+ cgi_check_for_malice();
11601161
fpid = symbolic_name_to_rid(zName, "f");
11611162
if( fpid<=0 ){
11621163
if( fpid==0 ){
11631164
webpage_notfound_error("Unknown forum id: \"%s\"", zName);
11641165
}else{
@@ -1902,10 +1903,11 @@
19021903
srchFlags = search_restrict(SRCH_FORUM);
19031904
if( !g.perm.RdForum ){
19041905
login_needed(g.anon.RdForum);
19051906
return;
19061907
}
1908
+ cgi_check_for_malice();
19071909
style_set_current_feature("forum");
19081910
style_header( "%s", isSearch ? "Forum Search Results" : "Forum" );
19091911
style_submenu_element("Timeline", "%R/timeline?ss=v&y=f&vfx");
19101912
if( g.perm.WrForum ){
19111913
style_submenu_element("New Thread","%R/forumnew");
19121914
--- src/forum.c
+++ src/forum.c
@@ -1155,10 +1155,11 @@
1155 return;
1156 }
1157 if( zName==0 ){
1158 webpage_error("Missing \"name=\" query parameter");
1159 }
 
1160 fpid = symbolic_name_to_rid(zName, "f");
1161 if( fpid<=0 ){
1162 if( fpid==0 ){
1163 webpage_notfound_error("Unknown forum id: \"%s\"", zName);
1164 }else{
@@ -1902,10 +1903,11 @@
1902 srchFlags = search_restrict(SRCH_FORUM);
1903 if( !g.perm.RdForum ){
1904 login_needed(g.anon.RdForum);
1905 return;
1906 }
 
1907 style_set_current_feature("forum");
1908 style_header( "%s", isSearch ? "Forum Search Results" : "Forum" );
1909 style_submenu_element("Timeline", "%R/timeline?ss=v&y=f&vfx");
1910 if( g.perm.WrForum ){
1911 style_submenu_element("New Thread","%R/forumnew");
1912
--- src/forum.c
+++ src/forum.c
@@ -1155,10 +1155,11 @@
1155 return;
1156 }
1157 if( zName==0 ){
1158 webpage_error("Missing \"name=\" query parameter");
1159 }
1160 cgi_check_for_malice();
1161 fpid = symbolic_name_to_rid(zName, "f");
1162 if( fpid<=0 ){
1163 if( fpid==0 ){
1164 webpage_notfound_error("Unknown forum id: \"%s\"", zName);
1165 }else{
@@ -1902,10 +1903,11 @@
1903 srchFlags = search_restrict(SRCH_FORUM);
1904 if( !g.perm.RdForum ){
1905 login_needed(g.anon.RdForum);
1906 return;
1907 }
1908 cgi_check_for_malice();
1909 style_set_current_feature("forum");
1910 style_header( "%s", isSearch ? "Forum Search Results" : "Forum" );
1911 style_submenu_element("Timeline", "%R/timeline?ss=v&y=f&vfx");
1912 if( g.perm.WrForum ){
1913 style_submenu_element("New Thread","%R/forumnew");
1914
+16
--- src/info.c
+++ src/info.c
@@ -506,10 +506,11 @@
506506
style_header("Check-in Information Error");
507507
@ No such object: %h(PD("name",""))
508508
style_finish_page();
509509
return;
510510
}
511
+ cgi_check_for_malice();
511512
zHash = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
512513
style_header("Tags and Properties");
513514
zType = whatis_rid_type_label(rid);
514515
if(!zType) zType = "Artifact";
515516
@ <h1>Tags and Properties for %s(zType) \
@@ -660,10 +661,11 @@
660661
rid, rid
661662
);
662663
zBrName = branch_of_rid(rid);
663664
664665
diffType = preferred_diff_type();
666
+ cgi_check_for_malice();
665667
if( db_step(&q1)==SQLITE_ROW ){
666668
const char *zUuid = db_column_text(&q1, 0);
667669
int nUuid = db_column_bytes(&q1, 0);
668670
char *zEUser, *zEComment;
669671
const char *zUser;
@@ -1001,10 +1003,11 @@
10011003
}
10021004
if( strcmp(zModAction,"approve")==0 ){
10031005
moderation_approve('w', rid);
10041006
}
10051007
}
1008
+ cgi_check_for_malice();
10061009
style_header("Update of \"%h\"", pWiki->zWikiTitle);
10071010
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
10081011
zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", pWiki->rDate);
10091012
style_submenu_element("Raw", "%R/artifact/%s", zUuid);
10101013
style_submenu_element("History", "%R/whistory?name=%t", pWiki->zWikiTitle);
@@ -1246,10 +1249,11 @@
12461249
}
12471250
pCfg = construct_diff_flags(diffType, &DCfg);
12481251
if( DCfg.diffFlags & DIFF_IGNORE_ALLWS ){
12491252
blob_appendf(&qp, "&w");
12501253
}
1254
+ cgi_check_for_malice();
12511255
style_set_current_feature("vdiff");
12521256
if( zBranch==0 ){
12531257
style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo);
12541258
}
12551259
if( diffType!=0 ){
@@ -1778,10 +1782,11 @@
17781782
}
17791783
db_finalize(&q);
17801784
}
17811785
if( v1==0 || v2==0 ) fossil_redirect_home();
17821786
zRe = P("regex");
1787
+ cgi_check_for_malice();
17831788
if( zRe ) re_compile(&pRe, zRe, 0);
17841789
if( verbose ) objdescFlags |= OBJDESC_DETAIL;
17851790
if( isPatch ){
17861791
Blob c1, c2, *pOut;
17871792
DiffConfig DCfg;
@@ -1853,18 +1858,21 @@
18531858
*/
18541859
void rawartifact_page(void){
18551860
int rid = 0;
18561861
char *zUuid;
18571862
1863
+ (void)P("at")/*for cgi_check_for_malice()*/;
1864
+ (void)P("m");
18581865
if( P("ci") ){
18591866
rid = artifact_from_ci_and_filename(0);
18601867
}
18611868
if( rid==0 ){
18621869
rid = name_to_rid_www("name");
18631870
}
18641871
login_check_credentials();
18651872
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1873
+ cgi_check_for_malice();
18661874
if( rid==0 ) fossil_redirect_home();
18671875
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
18681876
etag_check(ETAG_HASH, zUuid);
18691877
if( fossil_strcmp(P("name"), zUuid)==0 && login_is_nobody() ){
18701878
g.isConst = 1;
@@ -1885,10 +1893,13 @@
18851893
*/
18861894
void secure_rawartifact_page(void){
18871895
int rid = 0;
18881896
const char *zName = PD("name", "");
18891897
1898
+ (void)P("at")/*for cgi_check_for_malice()*/;
1899
+ (void)P("m");
1900
+ cgi_check_for_malice();
18901901
login_check_credentials();
18911902
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
18921903
rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName);
18931904
if( rid==0 ){
18941905
cgi_set_status(404, "Not Found");
@@ -1934,10 +1945,11 @@
19341945
ajax_route_error(400, "Just testing client-side error handling.");
19351946
return;
19361947
}
19371948
19381949
login_check_credentials();
1950
+ cgi_check_for_malice();
19391951
if( !g.perm.Read ){
19401952
ajax_route_error(403, "Access requires Read permissions.");
19411953
return;
19421954
}
19431955
#if 1
@@ -2115,10 +2127,11 @@
21152127
21162128
rid = name_to_rid_www("name");
21172129
login_check_credentials();
21182130
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
21192131
if( rid==0 ) fossil_redirect_home();
2132
+ cgi_check_for_malice();
21202133
if( g.perm.Admin ){
21212134
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
21222135
if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
21232136
style_submenu_element("Unshun", "%R/shun?accept=%s&sub=1#delshun", zUuid);
21242137
}else{
@@ -2421,10 +2434,11 @@
24212434
int isBranchCI = 0; /* ci= refers to a branch name */
24222435
char *zHeader = 0;
24232436
24242437
login_check_credentials();
24252438
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
2439
+ cgi_check_for_malice();
24262440
style_set_current_feature("artifact");
24272441
24282442
/* Capture and normalize the name= and ci= query parameters */
24292443
if( zName==0 ){
24302444
zName = P("filename");
@@ -2752,10 +2766,11 @@
27522766
char *zTktTitle;
27532767
login_check_credentials();
27542768
if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; }
27552769
rid = name_to_rid_www("name");
27562770
if( rid==0 ){ fossil_redirect_home(); }
2771
+ cgi_check_for_malice();
27572772
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
27582773
if( g.perm.Admin ){
27592774
if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
27602775
style_submenu_element("Unshun", "%R/shun?accept=%s&sub=1#accshun", zUuid);
27612776
}else{
@@ -2862,10 +2877,11 @@
28622877
int rc;
28632878
int nLen;
28642879
28652880
zName = P("name");
28662881
if( zName==0 ) fossil_redirect_home();
2882
+ cgi_check_for_malice();
28672883
nLen = strlen(zName);
28682884
blob_set(&uuid, zName);
28692885
if( name_collisions(zName) ){
28702886
cgi_set_parameter("src","info");
28712887
ambiguous_page();
28722888
--- src/info.c
+++ src/info.c
@@ -506,10 +506,11 @@
506 style_header("Check-in Information Error");
507 @ No such object: %h(PD("name",""))
508 style_finish_page();
509 return;
510 }
 
511 zHash = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
512 style_header("Tags and Properties");
513 zType = whatis_rid_type_label(rid);
514 if(!zType) zType = "Artifact";
515 @ <h1>Tags and Properties for %s(zType) \
@@ -660,10 +661,11 @@
660 rid, rid
661 );
662 zBrName = branch_of_rid(rid);
663
664 diffType = preferred_diff_type();
 
665 if( db_step(&q1)==SQLITE_ROW ){
666 const char *zUuid = db_column_text(&q1, 0);
667 int nUuid = db_column_bytes(&q1, 0);
668 char *zEUser, *zEComment;
669 const char *zUser;
@@ -1001,10 +1003,11 @@
1001 }
1002 if( strcmp(zModAction,"approve")==0 ){
1003 moderation_approve('w', rid);
1004 }
1005 }
 
1006 style_header("Update of \"%h\"", pWiki->zWikiTitle);
1007 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
1008 zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", pWiki->rDate);
1009 style_submenu_element("Raw", "%R/artifact/%s", zUuid);
1010 style_submenu_element("History", "%R/whistory?name=%t", pWiki->zWikiTitle);
@@ -1246,10 +1249,11 @@
1246 }
1247 pCfg = construct_diff_flags(diffType, &DCfg);
1248 if( DCfg.diffFlags & DIFF_IGNORE_ALLWS ){
1249 blob_appendf(&qp, "&w");
1250 }
 
1251 style_set_current_feature("vdiff");
1252 if( zBranch==0 ){
1253 style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo);
1254 }
1255 if( diffType!=0 ){
@@ -1778,10 +1782,11 @@
1778 }
1779 db_finalize(&q);
1780 }
1781 if( v1==0 || v2==0 ) fossil_redirect_home();
1782 zRe = P("regex");
 
1783 if( zRe ) re_compile(&pRe, zRe, 0);
1784 if( verbose ) objdescFlags |= OBJDESC_DETAIL;
1785 if( isPatch ){
1786 Blob c1, c2, *pOut;
1787 DiffConfig DCfg;
@@ -1853,18 +1858,21 @@
1853 */
1854 void rawartifact_page(void){
1855 int rid = 0;
1856 char *zUuid;
1857
 
 
1858 if( P("ci") ){
1859 rid = artifact_from_ci_and_filename(0);
1860 }
1861 if( rid==0 ){
1862 rid = name_to_rid_www("name");
1863 }
1864 login_check_credentials();
1865 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
 
1866 if( rid==0 ) fossil_redirect_home();
1867 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
1868 etag_check(ETAG_HASH, zUuid);
1869 if( fossil_strcmp(P("name"), zUuid)==0 && login_is_nobody() ){
1870 g.isConst = 1;
@@ -1885,10 +1893,13 @@
1885 */
1886 void secure_rawartifact_page(void){
1887 int rid = 0;
1888 const char *zName = PD("name", "");
1889
 
 
 
1890 login_check_credentials();
1891 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1892 rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName);
1893 if( rid==0 ){
1894 cgi_set_status(404, "Not Found");
@@ -1934,10 +1945,11 @@
1934 ajax_route_error(400, "Just testing client-side error handling.");
1935 return;
1936 }
1937
1938 login_check_credentials();
 
1939 if( !g.perm.Read ){
1940 ajax_route_error(403, "Access requires Read permissions.");
1941 return;
1942 }
1943 #if 1
@@ -2115,10 +2127,11 @@
2115
2116 rid = name_to_rid_www("name");
2117 login_check_credentials();
2118 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
2119 if( rid==0 ) fossil_redirect_home();
 
2120 if( g.perm.Admin ){
2121 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
2122 if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
2123 style_submenu_element("Unshun", "%R/shun?accept=%s&sub=1#delshun", zUuid);
2124 }else{
@@ -2421,10 +2434,11 @@
2421 int isBranchCI = 0; /* ci= refers to a branch name */
2422 char *zHeader = 0;
2423
2424 login_check_credentials();
2425 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
 
2426 style_set_current_feature("artifact");
2427
2428 /* Capture and normalize the name= and ci= query parameters */
2429 if( zName==0 ){
2430 zName = P("filename");
@@ -2752,10 +2766,11 @@
2752 char *zTktTitle;
2753 login_check_credentials();
2754 if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; }
2755 rid = name_to_rid_www("name");
2756 if( rid==0 ){ fossil_redirect_home(); }
 
2757 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
2758 if( g.perm.Admin ){
2759 if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
2760 style_submenu_element("Unshun", "%R/shun?accept=%s&sub=1#accshun", zUuid);
2761 }else{
@@ -2862,10 +2877,11 @@
2862 int rc;
2863 int nLen;
2864
2865 zName = P("name");
2866 if( zName==0 ) fossil_redirect_home();
 
2867 nLen = strlen(zName);
2868 blob_set(&uuid, zName);
2869 if( name_collisions(zName) ){
2870 cgi_set_parameter("src","info");
2871 ambiguous_page();
2872
--- src/info.c
+++ src/info.c
@@ -506,10 +506,11 @@
506 style_header("Check-in Information Error");
507 @ No such object: %h(PD("name",""))
508 style_finish_page();
509 return;
510 }
511 cgi_check_for_malice();
512 zHash = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
513 style_header("Tags and Properties");
514 zType = whatis_rid_type_label(rid);
515 if(!zType) zType = "Artifact";
516 @ <h1>Tags and Properties for %s(zType) \
@@ -660,10 +661,11 @@
661 rid, rid
662 );
663 zBrName = branch_of_rid(rid);
664
665 diffType = preferred_diff_type();
666 cgi_check_for_malice();
667 if( db_step(&q1)==SQLITE_ROW ){
668 const char *zUuid = db_column_text(&q1, 0);
669 int nUuid = db_column_bytes(&q1, 0);
670 char *zEUser, *zEComment;
671 const char *zUser;
@@ -1001,10 +1003,11 @@
1003 }
1004 if( strcmp(zModAction,"approve")==0 ){
1005 moderation_approve('w', rid);
1006 }
1007 }
1008 cgi_check_for_malice();
1009 style_header("Update of \"%h\"", pWiki->zWikiTitle);
1010 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
1011 zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", pWiki->rDate);
1012 style_submenu_element("Raw", "%R/artifact/%s", zUuid);
1013 style_submenu_element("History", "%R/whistory?name=%t", pWiki->zWikiTitle);
@@ -1246,10 +1249,11 @@
1249 }
1250 pCfg = construct_diff_flags(diffType, &DCfg);
1251 if( DCfg.diffFlags & DIFF_IGNORE_ALLWS ){
1252 blob_appendf(&qp, "&w");
1253 }
1254 cgi_check_for_malice();
1255 style_set_current_feature("vdiff");
1256 if( zBranch==0 ){
1257 style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo);
1258 }
1259 if( diffType!=0 ){
@@ -1778,10 +1782,11 @@
1782 }
1783 db_finalize(&q);
1784 }
1785 if( v1==0 || v2==0 ) fossil_redirect_home();
1786 zRe = P("regex");
1787 cgi_check_for_malice();
1788 if( zRe ) re_compile(&pRe, zRe, 0);
1789 if( verbose ) objdescFlags |= OBJDESC_DETAIL;
1790 if( isPatch ){
1791 Blob c1, c2, *pOut;
1792 DiffConfig DCfg;
@@ -1853,18 +1858,21 @@
1858 */
1859 void rawartifact_page(void){
1860 int rid = 0;
1861 char *zUuid;
1862
1863 (void)P("at")/*for cgi_check_for_malice()*/;
1864 (void)P("m");
1865 if( P("ci") ){
1866 rid = artifact_from_ci_and_filename(0);
1867 }
1868 if( rid==0 ){
1869 rid = name_to_rid_www("name");
1870 }
1871 login_check_credentials();
1872 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1873 cgi_check_for_malice();
1874 if( rid==0 ) fossil_redirect_home();
1875 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
1876 etag_check(ETAG_HASH, zUuid);
1877 if( fossil_strcmp(P("name"), zUuid)==0 && login_is_nobody() ){
1878 g.isConst = 1;
@@ -1885,10 +1893,13 @@
1893 */
1894 void secure_rawartifact_page(void){
1895 int rid = 0;
1896 const char *zName = PD("name", "");
1897
1898 (void)P("at")/*for cgi_check_for_malice()*/;
1899 (void)P("m");
1900 cgi_check_for_malice();
1901 login_check_credentials();
1902 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1903 rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName);
1904 if( rid==0 ){
1905 cgi_set_status(404, "Not Found");
@@ -1934,10 +1945,11 @@
1945 ajax_route_error(400, "Just testing client-side error handling.");
1946 return;
1947 }
1948
1949 login_check_credentials();
1950 cgi_check_for_malice();
1951 if( !g.perm.Read ){
1952 ajax_route_error(403, "Access requires Read permissions.");
1953 return;
1954 }
1955 #if 1
@@ -2115,10 +2127,11 @@
2127
2128 rid = name_to_rid_www("name");
2129 login_check_credentials();
2130 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
2131 if( rid==0 ) fossil_redirect_home();
2132 cgi_check_for_malice();
2133 if( g.perm.Admin ){
2134 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
2135 if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
2136 style_submenu_element("Unshun", "%R/shun?accept=%s&sub=1#delshun", zUuid);
2137 }else{
@@ -2421,10 +2434,11 @@
2434 int isBranchCI = 0; /* ci= refers to a branch name */
2435 char *zHeader = 0;
2436
2437 login_check_credentials();
2438 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
2439 cgi_check_for_malice();
2440 style_set_current_feature("artifact");
2441
2442 /* Capture and normalize the name= and ci= query parameters */
2443 if( zName==0 ){
2444 zName = P("filename");
@@ -2752,10 +2766,11 @@
2766 char *zTktTitle;
2767 login_check_credentials();
2768 if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; }
2769 rid = name_to_rid_www("name");
2770 if( rid==0 ){ fossil_redirect_home(); }
2771 cgi_check_for_malice();
2772 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
2773 if( g.perm.Admin ){
2774 if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
2775 style_submenu_element("Unshun", "%R/shun?accept=%s&sub=1#accshun", zUuid);
2776 }else{
@@ -2862,10 +2877,11 @@
2877 int rc;
2878 int nLen;
2879
2880 zName = P("name");
2881 if( zName==0 ) fossil_redirect_home();
2882 cgi_check_for_malice();
2883 nLen = strlen(zName);
2884 blob_set(&uuid, zName);
2885 if( name_collisions(zName) ){
2886 cgi_set_parameter("src","info");
2887 ambiguous_page();
2888
--- src/login.c
+++ src/login.c
@@ -575,10 +575,11 @@
575575
/* If the "Reset Password" button in the form was pressed, render
576576
** the Request Password Reset page in place of this one. */
577577
login_reqpwreset_page();
578578
return;
579579
}
580
+ cgi_check_for_malice();
580581
login_check_credentials();
581582
fossil_redirect_to_https_if_needed(1);
582583
sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
583584
constant_time_cmp_function, 0, 0);
584585
zUsername = P("u");
585586
--- src/login.c
+++ src/login.c
@@ -575,10 +575,11 @@
575 /* If the "Reset Password" button in the form was pressed, render
576 ** the Request Password Reset page in place of this one. */
577 login_reqpwreset_page();
578 return;
579 }
 
580 login_check_credentials();
581 fossil_redirect_to_https_if_needed(1);
582 sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
583 constant_time_cmp_function, 0, 0);
584 zUsername = P("u");
585
--- src/login.c
+++ src/login.c
@@ -575,10 +575,11 @@
575 /* If the "Reset Password" button in the form was pressed, render
576 ** the Request Password Reset page in place of this one. */
577 login_reqpwreset_page();
578 return;
579 }
580 cgi_check_for_malice();
581 login_check_credentials();
582 fossil_redirect_to_https_if_needed(1);
583 sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
584 constant_time_cmp_function, 0, 0);
585 zUsername = P("u");
586
+9 -3
--- src/lookslike.c
+++ src/lookslike.c
@@ -462,16 +462,20 @@
462462
fossil_print("Has flag LOOK_SHORT: %s\n",(lookFlags&LOOK_SHORT)?"yes":"no");
463463
blob_reset(&blob);
464464
}
465465
466466
/*
467
-** Return true if z[i] is the whole word given by zWord
467
+** Return true if z[i] is the whole word given by zWord in a context that
468
+** might be an attempted SQL injection.
468469
*/
469470
static int isWholeWord(const char *z, unsigned int i, const char *zWord, int n){
470
- if( i>0 && fossil_isalnum(z[i-1]) ) return 0;
471
+ if( i==0 ) return 0;
471472
if( sqlite3_strnicmp(z+i, zWord, n)!=0 ) return 0;
473
+ if( fossil_isalnum(z[i-1]) ) return 0;
472474
if( fossil_isalnum(z[i+n]) ) return 0;
475
+ if( strchr("-)_", z[i-1])!=0 ) return 0;
476
+ if( strchr("(_", z[i+n])!=0 ) return 0;
473477
return 1;
474478
}
475479
476480
/*
477481
** Returns true if the given text contains certain keywords or
@@ -502,11 +506,13 @@
502506
case 'N':
503507
if( isWholeWord(zTxt, i, "null", 4) ) return 1;
504508
break;
505509
case 'o':
506510
case 'O':
507
- if( isWholeWord(zTxt, i, "order", 5) ) return 1;
511
+ if( isWholeWord(zTxt, i, "order", 5) && fossil_isspace(zTxt[i+5]) ){
512
+ return 1;
513
+ }
508514
if( isWholeWord(zTxt, i, "or", 2) ) return 1;
509515
break;
510516
case 's':
511517
case 'S':
512518
if( isWholeWord(zTxt, i, "select", 6) ) return 1;
513519
--- src/lookslike.c
+++ src/lookslike.c
@@ -462,16 +462,20 @@
462 fossil_print("Has flag LOOK_SHORT: %s\n",(lookFlags&LOOK_SHORT)?"yes":"no");
463 blob_reset(&blob);
464 }
465
466 /*
467 ** Return true if z[i] is the whole word given by zWord
 
468 */
469 static int isWholeWord(const char *z, unsigned int i, const char *zWord, int n){
470 if( i>0 && fossil_isalnum(z[i-1]) ) return 0;
471 if( sqlite3_strnicmp(z+i, zWord, n)!=0 ) return 0;
 
472 if( fossil_isalnum(z[i+n]) ) return 0;
 
 
473 return 1;
474 }
475
476 /*
477 ** Returns true if the given text contains certain keywords or
@@ -502,11 +506,13 @@
502 case 'N':
503 if( isWholeWord(zTxt, i, "null", 4) ) return 1;
504 break;
505 case 'o':
506 case 'O':
507 if( isWholeWord(zTxt, i, "order", 5) ) return 1;
 
 
508 if( isWholeWord(zTxt, i, "or", 2) ) return 1;
509 break;
510 case 's':
511 case 'S':
512 if( isWholeWord(zTxt, i, "select", 6) ) return 1;
513
--- src/lookslike.c
+++ src/lookslike.c
@@ -462,16 +462,20 @@
462 fossil_print("Has flag LOOK_SHORT: %s\n",(lookFlags&LOOK_SHORT)?"yes":"no");
463 blob_reset(&blob);
464 }
465
466 /*
467 ** Return true if z[i] is the whole word given by zWord in a context that
468 ** might be an attempted SQL injection.
469 */
470 static int isWholeWord(const char *z, unsigned int i, const char *zWord, int n){
471 if( i==0 ) return 0;
472 if( sqlite3_strnicmp(z+i, zWord, n)!=0 ) return 0;
473 if( fossil_isalnum(z[i-1]) ) return 0;
474 if( fossil_isalnum(z[i+n]) ) return 0;
475 if( strchr("-)_", z[i-1])!=0 ) return 0;
476 if( strchr("(_", z[i+n])!=0 ) return 0;
477 return 1;
478 }
479
480 /*
481 ** Returns true if the given text contains certain keywords or
@@ -502,11 +506,13 @@
506 case 'N':
507 if( isWholeWord(zTxt, i, "null", 4) ) return 1;
508 break;
509 case 'o':
510 case 'O':
511 if( isWholeWord(zTxt, i, "order", 5) && fossil_isspace(zTxt[i+5]) ){
512 return 1;
513 }
514 if( isWholeWord(zTxt, i, "or", 2) ) return 1;
515 break;
516 case 's':
517 case 'S':
518 if( isWholeWord(zTxt, i, "select", 6) ) return 1;
519
+1
--- src/name.c
+++ src/name.c
@@ -1651,10 +1651,11 @@
16511651
char *zSha1Bg;
16521652
char *zSha3Bg;
16531653
16541654
login_check_credentials();
16551655
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1656
+ cgi_check_for_malice();
16561657
style_header("List Of Artifacts");
16571658
style_submenu_element("250 Largest", "bigbloblist");
16581659
if( g.perm.Admin ){
16591660
style_submenu_element("Artifact Log", "rcvfromlist");
16601661
}
16611662
--- src/name.c
+++ src/name.c
@@ -1651,10 +1651,11 @@
1651 char *zSha1Bg;
1652 char *zSha3Bg;
1653
1654 login_check_credentials();
1655 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
 
1656 style_header("List Of Artifacts");
1657 style_submenu_element("250 Largest", "bigbloblist");
1658 if( g.perm.Admin ){
1659 style_submenu_element("Artifact Log", "rcvfromlist");
1660 }
1661
--- src/name.c
+++ src/name.c
@@ -1651,10 +1651,11 @@
1651 char *zSha1Bg;
1652 char *zSha3Bg;
1653
1654 login_check_credentials();
1655 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
1656 cgi_check_for_malice();
1657 style_header("List Of Artifacts");
1658 style_submenu_element("250 Largest", "bigbloblist");
1659 if( g.perm.Admin ){
1660 style_submenu_element("Artifact Log", "rcvfromlist");
1661 }
1662
--- src/search.c
+++ src/search.c
@@ -1219,10 +1219,11 @@
12191219
*/
12201220
void search_page(void){
12211221
const int isSearch = P("s")!=0;
12221222
login_check_credentials();
12231223
style_header("Search%s", isSearch ? " Results" : "");
1224
+ cgi_check_for_malice();
12241225
search_screen(SRCH_ALL, 1);
12251226
style_finish_page();
12261227
}
12271228
12281229
12291230
--- src/search.c
+++ src/search.c
@@ -1219,10 +1219,11 @@
1219 */
1220 void search_page(void){
1221 const int isSearch = P("s")!=0;
1222 login_check_credentials();
1223 style_header("Search%s", isSearch ? " Results" : "");
 
1224 search_screen(SRCH_ALL, 1);
1225 style_finish_page();
1226 }
1227
1228
1229
--- src/search.c
+++ src/search.c
@@ -1219,10 +1219,11 @@
1219 */
1220 void search_page(void){
1221 const int isSearch = P("s")!=0;
1222 login_check_credentials();
1223 style_header("Search%s", isSearch ? " Results" : "");
1224 cgi_check_for_malice();
1225 search_screen(SRCH_ALL, 1);
1226 style_finish_page();
1227 }
1228
1229
1230
+2
--- src/stat.c
+++ src/stat.c
@@ -807,10 +807,11 @@
807807
sqlite3_int64 fsize;
808808
char zBuf[100];
809809
810810
login_check_credentials();
811811
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
812
+ cgi_check_for_malice();
812813
style_set_current_feature("stat");
813814
style_header("Repository Table Sizes");
814815
style_adunit_config(ADUNIT_RIGHT_OK);
815816
style_submenu_element("Stat", "stat");
816817
if( g.perm.Admin ){
@@ -983,10 +984,11 @@
983984
*/
984985
if( !g.perm.Write && !db_get_boolean("artifact_stats_enable",0) ){
985986
login_needed(g.anon.Write);
986987
return;
987988
}
989
+ cgi_check_for_malice();
988990
fossil_nice_default();
989991
990992
style_set_current_feature("stat");
991993
style_header("Artifact Statistics");
992994
style_submenu_element("Repository Stats", "stat");
993995
--- src/stat.c
+++ src/stat.c
@@ -807,10 +807,11 @@
807 sqlite3_int64 fsize;
808 char zBuf[100];
809
810 login_check_credentials();
811 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
 
812 style_set_current_feature("stat");
813 style_header("Repository Table Sizes");
814 style_adunit_config(ADUNIT_RIGHT_OK);
815 style_submenu_element("Stat", "stat");
816 if( g.perm.Admin ){
@@ -983,10 +984,11 @@
983 */
984 if( !g.perm.Write && !db_get_boolean("artifact_stats_enable",0) ){
985 login_needed(g.anon.Write);
986 return;
987 }
 
988 fossil_nice_default();
989
990 style_set_current_feature("stat");
991 style_header("Artifact Statistics");
992 style_submenu_element("Repository Stats", "stat");
993
--- src/stat.c
+++ src/stat.c
@@ -807,10 +807,11 @@
807 sqlite3_int64 fsize;
808 char zBuf[100];
809
810 login_check_credentials();
811 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
812 cgi_check_for_malice();
813 style_set_current_feature("stat");
814 style_header("Repository Table Sizes");
815 style_adunit_config(ADUNIT_RIGHT_OK);
816 style_submenu_element("Stat", "stat");
817 if( g.perm.Admin ){
@@ -983,10 +984,11 @@
984 */
985 if( !g.perm.Write && !db_get_boolean("artifact_stats_enable",0) ){
986 login_needed(g.anon.Write);
987 return;
988 }
989 cgi_check_for_malice();
990 fossil_nice_default();
991
992 style_set_current_feature("stat");
993 style_header("Artifact Statistics");
994 style_submenu_element("Repository Stats", "stat");
995
--- src/statrep.c
+++ src/statrep.c
@@ -912,10 +912,11 @@
912912
if( fossil_strcmp(zView, aViewType[i].zVal)==0 ){
913913
eType = aViewType[i].eType;
914914
break;
915915
}
916916
}
917
+ cgi_check_for_malice();
917918
if( eType!=RPT_NONE ){
918919
int nView = 0; /* Slots used in azView[] */
919920
for(i=0; i<count(aViewType); i++){
920921
azView[nView++] = aViewType[i].zVal;
921922
azView[nView++] = aViewType[i].zName;
922923
--- src/statrep.c
+++ src/statrep.c
@@ -912,10 +912,11 @@
912 if( fossil_strcmp(zView, aViewType[i].zVal)==0 ){
913 eType = aViewType[i].eType;
914 break;
915 }
916 }
 
917 if( eType!=RPT_NONE ){
918 int nView = 0; /* Slots used in azView[] */
919 for(i=0; i<count(aViewType); i++){
920 azView[nView++] = aViewType[i].zVal;
921 azView[nView++] = aViewType[i].zName;
922
--- src/statrep.c
+++ src/statrep.c
@@ -912,10 +912,11 @@
912 if( fossil_strcmp(zView, aViewType[i].zVal)==0 ){
913 eType = aViewType[i].eType;
914 break;
915 }
916 }
917 cgi_check_for_malice();
918 if( eType!=RPT_NONE ){
919 int nView = 0; /* Slots used in azView[] */
920 for(i=0; i<count(aViewType); i++){
921 azView[nView++] = aViewType[i].zVal;
922 azView[nView++] = aViewType[i].zName;
923
+1
--- src/tag.c
+++ src/tag.c
@@ -805,10 +805,11 @@
805805
806806
login_check_credentials();
807807
if( !g.perm.Read ){
808808
login_needed(g.anon.Read);
809809
}
810
+ cgi_check_for_malice();
810811
login_anonymous_available();
811812
style_header("Tags");
812813
style_adunit_config(ADUNIT_RIGHT_OK);
813814
style_submenu_element("Timeline", "tagtimeline");
814815
@ <h2>Non-propagating tags:</h2>
815816
--- src/tag.c
+++ src/tag.c
@@ -805,10 +805,11 @@
805
806 login_check_credentials();
807 if( !g.perm.Read ){
808 login_needed(g.anon.Read);
809 }
 
810 login_anonymous_available();
811 style_header("Tags");
812 style_adunit_config(ADUNIT_RIGHT_OK);
813 style_submenu_element("Timeline", "tagtimeline");
814 @ <h2>Non-propagating tags:</h2>
815
--- src/tag.c
+++ src/tag.c
@@ -805,10 +805,11 @@
805
806 login_check_credentials();
807 if( !g.perm.Read ){
808 login_needed(g.anon.Read);
809 }
810 cgi_check_for_malice();
811 login_anonymous_available();
812 style_header("Tags");
813 style_adunit_config(ADUNIT_RIGHT_OK);
814 style_submenu_element("Timeline", "tagtimeline");
815 @ <h2>Non-propagating tags:</h2>
816
+1
--- src/tar.c
+++ src/tar.c
@@ -831,10 +831,11 @@
831831
@ <input type="submit" value="Download">
832832
@ </form>
833833
style_finish_page();
834834
return;
835835
}
836
+ cgi_check_for_malice();
836837
blob_zero(&tarball);
837838
if( cache_read(&tarball, zKey)==0 ){
838839
tarball_of_checkin(rid, &tarball, zName, pInclude, pExclude, 0);
839840
cache_write(&tarball, zKey);
840841
}
841842
--- src/tar.c
+++ src/tar.c
@@ -831,10 +831,11 @@
831 @ <input type="submit" value="Download">
832 @ </form>
833 style_finish_page();
834 return;
835 }
 
836 blob_zero(&tarball);
837 if( cache_read(&tarball, zKey)==0 ){
838 tarball_of_checkin(rid, &tarball, zName, pInclude, pExclude, 0);
839 cache_write(&tarball, zKey);
840 }
841
--- src/tar.c
+++ src/tar.c
@@ -831,10 +831,11 @@
831 @ <input type="submit" value="Download">
832 @ </form>
833 style_finish_page();
834 return;
835 }
836 cgi_check_for_malice();
837 blob_zero(&tarball);
838 if( cache_read(&tarball, zKey)==0 ){
839 tarball_of_checkin(rid, &tarball, zName, pInclude, pExclude, 0);
840 cache_write(&tarball, zKey);
841 }
842
--- src/timeline.c
+++ src/timeline.c
@@ -2835,10 +2835,11 @@
28352835
28362836
if( zNewerButton ){
28372837
@ %z(chref("button","%s",zNewerButton))%h(zNewerButtonLabel)\
28382838
@ &nbsp;&uarr;</a>
28392839
}
2840
+ cgi_check_for_malice();
28402841
www_print_timeline(&q, tmFlags, zThisUser, zThisTag, zBrName,
28412842
selectedRid, secondaryRid, 0);
28422843
db_finalize(&q);
28432844
if( zOlderButton ){
28442845
@ %z(chref("button","%s",zOlderButton))%h(zOlderButtonLabel)\
28452846
--- src/timeline.c
+++ src/timeline.c
@@ -2835,10 +2835,11 @@
2835
2836 if( zNewerButton ){
2837 @ %z(chref("button","%s",zNewerButton))%h(zNewerButtonLabel)\
2838 @ &nbsp;&uarr;</a>
2839 }
 
2840 www_print_timeline(&q, tmFlags, zThisUser, zThisTag, zBrName,
2841 selectedRid, secondaryRid, 0);
2842 db_finalize(&q);
2843 if( zOlderButton ){
2844 @ %z(chref("button","%s",zOlderButton))%h(zOlderButtonLabel)\
2845
--- src/timeline.c
+++ src/timeline.c
@@ -2835,10 +2835,11 @@
2835
2836 if( zNewerButton ){
2837 @ %z(chref("button","%s",zNewerButton))%h(zNewerButtonLabel)\
2838 @ &nbsp;&uarr;</a>
2839 }
2840 cgi_check_for_malice();
2841 www_print_timeline(&q, tmFlags, zThisUser, zThisTag, zBrName,
2842 selectedRid, secondaryRid, 0);
2843 db_finalize(&q);
2844 if( zOlderButton ){
2845 @ %z(chref("button","%s",zOlderButton))%h(zOlderButtonLabel)\
2846
--- src/unversioned.c
+++ src/unversioned.c
@@ -542,10 +542,11 @@
542542
int showDel = 0;
543543
char zSzName[100];
544544
545545
login_check_credentials();
546546
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
547
+ cgi_check_for_malice();
547548
etag_check(ETAG_DATA,0);
548549
style_header("Unversioned Files");
549550
if( !db_table_exists("repository","unversioned") ){
550551
@ No unversioned files on this server
551552
style_finish_page();
@@ -654,10 +655,11 @@
654655
char *zSep = "[";
655656
Blob json;
656657
657658
login_check_credentials();
658659
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
660
+ cgi_check_for_malice();
659661
cgi_set_content_type("application/json");
660662
etag_check(ETAG_DATA,0);
661663
if( !db_table_exists("repository","unversioned") ){
662664
blob_init(&json, "[]", -1);
663665
cgi_set_content(&json);
664666
--- src/unversioned.c
+++ src/unversioned.c
@@ -542,10 +542,11 @@
542 int showDel = 0;
543 char zSzName[100];
544
545 login_check_credentials();
546 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
 
547 etag_check(ETAG_DATA,0);
548 style_header("Unversioned Files");
549 if( !db_table_exists("repository","unversioned") ){
550 @ No unversioned files on this server
551 style_finish_page();
@@ -654,10 +655,11 @@
654 char *zSep = "[";
655 Blob json;
656
657 login_check_credentials();
658 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
 
659 cgi_set_content_type("application/json");
660 etag_check(ETAG_DATA,0);
661 if( !db_table_exists("repository","unversioned") ){
662 blob_init(&json, "[]", -1);
663 cgi_set_content(&json);
664
--- src/unversioned.c
+++ src/unversioned.c
@@ -542,10 +542,11 @@
542 int showDel = 0;
543 char zSzName[100];
544
545 login_check_credentials();
546 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
547 cgi_check_for_malice();
548 etag_check(ETAG_DATA,0);
549 style_header("Unversioned Files");
550 if( !db_table_exists("repository","unversioned") ){
551 @ No unversioned files on this server
552 style_finish_page();
@@ -654,10 +655,11 @@
655 char *zSep = "[";
656 Blob json;
657
658 login_check_credentials();
659 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
660 cgi_check_for_malice();
661 cgi_set_content_type("application/json");
662 etag_check(ETAG_DATA,0);
663 if( !db_table_exists("repository","unversioned") ){
664 blob_init(&json, "[]", -1);
665 cgi_set_content(&json);
666
+5
--- src/wiki.c
+++ src/wiki.c
@@ -115,10 +115,11 @@
115115
*/
116116
void home_page(void){
117117
char *zPageName = db_get("project-name",0);
118118
char *zIndexPage = db_get("index-page",0);
119119
login_check_credentials();
120
+ cgi_check_for_malice();
120121
if( zIndexPage ){
121122
const char *zPathInfo = P("PATH_INFO");
122123
while( zIndexPage[0]=='/' ) zIndexPage++;
123124
while( zPathInfo[0]=='/' ) zPathInfo++;
124125
if( fossil_strcmp(zIndexPage, zPathInfo)==0 ) zIndexPage = 0;
@@ -550,10 +551,11 @@
550551
int noSubmenu = P("nsm")!=0 || g.isHome;
551552
552553
login_check_credentials();
553554
if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
554555
zPageName = P("name");
556
+ cgi_check_for_malice();
555557
if( zPageName==0 ){
556558
if( search_restrict(SRCH_WIKI)!=0 ){
557559
wiki_srchpage();
558560
}else{
559561
wiki_helppage();
@@ -1842,10 +1844,11 @@
18421844
blob_init(&w1, pW1->zWiki, -1);
18431845
zPid = P("pid");
18441846
if( ( zPid==0 || zPid[0] == 0 ) && pW1->nParent ){
18451847
zPid = pW1->azParent[0];
18461848
}
1849
+ cgi_check_for_malice();
18471850
if( zPid && zPid[0] != 0 ){
18481851
char *zDate;
18491852
rid2 = name_to_typed_rid(zPid, "w");
18501853
pW2 = manifest_get(rid2, CFTYPE_WIKI, 0);
18511854
blob_init(&w2, pW2->zWiki, -1);
@@ -1929,10 +1932,11 @@
19291932
if( showAll ){
19301933
style_submenu_element("Active", "%R/wcontent");
19311934
}else{
19321935
style_submenu_element("All", "%R/wcontent?all=1");
19331936
}
1937
+ cgi_check_for_malice();
19341938
showCkBr = db_exists(
19351939
"SELECT tag.tagname AS tn FROM tag JOIN tagxref USING(tagid) "
19361940
"WHERE ( tn GLOB 'wiki-checkin/*' OR tn GLOB 'wiki-branch/*' ) "
19371941
" AND TYPEOF(tagxref.value+0)='integer'" );
19381942
if( showCkBr ){
@@ -2006,10 +2010,11 @@
20062010
Stmt q;
20072011
const char *zTitle;
20082012
login_check_credentials();
20092013
if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
20102014
zTitle = PD("title","*");
2015
+ cgi_check_for_malice();
20112016
style_set_current_feature("wiki");
20122017
style_header("Wiki Pages Found");
20132018
@ <ul>
20142019
db_prepare(&q,
20152020
"SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'"
20162021
--- src/wiki.c
+++ src/wiki.c
@@ -115,10 +115,11 @@
115 */
116 void home_page(void){
117 char *zPageName = db_get("project-name",0);
118 char *zIndexPage = db_get("index-page",0);
119 login_check_credentials();
 
120 if( zIndexPage ){
121 const char *zPathInfo = P("PATH_INFO");
122 while( zIndexPage[0]=='/' ) zIndexPage++;
123 while( zPathInfo[0]=='/' ) zPathInfo++;
124 if( fossil_strcmp(zIndexPage, zPathInfo)==0 ) zIndexPage = 0;
@@ -550,10 +551,11 @@
550 int noSubmenu = P("nsm")!=0 || g.isHome;
551
552 login_check_credentials();
553 if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
554 zPageName = P("name");
 
555 if( zPageName==0 ){
556 if( search_restrict(SRCH_WIKI)!=0 ){
557 wiki_srchpage();
558 }else{
559 wiki_helppage();
@@ -1842,10 +1844,11 @@
1842 blob_init(&w1, pW1->zWiki, -1);
1843 zPid = P("pid");
1844 if( ( zPid==0 || zPid[0] == 0 ) && pW1->nParent ){
1845 zPid = pW1->azParent[0];
1846 }
 
1847 if( zPid && zPid[0] != 0 ){
1848 char *zDate;
1849 rid2 = name_to_typed_rid(zPid, "w");
1850 pW2 = manifest_get(rid2, CFTYPE_WIKI, 0);
1851 blob_init(&w2, pW2->zWiki, -1);
@@ -1929,10 +1932,11 @@
1929 if( showAll ){
1930 style_submenu_element("Active", "%R/wcontent");
1931 }else{
1932 style_submenu_element("All", "%R/wcontent?all=1");
1933 }
 
1934 showCkBr = db_exists(
1935 "SELECT tag.tagname AS tn FROM tag JOIN tagxref USING(tagid) "
1936 "WHERE ( tn GLOB 'wiki-checkin/*' OR tn GLOB 'wiki-branch/*' ) "
1937 " AND TYPEOF(tagxref.value+0)='integer'" );
1938 if( showCkBr ){
@@ -2006,10 +2010,11 @@
2006 Stmt q;
2007 const char *zTitle;
2008 login_check_credentials();
2009 if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
2010 zTitle = PD("title","*");
 
2011 style_set_current_feature("wiki");
2012 style_header("Wiki Pages Found");
2013 @ <ul>
2014 db_prepare(&q,
2015 "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'"
2016
--- src/wiki.c
+++ src/wiki.c
@@ -115,10 +115,11 @@
115 */
116 void home_page(void){
117 char *zPageName = db_get("project-name",0);
118 char *zIndexPage = db_get("index-page",0);
119 login_check_credentials();
120 cgi_check_for_malice();
121 if( zIndexPage ){
122 const char *zPathInfo = P("PATH_INFO");
123 while( zIndexPage[0]=='/' ) zIndexPage++;
124 while( zPathInfo[0]=='/' ) zPathInfo++;
125 if( fossil_strcmp(zIndexPage, zPathInfo)==0 ) zIndexPage = 0;
@@ -550,10 +551,11 @@
551 int noSubmenu = P("nsm")!=0 || g.isHome;
552
553 login_check_credentials();
554 if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
555 zPageName = P("name");
556 cgi_check_for_malice();
557 if( zPageName==0 ){
558 if( search_restrict(SRCH_WIKI)!=0 ){
559 wiki_srchpage();
560 }else{
561 wiki_helppage();
@@ -1842,10 +1844,11 @@
1844 blob_init(&w1, pW1->zWiki, -1);
1845 zPid = P("pid");
1846 if( ( zPid==0 || zPid[0] == 0 ) && pW1->nParent ){
1847 zPid = pW1->azParent[0];
1848 }
1849 cgi_check_for_malice();
1850 if( zPid && zPid[0] != 0 ){
1851 char *zDate;
1852 rid2 = name_to_typed_rid(zPid, "w");
1853 pW2 = manifest_get(rid2, CFTYPE_WIKI, 0);
1854 blob_init(&w2, pW2->zWiki, -1);
@@ -1929,10 +1932,11 @@
1932 if( showAll ){
1933 style_submenu_element("Active", "%R/wcontent");
1934 }else{
1935 style_submenu_element("All", "%R/wcontent?all=1");
1936 }
1937 cgi_check_for_malice();
1938 showCkBr = db_exists(
1939 "SELECT tag.tagname AS tn FROM tag JOIN tagxref USING(tagid) "
1940 "WHERE ( tn GLOB 'wiki-checkin/*' OR tn GLOB 'wiki-branch/*' ) "
1941 " AND TYPEOF(tagxref.value+0)='integer'" );
1942 if( showCkBr ){
@@ -2006,10 +2010,11 @@
2010 Stmt q;
2011 const char *zTitle;
2012 login_check_credentials();
2013 if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; }
2014 zTitle = PD("title","*");
2015 cgi_check_for_malice();
2016 style_set_current_feature("wiki");
2017 style_header("Wiki Pages Found");
2018 @ <ul>
2019 db_prepare(&q,
2020 "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'"
2021
+1
--- src/xfer.c
+++ src/xfer.c
@@ -1220,10 +1220,11 @@
12201220
fossil_redirect_home();
12211221
}
12221222
g.zLogin = "anonymous";
12231223
login_set_anon_nobody_capabilities();
12241224
login_check_credentials();
1225
+ cgi_check_for_malice();
12251226
memset(&xfer, 0, sizeof(xfer));
12261227
blobarray_zero(xfer.aToken, count(xfer.aToken));
12271228
cgi_set_content_type(g.zContentType);
12281229
cgi_reset_content();
12291230
if( db_schema_is_outofdate() ){
12301231
--- src/xfer.c
+++ src/xfer.c
@@ -1220,10 +1220,11 @@
1220 fossil_redirect_home();
1221 }
1222 g.zLogin = "anonymous";
1223 login_set_anon_nobody_capabilities();
1224 login_check_credentials();
 
1225 memset(&xfer, 0, sizeof(xfer));
1226 blobarray_zero(xfer.aToken, count(xfer.aToken));
1227 cgi_set_content_type(g.zContentType);
1228 cgi_reset_content();
1229 if( db_schema_is_outofdate() ){
1230
--- src/xfer.c
+++ src/xfer.c
@@ -1220,10 +1220,11 @@
1220 fossil_redirect_home();
1221 }
1222 g.zLogin = "anonymous";
1223 login_set_anon_nobody_capabilities();
1224 login_check_credentials();
1225 cgi_check_for_malice();
1226 memset(&xfer, 0, sizeof(xfer));
1227 blobarray_zero(xfer.aToken, count(xfer.aToken));
1228 cgi_set_content_type(g.zContentType);
1229 cgi_reset_content();
1230 if( db_schema_is_outofdate() ){
1231
+1
--- src/zip.c
+++ src/zip.c
@@ -1014,10 +1014,11 @@
10141014
@ <input type="submit" value="Download">
10151015
@ </form>
10161016
style_finish_page();
10171017
return;
10181018
}
1019
+ cgi_check_for_malice();
10191020
blob_zero(&zip);
10201021
if( cache_read(&zip, zKey)==0 ){
10211022
zip_of_checkin(eType, rid, &zip, zName, pInclude, pExclude, 0);
10221023
cache_write(&zip, zKey);
10231024
}
10241025
--- src/zip.c
+++ src/zip.c
@@ -1014,10 +1014,11 @@
1014 @ <input type="submit" value="Download">
1015 @ </form>
1016 style_finish_page();
1017 return;
1018 }
 
1019 blob_zero(&zip);
1020 if( cache_read(&zip, zKey)==0 ){
1021 zip_of_checkin(eType, rid, &zip, zName, pInclude, pExclude, 0);
1022 cache_write(&zip, zKey);
1023 }
1024
--- src/zip.c
+++ src/zip.c
@@ -1014,10 +1014,11 @@
1014 @ <input type="submit" value="Download">
1015 @ </form>
1016 style_finish_page();
1017 return;
1018 }
1019 cgi_check_for_malice();
1020 blob_zero(&zip);
1021 if( cache_read(&zip, zKey)==0 ){
1022 zip_of_checkin(eType, rid, &zip, zName, pInclude, pExclude, 0);
1023 cache_write(&zip, zKey);
1024 }
1025

Keyboard Shortcuts

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