Fossil SCM

Enhance the ssh:// URL to be cautious about the fossil= query parameter. Only commands "fossil" and "echo" (with an optional path) are accepted.

drh 2017-08-12 18:47 trunk
Commit cb43937d8c1232d3f9f0cb18bc20b41ce8d47f7c09e703d1f32df608df83fa03
1 file changed +19
--- src/http_transport.c
+++ src/http_transport.c
@@ -73,10 +73,25 @@
7373
if( resetFlag ){
7474
transport.nSent = 0;
7575
transport.nRcvd = 0;
7676
}
7777
}
78
+
79
+/*
80
+** Check zFossil to see if it is a reasonable "fossil" command to
81
+** run on the server. Do not allow an attacker to substitute something
82
+** like "/bin/rm".
83
+*/
84
+static int is_safe_fossil_command(const char *zFossil){
85
+ static const char *azSafe[] = { "*/fossil", "*/echo" };
86
+ int i;
87
+ for(i=0; i<sizeof(azSafe)/sizeof(azSafe[0]); i++){
88
+ if( sqlite3_strglob(azSafe[i], zFossil)==0 ) return 1;
89
+ if( strcmp(azSafe[i]+2, zFossil)==0 ) return 1;
90
+ }
91
+ return 0;
92
+}
7893
7994
/*
8095
** Default SSH command
8196
*/
8297
#ifdef _WIN32
@@ -110,10 +125,14 @@
110125
zHost = mprintf("%s@%s", pUrlData->user, pUrlData->name);
111126
blob_append_escaped_arg(&zCmd, zHost);
112127
fossil_free(zHost);
113128
}else{
114129
blob_append_escaped_arg(&zCmd, pUrlData->name);
130
+ }
131
+ if( !is_safe_fossil_command(pUrlData->fossil) ){
132
+ fossil_fatal("the ssh:// URL is asking to run an unsafe command [%s] on "
133
+ "the server.", pUrlData->fossil);
115134
}
116135
blob_append_escaped_arg(&zCmd, pUrlData->fossil);
117136
blob_append(&zCmd, " test-http", 10);
118137
if( pUrlData->path && pUrlData->path[0] ){
119138
blob_append_escaped_arg(&zCmd, pUrlData->path);
120139
--- src/http_transport.c
+++ src/http_transport.c
@@ -73,10 +73,25 @@
73 if( resetFlag ){
74 transport.nSent = 0;
75 transport.nRcvd = 0;
76 }
77 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
79 /*
80 ** Default SSH command
81 */
82 #ifdef _WIN32
@@ -110,10 +125,14 @@
110 zHost = mprintf("%s@%s", pUrlData->user, pUrlData->name);
111 blob_append_escaped_arg(&zCmd, zHost);
112 fossil_free(zHost);
113 }else{
114 blob_append_escaped_arg(&zCmd, pUrlData->name);
 
 
 
 
115 }
116 blob_append_escaped_arg(&zCmd, pUrlData->fossil);
117 blob_append(&zCmd, " test-http", 10);
118 if( pUrlData->path && pUrlData->path[0] ){
119 blob_append_escaped_arg(&zCmd, pUrlData->path);
120
--- src/http_transport.c
+++ src/http_transport.c
@@ -73,10 +73,25 @@
73 if( resetFlag ){
74 transport.nSent = 0;
75 transport.nRcvd = 0;
76 }
77 }
78
79 /*
80 ** Check zFossil to see if it is a reasonable "fossil" command to
81 ** run on the server. Do not allow an attacker to substitute something
82 ** like "/bin/rm".
83 */
84 static int is_safe_fossil_command(const char *zFossil){
85 static const char *azSafe[] = { "*/fossil", "*/echo" };
86 int i;
87 for(i=0; i<sizeof(azSafe)/sizeof(azSafe[0]); i++){
88 if( sqlite3_strglob(azSafe[i], zFossil)==0 ) return 1;
89 if( strcmp(azSafe[i]+2, zFossil)==0 ) return 1;
90 }
91 return 0;
92 }
93
94 /*
95 ** Default SSH command
96 */
97 #ifdef _WIN32
@@ -110,10 +125,14 @@
125 zHost = mprintf("%s@%s", pUrlData->user, pUrlData->name);
126 blob_append_escaped_arg(&zCmd, zHost);
127 fossil_free(zHost);
128 }else{
129 blob_append_escaped_arg(&zCmd, pUrlData->name);
130 }
131 if( !is_safe_fossil_command(pUrlData->fossil) ){
132 fossil_fatal("the ssh:// URL is asking to run an unsafe command [%s] on "
133 "the server.", pUrlData->fossil);
134 }
135 blob_append_escaped_arg(&zCmd, pUrlData->fossil);
136 blob_append(&zCmd, " test-http", 10);
137 if( pUrlData->path && pUrlData->path[0] ){
138 blob_append_escaped_arg(&zCmd, pUrlData->path);
139

Keyboard Shortcuts

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