Fossil SCM
Additional webserver security: Do not allow the "fossil server" command to return any static content with an unrecognized suffix.
Commit
4a5e972e2c7f98ce309735b040364949edb370c8
Parent
28faff0d6a11bc2…
1 file changed
+7
-2
+7
-2
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -1297,21 +1297,26 @@ | ||
| 1297 | 1297 | } |
| 1298 | 1298 | if( zRepo[0]=='/' && zRepo[1]=='/' ){ zRepo++; j--; } |
| 1299 | 1299 | |
| 1300 | 1300 | szFile = file_size(zRepo); |
| 1301 | 1301 | if( szFile<0 ){ |
| 1302 | + const char *zMimetype; | |
| 1302 | 1303 | assert( fossil_strcmp(&zRepo[j], ".fossil")==0 ); |
| 1303 | 1304 | zRepo[j] = 0; |
| 1304 | 1305 | if( zPathInfo[i]=='/' && file_isdir(zRepo)==1 ){ |
| 1305 | 1306 | fossil_free(zToFree); |
| 1306 | 1307 | i++; |
| 1307 | 1308 | continue; |
| 1308 | 1309 | } |
| 1309 | - if( file_isfile(zRepo) && strglob("*.fossil*",zRepo)==0 ){ | |
| 1310 | + if( file_isfile(zRepo) | |
| 1311 | + && strglob("*.fossil*",zRepo)==0 | |
| 1312 | + && (zMimetype = mimetype_from_name(zRepo))!=0 | |
| 1313 | + && strcmp(zMimetype, "application/x-fossil-artifact")!=0 | |
| 1314 | + ){ | |
| 1310 | 1315 | Blob content; |
| 1311 | 1316 | blob_read_from_file(&content, zRepo); |
| 1312 | - cgi_set_content_type(mimetype_from_name(zRepo)); | |
| 1317 | + cgi_set_content_type(zMimetype); | |
| 1313 | 1318 | cgi_set_content(&content); |
| 1314 | 1319 | cgi_reply(); |
| 1315 | 1320 | return; |
| 1316 | 1321 | } |
| 1317 | 1322 | zRepo[j] = '.'; |
| 1318 | 1323 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1297,21 +1297,26 @@ | |
| 1297 | } |
| 1298 | if( zRepo[0]=='/' && zRepo[1]=='/' ){ zRepo++; j--; } |
| 1299 | |
| 1300 | szFile = file_size(zRepo); |
| 1301 | if( szFile<0 ){ |
| 1302 | assert( fossil_strcmp(&zRepo[j], ".fossil")==0 ); |
| 1303 | zRepo[j] = 0; |
| 1304 | if( zPathInfo[i]=='/' && file_isdir(zRepo)==1 ){ |
| 1305 | fossil_free(zToFree); |
| 1306 | i++; |
| 1307 | continue; |
| 1308 | } |
| 1309 | if( file_isfile(zRepo) && strglob("*.fossil*",zRepo)==0 ){ |
| 1310 | Blob content; |
| 1311 | blob_read_from_file(&content, zRepo); |
| 1312 | cgi_set_content_type(mimetype_from_name(zRepo)); |
| 1313 | cgi_set_content(&content); |
| 1314 | cgi_reply(); |
| 1315 | return; |
| 1316 | } |
| 1317 | zRepo[j] = '.'; |
| 1318 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1297,21 +1297,26 @@ | |
| 1297 | } |
| 1298 | if( zRepo[0]=='/' && zRepo[1]=='/' ){ zRepo++; j--; } |
| 1299 | |
| 1300 | szFile = file_size(zRepo); |
| 1301 | if( szFile<0 ){ |
| 1302 | const char *zMimetype; |
| 1303 | assert( fossil_strcmp(&zRepo[j], ".fossil")==0 ); |
| 1304 | zRepo[j] = 0; |
| 1305 | if( zPathInfo[i]=='/' && file_isdir(zRepo)==1 ){ |
| 1306 | fossil_free(zToFree); |
| 1307 | i++; |
| 1308 | continue; |
| 1309 | } |
| 1310 | if( file_isfile(zRepo) |
| 1311 | && strglob("*.fossil*",zRepo)==0 |
| 1312 | && (zMimetype = mimetype_from_name(zRepo))!=0 |
| 1313 | && strcmp(zMimetype, "application/x-fossil-artifact")!=0 |
| 1314 | ){ |
| 1315 | Blob content; |
| 1316 | blob_read_from_file(&content, zRepo); |
| 1317 | cgi_set_content_type(zMimetype); |
| 1318 | cgi_set_content(&content); |
| 1319 | cgi_reply(); |
| 1320 | return; |
| 1321 | } |
| 1322 | zRepo[j] = '.'; |
| 1323 |