a6b5d7
diff --git a/setuptools/package_index.py b/setuptools/package_index.py
a6b5d7
index 123e958..a90b810 100644
a6b5d7
--- a/setuptools/package_index.py
a6b5d7
+++ b/setuptools/package_index.py
a6b5d7
@@ -215,7 +215,7 @@ def unique_values(func):
a6b5d7
     return wrapper
a6b5d7
 
a6b5d7
 
a6b5d7
-REL = re.compile(r"""<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>""", re.I)
a6b5d7
+REL = re.compile(r"""<([^>]*\srel\s{0,10}=\s{0,10}['"]?([^'" >]+)[^>]*)>""", re.I)
a6b5d7
 # this line is here to fix emacs' cruddy broken syntax highlighting
a6b5d7
 
a6b5d7
 
a6b5d7
diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py
a6b5d7
index 8e9435e..bc1e373 100644
a6b5d7
--- a/setuptools/tests/test_packageindex.py
a6b5d7
+++ b/setuptools/tests/test_packageindex.py
a6b5d7
@@ -308,3 +308,10 @@ class TestPyPIConfig:
a6b5d7
         cred = cfg.creds_by_repository['https://pypi.org']
a6b5d7
         assert cred.username == 'jaraco'
a6b5d7
         assert cred.password == 'pity%'
a6b5d7
+
a6b5d7
+@pytest.mark.timeout(1)
a6b5d7
+def test_REL_DoS():
a6b5d7
+    """
a6b5d7
+    REL should not hang on a contrived attack string.
a6b5d7
+    """
a6b5d7
+    setuptools.package_index.REL.search('< rel=' + ' ' * 2**12)