21123cb5a9a1542b7ff01542f29078adc04764a0 max Sun Sep 6 07:31:34 2026 -0700 lib: check every component in isSafeRelativePath The loop that walks the '/'-separated components stepped to the terminator that replaced the slash instead of past it, so it ended after the first component and the rest of the path went unchecked. Callers are gfServer's dynamic mode, which takes genome and genomeDataDir from the client. diff --git src/lib/filePath.c src/lib/filePath.c index 111874ed9ea..094257139c3 100644 --- src/lib/filePath.c +++ src/lib/filePath.c @@ -221,31 +221,31 @@ return FALSE; char tmpPath[PATH_LEN]; safecpy(tmpPath, sizeof(tmpPath), path); char *p = tmpPath; while (TRUE) { char *end = strchr(p, '/'); if (end != NULL) *end = '\0'; if (sameString(p, "..")) return FALSE; if (end == NULL) break; else - p = end++; + p = end + 1; } return TRUE; } char *resolveDotDots(char *pathOrUrl) /* Given a file path or URL, return a version with ".." components resolved. * For URLs, only the path portion is simplified (scheme :// is preserved). * Double slashes are collapsed for file paths but not for URLs. * Result should be freeMem'd. */ { if (hasProtocol(pathOrUrl)) { struct netParsedUrl npu; netParseUrl(pathOrUrl, &npu); eatExcessDotsInPath(npu.file);