Fossil SCM

Improve the error log message for 418 responses so that it includes the name of the offending query parameter. Require whitespace around keywords when trying to detect SQL.

drh 2023-07-17 11:44 verify-options-cgi
Commit ef1702fde39616ec00b6536277f11ad65fb6e2526a4abada6ee2c7e33e022f82
2 files changed +7 -7 +2 -2
+7 -7
--- src/cgi.c
+++ src/cgi.c
@@ -1533,11 +1533,11 @@
15331533
}
15341534
15351535
/*
15361536
** Renders the "begone, spider" page and exits.
15371537
*/
1538
-static void cgi_begone_spider(void){
1538
+static void cgi_begone_spider(const char *zName){
15391539
Blob content = empty_blob;
15401540
cgi_set_content(&content);
15411541
style_set_current_feature("test");
15421542
style_submenu_enable(0);
15431543
style_header("Malicious Query Detected");
@@ -1547,13 +1547,13 @@
15471547
@
15481548
@ <p>If you believe you are innocent and have reached this page in error,
15491549
@ contact the Fossil developers on the Fossil-SCM Forum. Type
15501550
@ "fossil-scm forum" into any search engine to locate the Fossil-SCM Forum.
15511551
style_finish_page();
1552
- cgi_set_status(418,"I'm a teapot");
1552
+ cgi_set_status(418,"I'm a teapotgrep ");
15531553
cgi_reply();
1554
- fossil_errorlog("possible hack attempt - 418 response");
1554
+ fossil_errorlog("possible hack attempt - 418 response on \"%s\"", zName);
15551555
exit(0);
15561556
}
15571557
15581558
/*
15591559
** If looks_like_sql_injection() returns true for the given string, calls
@@ -1569,13 +1569,13 @@
15691569
** the server with dozens or hundreds of SQL injection attempts per second
15701570
** against pages (such as /vdiff) that are expensive to compute. In other
15711571
** words, this is an effort to reduce the CPU load imposed by malicious
15721572
** spiders. It is not an effect defense against SQL injection vulnerabilities.
15731573
*/
1574
-void cgi_value_spider_check(const char *zTxt){
1574
+void cgi_value_spider_check(const char *zTxt, const char *zName){
15751575
if( g.zLogin==0 && looks_like_sql_injection(zTxt) ){
1576
- cgi_begone_spider();
1576
+ cgi_begone_spider(zName);
15771577
}
15781578
}
15791579
15801580
/*
15811581
** A variant of cgi_parameter() with the same semantics except that if
@@ -1584,11 +1584,11 @@
15841584
*/
15851585
const char *cgi_parameter_nosql(const char *zName, const char *zDefault){
15861586
const char *zTxt = cgi_parameter(zName, zDefault);
15871587
15881588
if( zTxt!=zDefault ){
1589
- cgi_value_spider_check(zTxt);
1589
+ cgi_value_spider_check(zTxt, zName);
15901590
}
15911591
return zTxt;
15921592
}
15931593
15941594
/*
@@ -2744,9 +2744,9 @@
27442744
int i;
27452745
for(i = 0; i < nUsedQP; ++i){
27462746
pParam = &aParamQP[i];
27472747
if(0 == pParam->isFetched
27482748
&& fossil_islower(pParam->zName[0])){
2749
- cgi_value_spider_check(pParam->zValue);
2749
+ cgi_value_spider_check(pParam->zValue, pParam->zName);
27502750
}
27512751
}
27522752
}
27532753
--- src/cgi.c
+++ src/cgi.c
@@ -1533,11 +1533,11 @@
1533 }
1534
1535 /*
1536 ** Renders the "begone, spider" page and exits.
1537 */
1538 static void cgi_begone_spider(void){
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");
@@ -1547,13 +1547,13 @@
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");
1555 exit(0);
1556 }
1557
1558 /*
1559 ** If looks_like_sql_injection() returns true for the given string, calls
@@ -1569,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){
1575 if( g.zLogin==0 && looks_like_sql_injection(zTxt) ){
1576 cgi_begone_spider();
1577 }
1578 }
1579
1580 /*
1581 ** A variant of cgi_parameter() with the same semantics except that if
@@ -1584,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);
1590 }
1591 return zTxt;
1592 }
1593
1594 /*
@@ -2744,9 +2744,9 @@
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);
2750 }
2751 }
2752 }
2753
--- src/cgi.c
+++ src/cgi.c
@@ -1533,11 +1533,11 @@
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");
@@ -1547,13 +1547,13 @@
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 teapotgrep ");
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
@@ -1569,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
@@ -1584,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 /*
@@ -2744,9 +2744,9 @@
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
+2 -2
--- src/lookslike.c
+++ src/lookslike.c
@@ -465,13 +465,13 @@
465465
466466
/*
467467
** Return true if z[i] is the whole word given by zWord
468468
*/
469469
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;
470
+ if( i>0 && !fossil_isspace(z[i-1]) ) return 0;
471471
if( sqlite3_strnicmp(z+i, zWord, n)!=0 ) return 0;
472
- if( fossil_isalnum(z[i+n]) ) return 0;
472
+ if( z[i+n]!=0 && !fossil_isspace(z[i+n]) ) return 0;
473473
return 1;
474474
}
475475
476476
/*
477477
** Returns true if the given text contains certain keywords or
478478
--- src/lookslike.c
+++ src/lookslike.c
@@ -465,13 +465,13 @@
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
478
--- src/lookslike.c
+++ src/lookslike.c
@@ -465,13 +465,13 @@
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_isspace(z[i-1]) ) return 0;
471 if( sqlite3_strnicmp(z+i, zWord, n)!=0 ) return 0;
472 if( z[i+n]!=0 && !fossil_isspace(z[i+n]) ) return 0;
473 return 1;
474 }
475
476 /*
477 ** Returns true if the given text contains certain keywords or
478

Keyboard Shortcuts

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