Fossil SCM

Make the repository database read-only if an HTTP request is not from the same origin. This is not required for security. It is just an extra layer of defense.

drh 2022-12-29 17:00 trunk
Commit 7c71f00ac8b239d4ae9cc40a74bdcf43d34c81fe971f44d282a446654140c6c0
2 files changed +17 -7 +3
+17 -7
--- src/cgi.c
+++ src/cgi.c
@@ -680,31 +680,41 @@
680680
if( zRef==0 ) zRef = zDefault;
681681
}
682682
return zRef;
683683
}
684684
685
+
686
+/*
687
+** Return true if the current request is coming from the same origin.
688
+*/
689
+int cgi_same_origin(void){
690
+ const char *zRef;
691
+ int nBase;
692
+ if( g.zBaseURL==0 ) return 0;
693
+ zRef = P("HTTP_REFERER");
694
+ if( zRef==0 ) return 0;
695
+ nBase = (int)strlen(g.zBaseURL);
696
+ if( fossil_strncmp(g.zBaseURL,zRef,nBase)!=0 ) return 0;
697
+ if( zRef[nBase]!=0 && zRef[nBase]!='/' ) return 0;
698
+ return 1;
699
+}
700
+
685701
/*
686702
** Return true if the current request appears to be safe from a
687703
** Cross-Site Request Forgery (CSRF) attack. Conditions that must
688704
** be met:
689705
**
690706
** * The HTTP_REFERER must have the same origin
691707
** * The REQUEST_METHOD must be POST - or requirePost==0
692708
*/
693709
int cgi_csrf_safe(int requirePost){
694
- const char *zRef = P("HTTP_REFERER");
695
- int nBase;
696
- if( zRef==0 ) return 0;
697710
if( requirePost ){
698711
const char *zMethod = P("REQUEST_METHOD");
699712
if( zMethod==0 ) return 0;
700713
if( strcmp(zMethod,"POST")!=0 ) return 0;
701714
}
702
- nBase = (int)strlen(g.zBaseURL);
703
- if( fossil_strncmp(g.zBaseURL,zRef,nBase)!=0 ) return 0;
704
- if( zRef[nBase]!=0 && zRef[nBase]!='/' ) return 0;
705
- return 1;
715
+ return cgi_same_origin();
706716
}
707717
708718
/*
709719
** Information about all query parameters, post parameter, cookies and
710720
** CGI environment variables are stored in a hash table as follows:
711721
--- src/cgi.c
+++ src/cgi.c
@@ -680,31 +680,41 @@
680 if( zRef==0 ) zRef = zDefault;
681 }
682 return zRef;
683 }
684
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
685 /*
686 ** Return true if the current request appears to be safe from a
687 ** Cross-Site Request Forgery (CSRF) attack. Conditions that must
688 ** be met:
689 **
690 ** * The HTTP_REFERER must have the same origin
691 ** * The REQUEST_METHOD must be POST - or requirePost==0
692 */
693 int cgi_csrf_safe(int requirePost){
694 const char *zRef = P("HTTP_REFERER");
695 int nBase;
696 if( zRef==0 ) return 0;
697 if( requirePost ){
698 const char *zMethod = P("REQUEST_METHOD");
699 if( zMethod==0 ) return 0;
700 if( strcmp(zMethod,"POST")!=0 ) return 0;
701 }
702 nBase = (int)strlen(g.zBaseURL);
703 if( fossil_strncmp(g.zBaseURL,zRef,nBase)!=0 ) return 0;
704 if( zRef[nBase]!=0 && zRef[nBase]!='/' ) return 0;
705 return 1;
706 }
707
708 /*
709 ** Information about all query parameters, post parameter, cookies and
710 ** CGI environment variables are stored in a hash table as follows:
711
--- src/cgi.c
+++ src/cgi.c
@@ -680,31 +680,41 @@
680 if( zRef==0 ) zRef = zDefault;
681 }
682 return zRef;
683 }
684
685
686 /*
687 ** Return true if the current request is coming from the same origin.
688 */
689 int cgi_same_origin(void){
690 const char *zRef;
691 int nBase;
692 if( g.zBaseURL==0 ) return 0;
693 zRef = P("HTTP_REFERER");
694 if( zRef==0 ) return 0;
695 nBase = (int)strlen(g.zBaseURL);
696 if( fossil_strncmp(g.zBaseURL,zRef,nBase)!=0 ) return 0;
697 if( zRef[nBase]!=0 && zRef[nBase]!='/' ) return 0;
698 return 1;
699 }
700
701 /*
702 ** Return true if the current request appears to be safe from a
703 ** Cross-Site Request Forgery (CSRF) attack. Conditions that must
704 ** be met:
705 **
706 ** * The HTTP_REFERER must have the same origin
707 ** * The REQUEST_METHOD must be POST - or requirePost==0
708 */
709 int cgi_csrf_safe(int requirePost){
 
 
 
710 if( requirePost ){
711 const char *zMethod = P("REQUEST_METHOD");
712 if( zMethod==0 ) return 0;
713 if( strcmp(zMethod,"POST")!=0 ) return 0;
714 }
715 return cgi_same_origin();
 
 
 
716 }
717
718 /*
719 ** Information about all query parameters, post parameter, cookies and
720 ** CGI environment variables are stored in a hash table as follows:
721
+3
--- src/main.c
+++ src/main.c
@@ -2059,10 +2059,13 @@
20592059
}
20602060
}
20612061
#endif
20622062
if( (pCmd->eCmdFlags & CMDFLAG_RAWCONTENT)==0 ){
20632063
cgi_decode_post_parameters();
2064
+ if( !cgi_same_origin() ){
2065
+ db_protect(PROTECT_READONLY);
2066
+ }
20642067
}
20652068
if( g.fCgiTrace ){
20662069
fossil_trace("######## Calling %s #########\n", pCmd->zName);
20672070
cgi_print_all(1, 1);
20682071
}
20692072
--- src/main.c
+++ src/main.c
@@ -2059,10 +2059,13 @@
2059 }
2060 }
2061 #endif
2062 if( (pCmd->eCmdFlags & CMDFLAG_RAWCONTENT)==0 ){
2063 cgi_decode_post_parameters();
 
 
 
2064 }
2065 if( g.fCgiTrace ){
2066 fossil_trace("######## Calling %s #########\n", pCmd->zName);
2067 cgi_print_all(1, 1);
2068 }
2069
--- src/main.c
+++ src/main.c
@@ -2059,10 +2059,13 @@
2059 }
2060 }
2061 #endif
2062 if( (pCmd->eCmdFlags & CMDFLAG_RAWCONTENT)==0 ){
2063 cgi_decode_post_parameters();
2064 if( !cgi_same_origin() ){
2065 db_protect(PROTECT_READONLY);
2066 }
2067 }
2068 if( g.fCgiTrace ){
2069 fossil_trace("######## Calling %s #########\n", pCmd->zName);
2070 cgi_print_all(1, 1);
2071 }
2072

Keyboard Shortcuts

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