Skip to content

Commit ea24920

Browse files
committed
Improve some defects related to http service request path
add hv_normalize_path function to hbase.h support http legal relative path request optimize http server path file cache map key fix false positives '/..file' normal path bug
1 parent 1e3dd55 commit ea24920

3 files changed

Lines changed: 63 additions & 4 deletions

File tree

base/hbase.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,3 +540,59 @@ int hv_parse_url(hurl_t* stURL, const char* strURL) {
540540
stURL->fields[HV_URL_FRAGMENT].len = ep - sp;
541541
return 0;
542542
}
543+
544+
int hv_normalize_path(char *path) {
545+
if (*path != '/') return 0;
546+
int pos = 1;
547+
#ifdef OS_WIN
548+
int sum = 0;
549+
#endif
550+
for (int i = 1; path[i] != '\0'; ++i) {
551+
switch (path[i]) {
552+
case '\\':
553+
case '/':
554+
if (path[pos - 1] != '/') path[pos++] = '/';
555+
break;
556+
557+
case '.':
558+
if (path[pos - 1] == '/') {
559+
if (path[i + 1] == '.' && (path[i + 2] == '/' || path[i + 2] == '\\' || path[i + 2] == '\0')) {
560+
while (--pos > 0) {
561+
if (path[pos - 1] == '/') break;
562+
}
563+
if (pos < 1) return 0;
564+
i += path[i + 2] == '\0' ? 1 : 2;
565+
break;
566+
}
567+
if (path[i + 1] == '\0') break;
568+
if (path[i + 1] == '/' || path[i + 1] == '\\') {
569+
++i;
570+
break;
571+
}
572+
}
573+
path[pos++] = '.';
574+
#ifdef OS_WIN
575+
// windows does not have a trailing '.'
576+
sum = 1;
577+
while (path[i + sum] == '.') {
578+
path[pos++] = '.';
579+
++sum;
580+
}
581+
if (path[i + sum] == '\0') pos -= sum;
582+
i += sum - 1;
583+
#endif
584+
break;
585+
586+
default:
587+
#ifdef OS_WIN
588+
// windows is not case sensitive
589+
path[pos++] = (char)tolower(path[i]);
590+
#else
591+
path[pos++] = path[i];
592+
#endif
593+
break;
594+
}
595+
}
596+
path[pos] = '\0';
597+
return pos;
598+
}

base/hbase.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ typedef struct hurl_s {
140140

141141
HV_EXPORT int hv_parse_url(hurl_t* stURL, const char* strURL);
142142

143+
HV_EXPORT int hv_normalize_path(char *path);
144+
143145
END_EXTERN_C
144146

145147
#endif // HV_BASE_H_

http/server/HttpHandler.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -524,14 +524,15 @@ int HttpHandler::defaultRequestHandler() {
524524
int HttpHandler::defaultStaticHandler() {
525525
// file service
526526
std::string path = req->Path();
527-
const char* req_path = path.c_str();
528-
// path safe check
529-
if (req_path[0] != '/' || strstr(req_path, "/..") || strstr(req_path, "\\..")) {
527+
path.resize(hv_normalize_path(const_cast<char*>(path.c_str())));
528+
if (path.empty()) {
529+
hloge("[%s:%d] Illegal relative path: %s", ip, port, req->path.c_str());
530530
return HTTP_STATUS_BAD_REQUEST;
531531
}
532532

533+
const char* req_path = path.c_str();
533534
std::string filepath;
534-
bool is_dir = path.back() == '/' &&
535+
const bool is_dir = path.back() == '/' &&
535536
service->index_of.size() > 0 &&
536537
hv_strstartswith(req_path, service->index_of.c_str());
537538
if (is_dir) {

0 commit comments

Comments
 (0)