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.
Commit
57f1e8725425e34fd092dc672dfa7fd5b480ed8aa5364b76645136bafa10a446
Parent
2b72f337becee3d…
26 files changed
+2
+3
+55
-11
+1
+1
+1
+1
+2
-1
+2
+1
+1
+2
+16
+1
+9
-3
+1
+1
+2
+1
+1
+1
+1
+2
+5
+1
+1
~
src/branch.c
~
src/browse.c
~
src/cgi.c
~
src/clone.c
~
src/descendants.c
~
src/diff.c
~
src/diffcmd.c
~
src/dispatch.c
~
src/doc.c
~
src/event.c
~
src/finfo.c
~
src/forum.c
~
src/info.c
~
src/login.c
~
src/lookslike.c
~
src/name.c
~
src/search.c
~
src/stat.c
~
src/statrep.c
~
src/tag.c
~
src/tar.c
~
src/timeline.c
~
src/unversioned.c
~
src/wiki.c
~
src/xfer.c
~
src/zip.c
+2
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -858,10 +858,11 @@ | ||
| 858 | 858 | new_brlist_page(); |
| 859 | 859 | return; |
| 860 | 860 | } |
| 861 | 861 | login_check_credentials(); |
| 862 | 862 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 863 | + cgi_check_for_malice(); | |
| 863 | 864 | if( colorTest ){ |
| 864 | 865 | showClosed = 0; |
| 865 | 866 | showAll = 1; |
| 866 | 867 | } |
| 867 | 868 | if( showAll ) brFlags = BRL_BOTH; |
| @@ -986,10 +987,11 @@ | ||
| 986 | 987 | style_set_current_feature("branch"); |
| 987 | 988 | style_header("Branches"); |
| 988 | 989 | style_submenu_element("List", "brlist"); |
| 989 | 990 | login_anonymous_available(); |
| 990 | 991 | timeline_ss_submenu(); |
| 992 | + cgi_check_for_malice(); | |
| 991 | 993 | @ <h2>The initial check-in for each branch:</h2> |
| 992 | 994 | blob_append(&sql, timeline_query_for_www(), -1); |
| 993 | 995 | blob_append_sql(&sql, |
| 994 | 996 | "AND blob.rid IN (SELECT rid FROM tagxref" |
| 995 | 997 | " WHERE tagtype>0 AND tagid=%d AND srcid!=0)", TAG_BRANCH); |
| 996 | 998 |
| --- 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 |
+3
| --- src/browse.c | ||
| +++ src/browse.c | ||
| @@ -209,10 +209,11 @@ | ||
| 209 | 209 | fossil_free(zHeader); |
| 210 | 210 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 211 | 211 | sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0, |
| 212 | 212 | pathelementFunc, 0, 0); |
| 213 | 213 | url_initialize(&sURI, "dir"); |
| 214 | + cgi_check_for_malice(); | |
| 214 | 215 | cgi_query_parameters_to_url(&sURI); |
| 215 | 216 | |
| 216 | 217 | /* Compute the title of the page */ |
| 217 | 218 | if( zD ){ |
| 218 | 219 | Blob dirname; |
| @@ -705,10 +706,11 @@ | ||
| 705 | 706 | zRE = P("re"); |
| 706 | 707 | if( zRE ){ |
| 707 | 708 | re_compile(&pRE, zRE, 0); |
| 708 | 709 | zREx = mprintf("&re=%T", zRE); |
| 709 | 710 | } |
| 711 | + cgi_check_for_malice(); | |
| 710 | 712 | |
| 711 | 713 | /* If the name= parameter is an empty string, make it a NULL pointer */ |
| 712 | 714 | if( zD && strlen(zD)==0 ){ zD = 0; } |
| 713 | 715 | |
| 714 | 716 | /* If a specific check-in is requested, fetch and parse it. If the |
| @@ -1109,10 +1111,11 @@ | ||
| 1109 | 1111 | zNow = db_text("", "SELECT datetime(mtime,toLocal()) FROM event" |
| 1110 | 1112 | " WHERE objid=%d", rid); |
| 1111 | 1113 | style_submenu_element("Tree-View", "%R/tree?ci=%T&mtime=1&type=tree", zName); |
| 1112 | 1114 | style_header("File Ages"); |
| 1113 | 1115 | zGlob = P("glob"); |
| 1116 | + cgi_check_for_malice(); | |
| 1114 | 1117 | compute_fileage(rid,zGlob); |
| 1115 | 1118 | db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);"); |
| 1116 | 1119 | |
| 1117 | 1120 | if( fossil_strcmp(zName,"tip")==0 ){ |
| 1118 | 1121 | @ <h1>Files in the %z(href("%R/info?name=tip"))latest check-in</a> |
| 1119 | 1122 |
| --- 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 @@ | ||
| 749 | 749 | const char *zName; /* Parameter or cookie name */ |
| 750 | 750 | const char *zValue; /* Value of the query parameter or cookie */ |
| 751 | 751 | int seq; /* Order of insertion */ |
| 752 | 752 | char isQP; /* True for query parameters */ |
| 753 | 753 | char cTag; /* Tag on query parameters */ |
| 754 | + char isFetched; /* 1 if the var is requested via P/PD() */ | |
| 754 | 755 | } *aParamQP; /* An array of all parameters and cookies */ |
| 755 | 756 | |
| 756 | 757 | /* |
| 757 | 758 | ** Add another query parameter or cookie to the parameter set. |
| 758 | 759 | ** zName is the name of the query parameter or cookie and zValue |
| @@ -776,10 +777,11 @@ | ||
| 776 | 777 | fprintf(stderr, "# cgi: %s = [%s]\n", zName, zValue); |
| 777 | 778 | } |
| 778 | 779 | aParamQP[nUsedQP].seq = seqQP++; |
| 779 | 780 | aParamQP[nUsedQP].isQP = isQP; |
| 780 | 781 | aParamQP[nUsedQP].cTag = 0; |
| 782 | + aParamQP[nUsedQP].isFetched = 0; | |
| 781 | 783 | nUsedQP++; |
| 782 | 784 | sortQP = 1; |
| 783 | 785 | } |
| 784 | 786 | |
| 785 | 787 | /* |
| @@ -1503,10 +1505,11 @@ | ||
| 1503 | 1505 | while( lo<=hi ){ |
| 1504 | 1506 | mid = (lo+hi)/2; |
| 1505 | 1507 | c = fossil_strcmp(aParamQP[mid].zName, zName); |
| 1506 | 1508 | if( c==0 ){ |
| 1507 | 1509 | CGIDEBUG(("mem-match [%s] = [%s]\n", zName, aParamQP[mid].zValue)); |
| 1510 | + aParamQP[mid].isFetched = 1; | |
| 1508 | 1511 | return aParamQP[mid].zValue; |
| 1509 | 1512 | }else if( c>0 ){ |
| 1510 | 1513 | hi = mid-1; |
| 1511 | 1514 | }else{ |
| 1512 | 1515 | lo = mid+1; |
| @@ -1530,24 +1533,27 @@ | ||
| 1530 | 1533 | } |
| 1531 | 1534 | |
| 1532 | 1535 | /* |
| 1533 | 1536 | ** Renders the "begone, spider" page and exits. |
| 1534 | 1537 | */ |
| 1535 | -static void cgi_begone_spider(void){ | |
| 1538 | +static void cgi_begone_spider(const char *zName){ | |
| 1536 | 1539 | Blob content = empty_blob; |
| 1537 | - | |
| 1538 | 1540 | cgi_set_content(&content); |
| 1539 | 1541 | style_set_current_feature("test"); |
| 1542 | + style_submenu_enable(0); | |
| 1540 | 1543 | 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 | |
| 1545 | 1550 | @ "fossil-scm forum" into any search engine to locate the Fossil-SCM Forum. |
| 1546 | 1551 | style_finish_page(); |
| 1547 | - cgi_set_status(404,"Robot Attack Detected"); | |
| 1552 | + cgi_set_status(418,"I'm a teapot"); | |
| 1548 | 1553 | cgi_reply(); |
| 1554 | + fossil_errorlog("possible hack attempt - 418 response on \"%s\"", zName); | |
| 1549 | 1555 | exit(0); |
| 1550 | 1556 | } |
| 1551 | 1557 | |
| 1552 | 1558 | /* |
| 1553 | 1559 | ** If looks_like_sql_injection() returns true for the given string, calls |
| @@ -1563,13 +1569,13 @@ | ||
| 1563 | 1569 | ** the server with dozens or hundreds of SQL injection attempts per second |
| 1564 | 1570 | ** against pages (such as /vdiff) that are expensive to compute. In other |
| 1565 | 1571 | ** words, this is an effort to reduce the CPU load imposed by malicious |
| 1566 | 1572 | ** spiders. It is not an effect defense against SQL injection vulnerabilities. |
| 1567 | 1573 | */ |
| 1568 | -void cgi_value_spider_check(const char *zTxt){ | |
| 1574 | +void cgi_value_spider_check(const char *zTxt, const char *zName){ | |
| 1569 | 1575 | if( g.zLogin==0 && looks_like_sql_injection(zTxt) ){ |
| 1570 | - cgi_begone_spider(); | |
| 1576 | + cgi_begone_spider(zName); | |
| 1571 | 1577 | } |
| 1572 | 1578 | } |
| 1573 | 1579 | |
| 1574 | 1580 | /* |
| 1575 | 1581 | ** A variant of cgi_parameter() with the same semantics except that if |
| @@ -1578,11 +1584,11 @@ | ||
| 1578 | 1584 | */ |
| 1579 | 1585 | const char *cgi_parameter_nosql(const char *zName, const char *zDefault){ |
| 1580 | 1586 | const char *zTxt = cgi_parameter(zName, zDefault); |
| 1581 | 1587 | |
| 1582 | 1588 | if( zTxt!=zDefault ){ |
| 1583 | - cgi_value_spider_check(zTxt); | |
| 1589 | + cgi_value_spider_check(zTxt, zName); | |
| 1584 | 1590 | } |
| 1585 | 1591 | return zTxt; |
| 1586 | 1592 | } |
| 1587 | 1593 | |
| 1588 | 1594 | /* |
| @@ -1770,11 +1776,11 @@ | ||
| 1770 | 1776 | switch( eDest ){ |
| 1771 | 1777 | case 0: { |
| 1772 | 1778 | cgi_printf("%h = %h <br>\n", zName, aParamQP[i].zValue); |
| 1773 | 1779 | break; |
| 1774 | 1780 | } |
| 1775 | - case 1: { | |
| 1781 | + case 1: { | |
| 1776 | 1782 | fossil_trace("%s = %s\n", zName, aParamQP[i].zValue); |
| 1777 | 1783 | break; |
| 1778 | 1784 | } |
| 1779 | 1785 | case 2: { |
| 1780 | 1786 | cgi_debug("%s = %s\n", zName, aParamQP[i].zValue); |
| @@ -2704,5 +2710,43 @@ | ||
| 2704 | 2710 | const char *zAgent = P("HTTP_USER_AGENT"); |
| 2705 | 2711 | if( zAgent==0 ) return 0; |
| 2706 | 2712 | if( sqlite3_strglob("*iPad*", zAgent)==0 ) return 0; |
| 2707 | 2713 | return sqlite3_strlike("%mobile%", zAgent, 0)==0; |
| 2708 | 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 | +} | |
| 2709 | 2753 |
| --- 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 |
+1
| --- src/clone.c | ||
| +++ src/clone.c | ||
| @@ -398,10 +398,11 @@ | ||
| 398 | 398 | ** Provide a simple page that enables newbies to download the latest tarball or |
| 399 | 399 | ** ZIP archive, and provides instructions on how to clone. |
| 400 | 400 | */ |
| 401 | 401 | void download_page(void){ |
| 402 | 402 | login_check_credentials(); |
| 403 | + cgi_check_for_malice(); | |
| 403 | 404 | style_header("Download Page"); |
| 404 | 405 | if( !g.perm.Zip ){ |
| 405 | 406 | @ <p>Bummer. You do not have permission to download. |
| 406 | 407 | if( g.zLogin==0 || g.zLogin[0]==0 ){ |
| 407 | 408 | @ Maybe it would work better if you |
| 408 | 409 |
| --- 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 |
+1
| --- src/descendants.c | ||
| +++ src/descendants.c | ||
| @@ -576,10 +576,11 @@ | ||
| 576 | 576 | } |
| 577 | 577 | if( showClosed || showAll ){ |
| 578 | 578 | style_submenu_element("Open", "%s", url_render(&url, 0, 0, 0, 0)); |
| 579 | 579 | } |
| 580 | 580 | url_reset(&url); |
| 581 | + cgi_check_for_malice(); | |
| 581 | 582 | style_set_current_feature("leaves"); |
| 582 | 583 | style_header("Leaves"); |
| 583 | 584 | login_anonymous_available(); |
| 584 | 585 | timeline_ss_submenu(); |
| 585 | 586 | #if 0 |
| 586 | 587 |
| --- 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 @@ | ||
| 3581 | 3581 | zLimit = P("limit"); |
| 3582 | 3582 | showLog = PB("log"); |
| 3583 | 3583 | fileVers = PB("filevers"); |
| 3584 | 3584 | ignoreWs = PB("w"); |
| 3585 | 3585 | if( ignoreWs ) annFlags |= DIFF_IGNORE_ALLWS; |
| 3586 | + cgi_check_for_malice(); | |
| 3586 | 3587 | |
| 3587 | 3588 | /* compute the annotation */ |
| 3588 | 3589 | annotate_file(&ann, zFilename, zRevision, zLimit, zOrigin, annFlags); |
| 3589 | 3590 | zCI = ann.aVers[0].zMUuid; |
| 3590 | 3591 | |
| 3591 | 3592 |
| --- 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 |
+1
| --- src/diffcmd.c | ||
| +++ src/diffcmd.c | ||
| @@ -1221,10 +1221,11 @@ | ||
| 1221 | 1221 | */ |
| 1222 | 1222 | void vpatch_page(void){ |
| 1223 | 1223 | const char *zFrom = P("from"); |
| 1224 | 1224 | const char *zTo = P("to"); |
| 1225 | 1225 | DiffConfig DCfg; |
| 1226 | + cgi_check_for_malice(); | |
| 1226 | 1227 | login_check_credentials(); |
| 1227 | 1228 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1228 | 1229 | if( zFrom==0 || zTo==0 ) fossil_redirect_home(); |
| 1229 | 1230 | |
| 1230 | 1231 | fossil_nice_default(); |
| 1231 | 1232 |
| --- 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 @@ | ||
| 813 | 813 | */ |
| 814 | 814 | void help_page(void){ |
| 815 | 815 | const char *zCmd = P("cmd"); |
| 816 | 816 | |
| 817 | 817 | if( zCmd==0 ) zCmd = P("name"); |
| 818 | + cgi_check_for_malice(); | |
| 818 | 819 | if( zCmd && *zCmd ){ |
| 819 | 820 | int rc; |
| 820 | 821 | const CmdOrPage *pCmd = 0; |
| 821 | 822 | |
| 822 | - style_set_current_feature("tkt"); | |
| 823 | + style_set_current_feature("tkt"); | |
| 823 | 824 | style_header("Help: %s", zCmd); |
| 824 | 825 | |
| 825 | 826 | style_submenu_element("Command-List", "%R/help"); |
| 826 | 827 | rc = dispatch_name_search(zCmd, CMDFLAG_ANY|CMDFLAG_PREFIX, &pCmd); |
| 827 | 828 | if( *zCmd=='/' ){ |
| 828 | 829 |
| --- 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 @@ | ||
| 1051 | 1051 | Th_Store("doc_version", db_text(0, "SELECT '[' || substr(uuid,1,10) || ']'" |
| 1052 | 1052 | " FROM blob WHERE rid=%d", vid)); |
| 1053 | 1053 | Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event" |
| 1054 | 1054 | " WHERE objid=%d AND type='ci'", vid)); |
| 1055 | 1055 | } |
| 1056 | + cgi_check_for_malice(); | |
| 1056 | 1057 | document_render(&filebody, zMime, zDfltTitle, zName); |
| 1057 | 1058 | if( nMiss>=count(azSuffix) ) cgi_set_status(404, "Not Found"); |
| 1058 | 1059 | db_end_transaction(0); |
| 1059 | 1060 | return; |
| 1060 | 1061 | |
| @@ -1242,8 +1243,9 @@ | ||
| 1242 | 1243 | */ |
| 1243 | 1244 | void doc_search_page(void){ |
| 1244 | 1245 | const int isSearch = P("s")!=0; |
| 1245 | 1246 | login_check_credentials(); |
| 1246 | 1247 | style_header("Document Search%s", isSearch ? " Results" : ""); |
| 1248 | + cgi_check_for_malice(); | |
| 1247 | 1249 | search_screen(SRCH_DOC, 0); |
| 1248 | 1250 | style_finish_page(); |
| 1249 | 1251 | } |
| 1250 | 1252 |
| --- 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 |
+1
| --- src/event.c | ||
| +++ src/event.c | ||
| @@ -129,10 +129,11 @@ | ||
| 129 | 129 | } |
| 130 | 130 | verboseFlag = (zVerbose!=0) && !is_false(zVerbose); |
| 131 | 131 | |
| 132 | 132 | /* Extract the event content. |
| 133 | 133 | */ |
| 134 | + cgi_check_for_malice(); | |
| 134 | 135 | pTNote = manifest_get(rid, CFTYPE_EVENT, 0); |
| 135 | 136 | if( pTNote==0 ){ |
| 136 | 137 | fossil_fatal("Object #%d is not a tech-note", rid); |
| 137 | 138 | } |
| 138 | 139 | zMimetype = wiki_filter_mimetypes(PD("mimetype",pTNote->zMimetype)); |
| 139 | 140 |
| --- 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 |
+1
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -423,10 +423,11 @@ | ||
| 423 | 423 | }else{ |
| 424 | 424 | compute_direct_ancestors(ridFrom); |
| 425 | 425 | } |
| 426 | 426 | } |
| 427 | 427 | url_add_parameter(&url, "name", zFilename); |
| 428 | + cgi_check_for_malice(); | |
| 428 | 429 | blob_zero(&sql); |
| 429 | 430 | if( ridCi ){ |
| 430 | 431 | /* If we will be tracking changes across renames, some extra temp |
| 431 | 432 | ** tables (implemented as CTEs) are required */ |
| 432 | 433 | blob_append_sql(&sql, |
| 433 | 434 |
| --- 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 |
+2
| --- src/forum.c | ||
| +++ src/forum.c | ||
| @@ -1155,10 +1155,11 @@ | ||
| 1155 | 1155 | return; |
| 1156 | 1156 | } |
| 1157 | 1157 | if( zName==0 ){ |
| 1158 | 1158 | webpage_error("Missing \"name=\" query parameter"); |
| 1159 | 1159 | } |
| 1160 | + cgi_check_for_malice(); | |
| 1160 | 1161 | fpid = symbolic_name_to_rid(zName, "f"); |
| 1161 | 1162 | if( fpid<=0 ){ |
| 1162 | 1163 | if( fpid==0 ){ |
| 1163 | 1164 | webpage_notfound_error("Unknown forum id: \"%s\"", zName); |
| 1164 | 1165 | }else{ |
| @@ -1902,10 +1903,11 @@ | ||
| 1902 | 1903 | srchFlags = search_restrict(SRCH_FORUM); |
| 1903 | 1904 | if( !g.perm.RdForum ){ |
| 1904 | 1905 | login_needed(g.anon.RdForum); |
| 1905 | 1906 | return; |
| 1906 | 1907 | } |
| 1908 | + cgi_check_for_malice(); | |
| 1907 | 1909 | style_set_current_feature("forum"); |
| 1908 | 1910 | style_header( "%s", isSearch ? "Forum Search Results" : "Forum" ); |
| 1909 | 1911 | style_submenu_element("Timeline", "%R/timeline?ss=v&y=f&vfx"); |
| 1910 | 1912 | if( g.perm.WrForum ){ |
| 1911 | 1913 | style_submenu_element("New Thread","%R/forumnew"); |
| 1912 | 1914 |
| --- 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 @@ | ||
| 506 | 506 | style_header("Check-in Information Error"); |
| 507 | 507 | @ No such object: %h(PD("name","")) |
| 508 | 508 | style_finish_page(); |
| 509 | 509 | return; |
| 510 | 510 | } |
| 511 | + cgi_check_for_malice(); | |
| 511 | 512 | zHash = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 512 | 513 | style_header("Tags and Properties"); |
| 513 | 514 | zType = whatis_rid_type_label(rid); |
| 514 | 515 | if(!zType) zType = "Artifact"; |
| 515 | 516 | @ <h1>Tags and Properties for %s(zType) \ |
| @@ -660,10 +661,11 @@ | ||
| 660 | 661 | rid, rid |
| 661 | 662 | ); |
| 662 | 663 | zBrName = branch_of_rid(rid); |
| 663 | 664 | |
| 664 | 665 | diffType = preferred_diff_type(); |
| 666 | + cgi_check_for_malice(); | |
| 665 | 667 | if( db_step(&q1)==SQLITE_ROW ){ |
| 666 | 668 | const char *zUuid = db_column_text(&q1, 0); |
| 667 | 669 | int nUuid = db_column_bytes(&q1, 0); |
| 668 | 670 | char *zEUser, *zEComment; |
| 669 | 671 | const char *zUser; |
| @@ -1001,10 +1003,11 @@ | ||
| 1001 | 1003 | } |
| 1002 | 1004 | if( strcmp(zModAction,"approve")==0 ){ |
| 1003 | 1005 | moderation_approve('w', rid); |
| 1004 | 1006 | } |
| 1005 | 1007 | } |
| 1008 | + cgi_check_for_malice(); | |
| 1006 | 1009 | style_header("Update of \"%h\"", pWiki->zWikiTitle); |
| 1007 | 1010 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1008 | 1011 | zDate = db_text(0, "SELECT datetime(%.17g,toLocal())", pWiki->rDate); |
| 1009 | 1012 | style_submenu_element("Raw", "%R/artifact/%s", zUuid); |
| 1010 | 1013 | style_submenu_element("History", "%R/whistory?name=%t", pWiki->zWikiTitle); |
| @@ -1246,10 +1249,11 @@ | ||
| 1246 | 1249 | } |
| 1247 | 1250 | pCfg = construct_diff_flags(diffType, &DCfg); |
| 1248 | 1251 | if( DCfg.diffFlags & DIFF_IGNORE_ALLWS ){ |
| 1249 | 1252 | blob_appendf(&qp, "&w"); |
| 1250 | 1253 | } |
| 1254 | + cgi_check_for_malice(); | |
| 1251 | 1255 | style_set_current_feature("vdiff"); |
| 1252 | 1256 | if( zBranch==0 ){ |
| 1253 | 1257 | style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo); |
| 1254 | 1258 | } |
| 1255 | 1259 | if( diffType!=0 ){ |
| @@ -1778,10 +1782,11 @@ | ||
| 1778 | 1782 | } |
| 1779 | 1783 | db_finalize(&q); |
| 1780 | 1784 | } |
| 1781 | 1785 | if( v1==0 || v2==0 ) fossil_redirect_home(); |
| 1782 | 1786 | zRe = P("regex"); |
| 1787 | + cgi_check_for_malice(); | |
| 1783 | 1788 | if( zRe ) re_compile(&pRe, zRe, 0); |
| 1784 | 1789 | if( verbose ) objdescFlags |= OBJDESC_DETAIL; |
| 1785 | 1790 | if( isPatch ){ |
| 1786 | 1791 | Blob c1, c2, *pOut; |
| 1787 | 1792 | DiffConfig DCfg; |
| @@ -1853,18 +1858,21 @@ | ||
| 1853 | 1858 | */ |
| 1854 | 1859 | void rawartifact_page(void){ |
| 1855 | 1860 | int rid = 0; |
| 1856 | 1861 | char *zUuid; |
| 1857 | 1862 | |
| 1863 | + (void)P("at")/*for cgi_check_for_malice()*/; | |
| 1864 | + (void)P("m"); | |
| 1858 | 1865 | if( P("ci") ){ |
| 1859 | 1866 | rid = artifact_from_ci_and_filename(0); |
| 1860 | 1867 | } |
| 1861 | 1868 | if( rid==0 ){ |
| 1862 | 1869 | rid = name_to_rid_www("name"); |
| 1863 | 1870 | } |
| 1864 | 1871 | login_check_credentials(); |
| 1865 | 1872 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1873 | + cgi_check_for_malice(); | |
| 1866 | 1874 | if( rid==0 ) fossil_redirect_home(); |
| 1867 | 1875 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1868 | 1876 | etag_check(ETAG_HASH, zUuid); |
| 1869 | 1877 | if( fossil_strcmp(P("name"), zUuid)==0 && login_is_nobody() ){ |
| 1870 | 1878 | g.isConst = 1; |
| @@ -1885,10 +1893,13 @@ | ||
| 1885 | 1893 | */ |
| 1886 | 1894 | void secure_rawartifact_page(void){ |
| 1887 | 1895 | int rid = 0; |
| 1888 | 1896 | const char *zName = PD("name", ""); |
| 1889 | 1897 | |
| 1898 | + (void)P("at")/*for cgi_check_for_malice()*/; | |
| 1899 | + (void)P("m"); | |
| 1900 | + cgi_check_for_malice(); | |
| 1890 | 1901 | login_check_credentials(); |
| 1891 | 1902 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1892 | 1903 | rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName); |
| 1893 | 1904 | if( rid==0 ){ |
| 1894 | 1905 | cgi_set_status(404, "Not Found"); |
| @@ -1934,10 +1945,11 @@ | ||
| 1934 | 1945 | ajax_route_error(400, "Just testing client-side error handling."); |
| 1935 | 1946 | return; |
| 1936 | 1947 | } |
| 1937 | 1948 | |
| 1938 | 1949 | login_check_credentials(); |
| 1950 | + cgi_check_for_malice(); | |
| 1939 | 1951 | if( !g.perm.Read ){ |
| 1940 | 1952 | ajax_route_error(403, "Access requires Read permissions."); |
| 1941 | 1953 | return; |
| 1942 | 1954 | } |
| 1943 | 1955 | #if 1 |
| @@ -2115,10 +2127,11 @@ | ||
| 2115 | 2127 | |
| 2116 | 2128 | rid = name_to_rid_www("name"); |
| 2117 | 2129 | login_check_credentials(); |
| 2118 | 2130 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 2119 | 2131 | if( rid==0 ) fossil_redirect_home(); |
| 2132 | + cgi_check_for_malice(); | |
| 2120 | 2133 | if( g.perm.Admin ){ |
| 2121 | 2134 | const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 2122 | 2135 | if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ |
| 2123 | 2136 | style_submenu_element("Unshun", "%R/shun?accept=%s&sub=1#delshun", zUuid); |
| 2124 | 2137 | }else{ |
| @@ -2421,10 +2434,11 @@ | ||
| 2421 | 2434 | int isBranchCI = 0; /* ci= refers to a branch name */ |
| 2422 | 2435 | char *zHeader = 0; |
| 2423 | 2436 | |
| 2424 | 2437 | login_check_credentials(); |
| 2425 | 2438 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 2439 | + cgi_check_for_malice(); | |
| 2426 | 2440 | style_set_current_feature("artifact"); |
| 2427 | 2441 | |
| 2428 | 2442 | /* Capture and normalize the name= and ci= query parameters */ |
| 2429 | 2443 | if( zName==0 ){ |
| 2430 | 2444 | zName = P("filename"); |
| @@ -2752,10 +2766,11 @@ | ||
| 2752 | 2766 | char *zTktTitle; |
| 2753 | 2767 | login_check_credentials(); |
| 2754 | 2768 | if( !g.perm.RdTkt ){ login_needed(g.anon.RdTkt); return; } |
| 2755 | 2769 | rid = name_to_rid_www("name"); |
| 2756 | 2770 | if( rid==0 ){ fossil_redirect_home(); } |
| 2771 | + cgi_check_for_malice(); | |
| 2757 | 2772 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 2758 | 2773 | if( g.perm.Admin ){ |
| 2759 | 2774 | if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){ |
| 2760 | 2775 | style_submenu_element("Unshun", "%R/shun?accept=%s&sub=1#accshun", zUuid); |
| 2761 | 2776 | }else{ |
| @@ -2862,10 +2877,11 @@ | ||
| 2862 | 2877 | int rc; |
| 2863 | 2878 | int nLen; |
| 2864 | 2879 | |
| 2865 | 2880 | zName = P("name"); |
| 2866 | 2881 | if( zName==0 ) fossil_redirect_home(); |
| 2882 | + cgi_check_for_malice(); | |
| 2867 | 2883 | nLen = strlen(zName); |
| 2868 | 2884 | blob_set(&uuid, zName); |
| 2869 | 2885 | if( name_collisions(zName) ){ |
| 2870 | 2886 | cgi_set_parameter("src","info"); |
| 2871 | 2887 | ambiguous_page(); |
| 2872 | 2888 |
| --- 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 |
+1
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -575,10 +575,11 @@ | ||
| 575 | 575 | /* If the "Reset Password" button in the form was pressed, render |
| 576 | 576 | ** the Request Password Reset page in place of this one. */ |
| 577 | 577 | login_reqpwreset_page(); |
| 578 | 578 | return; |
| 579 | 579 | } |
| 580 | + cgi_check_for_malice(); | |
| 580 | 581 | login_check_credentials(); |
| 581 | 582 | fossil_redirect_to_https_if_needed(1); |
| 582 | 583 | sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0, |
| 583 | 584 | constant_time_cmp_function, 0, 0); |
| 584 | 585 | zUsername = P("u"); |
| 585 | 586 |
| --- 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 @@ | ||
| 462 | 462 | fossil_print("Has flag LOOK_SHORT: %s\n",(lookFlags&LOOK_SHORT)?"yes":"no"); |
| 463 | 463 | blob_reset(&blob); |
| 464 | 464 | } |
| 465 | 465 | |
| 466 | 466 | /* |
| 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. | |
| 468 | 469 | */ |
| 469 | 470 | 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; | |
| 471 | 472 | if( sqlite3_strnicmp(z+i, zWord, n)!=0 ) return 0; |
| 473 | + if( fossil_isalnum(z[i-1]) ) return 0; | |
| 472 | 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; | |
| 473 | 477 | return 1; |
| 474 | 478 | } |
| 475 | 479 | |
| 476 | 480 | /* |
| 477 | 481 | ** Returns true if the given text contains certain keywords or |
| @@ -502,11 +506,13 @@ | ||
| 502 | 506 | case 'N': |
| 503 | 507 | if( isWholeWord(zTxt, i, "null", 4) ) return 1; |
| 504 | 508 | break; |
| 505 | 509 | case 'o': |
| 506 | 510 | 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 | + } | |
| 508 | 514 | if( isWholeWord(zTxt, i, "or", 2) ) return 1; |
| 509 | 515 | break; |
| 510 | 516 | case 's': |
| 511 | 517 | case 'S': |
| 512 | 518 | if( isWholeWord(zTxt, i, "select", 6) ) return 1; |
| 513 | 519 |
| --- 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 @@ | ||
| 1651 | 1651 | char *zSha1Bg; |
| 1652 | 1652 | char *zSha3Bg; |
| 1653 | 1653 | |
| 1654 | 1654 | login_check_credentials(); |
| 1655 | 1655 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 1656 | + cgi_check_for_malice(); | |
| 1656 | 1657 | style_header("List Of Artifacts"); |
| 1657 | 1658 | style_submenu_element("250 Largest", "bigbloblist"); |
| 1658 | 1659 | if( g.perm.Admin ){ |
| 1659 | 1660 | style_submenu_element("Artifact Log", "rcvfromlist"); |
| 1660 | 1661 | } |
| 1661 | 1662 |
| --- 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 |
+1
| --- src/search.c | ||
| +++ src/search.c | ||
| @@ -1219,10 +1219,11 @@ | ||
| 1219 | 1219 | */ |
| 1220 | 1220 | void search_page(void){ |
| 1221 | 1221 | const int isSearch = P("s")!=0; |
| 1222 | 1222 | login_check_credentials(); |
| 1223 | 1223 | style_header("Search%s", isSearch ? " Results" : ""); |
| 1224 | + cgi_check_for_malice(); | |
| 1224 | 1225 | search_screen(SRCH_ALL, 1); |
| 1225 | 1226 | style_finish_page(); |
| 1226 | 1227 | } |
| 1227 | 1228 | |
| 1228 | 1229 | |
| 1229 | 1230 |
| --- 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 @@ | ||
| 807 | 807 | sqlite3_int64 fsize; |
| 808 | 808 | char zBuf[100]; |
| 809 | 809 | |
| 810 | 810 | login_check_credentials(); |
| 811 | 811 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 812 | + cgi_check_for_malice(); | |
| 812 | 813 | style_set_current_feature("stat"); |
| 813 | 814 | style_header("Repository Table Sizes"); |
| 814 | 815 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 815 | 816 | style_submenu_element("Stat", "stat"); |
| 816 | 817 | if( g.perm.Admin ){ |
| @@ -983,10 +984,11 @@ | ||
| 983 | 984 | */ |
| 984 | 985 | if( !g.perm.Write && !db_get_boolean("artifact_stats_enable",0) ){ |
| 985 | 986 | login_needed(g.anon.Write); |
| 986 | 987 | return; |
| 987 | 988 | } |
| 989 | + cgi_check_for_malice(); | |
| 988 | 990 | fossil_nice_default(); |
| 989 | 991 | |
| 990 | 992 | style_set_current_feature("stat"); |
| 991 | 993 | style_header("Artifact Statistics"); |
| 992 | 994 | style_submenu_element("Repository Stats", "stat"); |
| 993 | 995 |
| --- 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 |
+1
| --- src/statrep.c | ||
| +++ src/statrep.c | ||
| @@ -912,10 +912,11 @@ | ||
| 912 | 912 | if( fossil_strcmp(zView, aViewType[i].zVal)==0 ){ |
| 913 | 913 | eType = aViewType[i].eType; |
| 914 | 914 | break; |
| 915 | 915 | } |
| 916 | 916 | } |
| 917 | + cgi_check_for_malice(); | |
| 917 | 918 | if( eType!=RPT_NONE ){ |
| 918 | 919 | int nView = 0; /* Slots used in azView[] */ |
| 919 | 920 | for(i=0; i<count(aViewType); i++){ |
| 920 | 921 | azView[nView++] = aViewType[i].zVal; |
| 921 | 922 | azView[nView++] = aViewType[i].zName; |
| 922 | 923 |
| --- 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 @@ | ||
| 805 | 805 | |
| 806 | 806 | login_check_credentials(); |
| 807 | 807 | if( !g.perm.Read ){ |
| 808 | 808 | login_needed(g.anon.Read); |
| 809 | 809 | } |
| 810 | + cgi_check_for_malice(); | |
| 810 | 811 | login_anonymous_available(); |
| 811 | 812 | style_header("Tags"); |
| 812 | 813 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 813 | 814 | style_submenu_element("Timeline", "tagtimeline"); |
| 814 | 815 | @ <h2>Non-propagating tags:</h2> |
| 815 | 816 |
| --- 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 @@ | ||
| 831 | 831 | @ <input type="submit" value="Download"> |
| 832 | 832 | @ </form> |
| 833 | 833 | style_finish_page(); |
| 834 | 834 | return; |
| 835 | 835 | } |
| 836 | + cgi_check_for_malice(); | |
| 836 | 837 | blob_zero(&tarball); |
| 837 | 838 | if( cache_read(&tarball, zKey)==0 ){ |
| 838 | 839 | tarball_of_checkin(rid, &tarball, zName, pInclude, pExclude, 0); |
| 839 | 840 | cache_write(&tarball, zKey); |
| 840 | 841 | } |
| 841 | 842 |
| --- 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 |
+1
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -2835,10 +2835,11 @@ | ||
| 2835 | 2835 | |
| 2836 | 2836 | if( zNewerButton ){ |
| 2837 | 2837 | @ %z(chref("button","%s",zNewerButton))%h(zNewerButtonLabel)\ |
| 2838 | 2838 | @ ↑</a> |
| 2839 | 2839 | } |
| 2840 | + cgi_check_for_malice(); | |
| 2840 | 2841 | www_print_timeline(&q, tmFlags, zThisUser, zThisTag, zBrName, |
| 2841 | 2842 | selectedRid, secondaryRid, 0); |
| 2842 | 2843 | db_finalize(&q); |
| 2843 | 2844 | if( zOlderButton ){ |
| 2844 | 2845 | @ %z(chref("button","%s",zOlderButton))%h(zOlderButtonLabel)\ |
| 2845 | 2846 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -2835,10 +2835,11 @@ | |
| 2835 | |
| 2836 | if( zNewerButton ){ |
| 2837 | @ %z(chref("button","%s",zNewerButton))%h(zNewerButtonLabel)\ |
| 2838 | @ ↑</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 | @ ↑</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 |
+2
| --- src/unversioned.c | ||
| +++ src/unversioned.c | ||
| @@ -542,10 +542,11 @@ | ||
| 542 | 542 | int showDel = 0; |
| 543 | 543 | char zSzName[100]; |
| 544 | 544 | |
| 545 | 545 | login_check_credentials(); |
| 546 | 546 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 547 | + cgi_check_for_malice(); | |
| 547 | 548 | etag_check(ETAG_DATA,0); |
| 548 | 549 | style_header("Unversioned Files"); |
| 549 | 550 | if( !db_table_exists("repository","unversioned") ){ |
| 550 | 551 | @ No unversioned files on this server |
| 551 | 552 | style_finish_page(); |
| @@ -654,10 +655,11 @@ | ||
| 654 | 655 | char *zSep = "["; |
| 655 | 656 | Blob json; |
| 656 | 657 | |
| 657 | 658 | login_check_credentials(); |
| 658 | 659 | if( !g.perm.Read ){ login_needed(g.anon.Read); return; } |
| 660 | + cgi_check_for_malice(); | |
| 659 | 661 | cgi_set_content_type("application/json"); |
| 660 | 662 | etag_check(ETAG_DATA,0); |
| 661 | 663 | if( !db_table_exists("repository","unversioned") ){ |
| 662 | 664 | blob_init(&json, "[]", -1); |
| 663 | 665 | cgi_set_content(&json); |
| 664 | 666 |
| --- 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 @@ | ||
| 115 | 115 | */ |
| 116 | 116 | void home_page(void){ |
| 117 | 117 | char *zPageName = db_get("project-name",0); |
| 118 | 118 | char *zIndexPage = db_get("index-page",0); |
| 119 | 119 | login_check_credentials(); |
| 120 | + cgi_check_for_malice(); | |
| 120 | 121 | if( zIndexPage ){ |
| 121 | 122 | const char *zPathInfo = P("PATH_INFO"); |
| 122 | 123 | while( zIndexPage[0]=='/' ) zIndexPage++; |
| 123 | 124 | while( zPathInfo[0]=='/' ) zPathInfo++; |
| 124 | 125 | if( fossil_strcmp(zIndexPage, zPathInfo)==0 ) zIndexPage = 0; |
| @@ -550,10 +551,11 @@ | ||
| 550 | 551 | int noSubmenu = P("nsm")!=0 || g.isHome; |
| 551 | 552 | |
| 552 | 553 | login_check_credentials(); |
| 553 | 554 | if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; } |
| 554 | 555 | zPageName = P("name"); |
| 556 | + cgi_check_for_malice(); | |
| 555 | 557 | if( zPageName==0 ){ |
| 556 | 558 | if( search_restrict(SRCH_WIKI)!=0 ){ |
| 557 | 559 | wiki_srchpage(); |
| 558 | 560 | }else{ |
| 559 | 561 | wiki_helppage(); |
| @@ -1842,10 +1844,11 @@ | ||
| 1842 | 1844 | blob_init(&w1, pW1->zWiki, -1); |
| 1843 | 1845 | zPid = P("pid"); |
| 1844 | 1846 | if( ( zPid==0 || zPid[0] == 0 ) && pW1->nParent ){ |
| 1845 | 1847 | zPid = pW1->azParent[0]; |
| 1846 | 1848 | } |
| 1849 | + cgi_check_for_malice(); | |
| 1847 | 1850 | if( zPid && zPid[0] != 0 ){ |
| 1848 | 1851 | char *zDate; |
| 1849 | 1852 | rid2 = name_to_typed_rid(zPid, "w"); |
| 1850 | 1853 | pW2 = manifest_get(rid2, CFTYPE_WIKI, 0); |
| 1851 | 1854 | blob_init(&w2, pW2->zWiki, -1); |
| @@ -1929,10 +1932,11 @@ | ||
| 1929 | 1932 | if( showAll ){ |
| 1930 | 1933 | style_submenu_element("Active", "%R/wcontent"); |
| 1931 | 1934 | }else{ |
| 1932 | 1935 | style_submenu_element("All", "%R/wcontent?all=1"); |
| 1933 | 1936 | } |
| 1937 | + cgi_check_for_malice(); | |
| 1934 | 1938 | showCkBr = db_exists( |
| 1935 | 1939 | "SELECT tag.tagname AS tn FROM tag JOIN tagxref USING(tagid) " |
| 1936 | 1940 | "WHERE ( tn GLOB 'wiki-checkin/*' OR tn GLOB 'wiki-branch/*' ) " |
| 1937 | 1941 | " AND TYPEOF(tagxref.value+0)='integer'" ); |
| 1938 | 1942 | if( showCkBr ){ |
| @@ -2006,10 +2010,11 @@ | ||
| 2006 | 2010 | Stmt q; |
| 2007 | 2011 | const char *zTitle; |
| 2008 | 2012 | login_check_credentials(); |
| 2009 | 2013 | if( !g.perm.RdWiki ){ login_needed(g.anon.RdWiki); return; } |
| 2010 | 2014 | zTitle = PD("title","*"); |
| 2015 | + cgi_check_for_malice(); | |
| 2011 | 2016 | style_set_current_feature("wiki"); |
| 2012 | 2017 | style_header("Wiki Pages Found"); |
| 2013 | 2018 | @ <ul> |
| 2014 | 2019 | db_prepare(&q, |
| 2015 | 2020 | "SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'" |
| 2016 | 2021 |
| --- 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 @@ | ||
| 1220 | 1220 | fossil_redirect_home(); |
| 1221 | 1221 | } |
| 1222 | 1222 | g.zLogin = "anonymous"; |
| 1223 | 1223 | login_set_anon_nobody_capabilities(); |
| 1224 | 1224 | login_check_credentials(); |
| 1225 | + cgi_check_for_malice(); | |
| 1225 | 1226 | memset(&xfer, 0, sizeof(xfer)); |
| 1226 | 1227 | blobarray_zero(xfer.aToken, count(xfer.aToken)); |
| 1227 | 1228 | cgi_set_content_type(g.zContentType); |
| 1228 | 1229 | cgi_reset_content(); |
| 1229 | 1230 | if( db_schema_is_outofdate() ){ |
| 1230 | 1231 |
| --- 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 @@ | ||
| 1014 | 1014 | @ <input type="submit" value="Download"> |
| 1015 | 1015 | @ </form> |
| 1016 | 1016 | style_finish_page(); |
| 1017 | 1017 | return; |
| 1018 | 1018 | } |
| 1019 | + cgi_check_for_malice(); | |
| 1019 | 1020 | blob_zero(&zip); |
| 1020 | 1021 | if( cache_read(&zip, zKey)==0 ){ |
| 1021 | 1022 | zip_of_checkin(eType, rid, &zip, zName, pInclude, pExclude, 0); |
| 1022 | 1023 | cache_write(&zip, zKey); |
| 1023 | 1024 | } |
| 1024 | 1025 |
| --- 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 |