Fossil SCM

Fix the SSH sync protocol to avoid "ssh" command-line option injection attacks such as those fixed in Git 2.14.1 and Mercurial 4.2.3.

drh 2017-08-11 15:29 trunk
Commit 1f63db591c77108cd722fd9ededaabf65e238f21d82b42ffbc19f0eb4f5eed3d
1 file changed +15 -2
--- src/http_transport.c
+++ src/http_transport.c
@@ -73,10 +73,23 @@
7373
if( resetFlag ){
7474
transport.nSent = 0;
7575
transport.nRcvd = 0;
7676
}
7777
}
78
+
79
+/*
80
+** Remove leading "-" characters from the input string.
81
+**
82
+** This prevents attacks that try to trick a victim into using
83
+** a ssh:// URI with a carefully crafted hostname of other
84
+** parameter that ends up being interpreted as a command-line
85
+** option by "ssh".
86
+*/
87
+static const char *stripLeadingMinus(const char *z){
88
+ while( z[0]=='-' ) z++;
89
+ return z;
90
+}
7891
7992
/*
8093
** Default SSH command
8194
*/
8295
#ifdef _WIN32
@@ -116,17 +129,17 @@
116129
}else{
117130
zHost = mprintf("%s", pUrlData->name);
118131
}
119132
n = blob_size(&zCmd);
120133
blob_append(&zCmd, " ", 1);
121
- shell_escape(&zCmd, zHost);
134
+ shell_escape(&zCmd, stripLeadingMinus(zHost));
122135
blob_append(&zCmd, " ", 1);
123136
shell_escape(&zCmd, mprintf("%s", pUrlData->fossil));
124137
blob_append(&zCmd, " test-http", 10);
125138
if( pUrlData->path && pUrlData->path[0] ){
126139
blob_append(&zCmd, " ", 1);
127
- shell_escape(&zCmd, mprintf("%s", pUrlData->path));
140
+ shell_escape(&zCmd, mprintf("%s", stripLeadingMinus(pUrlData->path)));
128141
}
129142
if( g.fSshTrace ){
130143
fossil_print("%s\n", blob_str(&zCmd)+n); /* Show tail of SSH command */
131144
}
132145
free(zHost);
133146
--- src/http_transport.c
+++ src/http_transport.c
@@ -73,10 +73,23 @@
73 if( resetFlag ){
74 transport.nSent = 0;
75 transport.nRcvd = 0;
76 }
77 }
 
 
 
 
 
 
 
 
 
 
 
 
 
78
79 /*
80 ** Default SSH command
81 */
82 #ifdef _WIN32
@@ -116,17 +129,17 @@
116 }else{
117 zHost = mprintf("%s", pUrlData->name);
118 }
119 n = blob_size(&zCmd);
120 blob_append(&zCmd, " ", 1);
121 shell_escape(&zCmd, zHost);
122 blob_append(&zCmd, " ", 1);
123 shell_escape(&zCmd, mprintf("%s", pUrlData->fossil));
124 blob_append(&zCmd, " test-http", 10);
125 if( pUrlData->path && pUrlData->path[0] ){
126 blob_append(&zCmd, " ", 1);
127 shell_escape(&zCmd, mprintf("%s", pUrlData->path));
128 }
129 if( g.fSshTrace ){
130 fossil_print("%s\n", blob_str(&zCmd)+n); /* Show tail of SSH command */
131 }
132 free(zHost);
133
--- src/http_transport.c
+++ src/http_transport.c
@@ -73,10 +73,23 @@
73 if( resetFlag ){
74 transport.nSent = 0;
75 transport.nRcvd = 0;
76 }
77 }
78
79 /*
80 ** Remove leading "-" characters from the input string.
81 **
82 ** This prevents attacks that try to trick a victim into using
83 ** a ssh:// URI with a carefully crafted hostname of other
84 ** parameter that ends up being interpreted as a command-line
85 ** option by "ssh".
86 */
87 static const char *stripLeadingMinus(const char *z){
88 while( z[0]=='-' ) z++;
89 return z;
90 }
91
92 /*
93 ** Default SSH command
94 */
95 #ifdef _WIN32
@@ -116,17 +129,17 @@
129 }else{
130 zHost = mprintf("%s", pUrlData->name);
131 }
132 n = blob_size(&zCmd);
133 blob_append(&zCmd, " ", 1);
134 shell_escape(&zCmd, stripLeadingMinus(zHost));
135 blob_append(&zCmd, " ", 1);
136 shell_escape(&zCmd, mprintf("%s", pUrlData->fossil));
137 blob_append(&zCmd, " test-http", 10);
138 if( pUrlData->path && pUrlData->path[0] ){
139 blob_append(&zCmd, " ", 1);
140 shell_escape(&zCmd, mprintf("%s", stripLeadingMinus(pUrlData->path)));
141 }
142 if( g.fSshTrace ){
143 fossil_print("%s\n", blob_str(&zCmd)+n); /* Show tail of SSH command */
144 }
145 free(zHost);
146

Keyboard Shortcuts

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