aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmar Polo <op@omarpolo.com>2021-04-12 20:23:28 +0000
committerOmar Polo <op@omarpolo.com>2021-04-12 20:23:28 +0000
commit762d824cb126dc40df1dccc84b8c68ca1a821837 (patch)
tree6aca6d27518b8a4c80421b17ccca79aa45bbce64
parentc8249bada3df6ab700dadaae36e9570cc8e62d55 (diff)
fix IRI-parsing bug
Some particularly crafted IRIs can cause a denial of service (DOS). IRIs which have a trailing `..' segment and resolve to a valid IRI (i.e. a .. that's not escaping the root directory) will make the server process loop forever. This is """just""" an DOS vulnerability, it doesn't expose anything sensitive or give an attacker anything else.
-rw-r--r--iri.c6
-rw-r--r--regress/iri_test.c4
2 files changed, 9 insertions, 1 deletions
diff --git a/iri.c b/iri.c
index 442af15..e1552d6 100644
--- a/iri.c
+++ b/iri.c
@@ -272,9 +272,13 @@ path_clean(char *path)
}
/* 3. eliminate each inner .. along with the preceding non-.. */
- for (i = strstr(path, "../"); i != NULL; i = strstr(path, ".."))
+ for (i = strstr(path, "../"); i != NULL; i = strstr(path, "..")) {
+ /* break if we've found a trailing .. */
+ if (i[2] == '\0')
+ break;
if (!path_elide_dotdot(path, i, 3))
return 0;
+ }
/* 4. eliminate trailing ..*/
if ((i = strstr(path, "..")) != NULL)
diff --git a/regress/iri_test.c b/regress/iri_test.c
index 785305d..6595f92 100644
--- a/regress/iri_test.c
+++ b/regress/iri_test.c
@@ -194,6 +194,10 @@ main(void)
PASS,
IRI("gemini", "omarpolo.com", "", "foo", "", ""),
"Trim initial slashes (pt. 2)");
+ TEST("http://a/b/c/../..",
+ PASS,
+ IRI("http", "a", "", "", "", ""),
+ "avoid infinite loops (see v1.6.1)");
/* query */
TEST("foo://example.com/foo/?gne",