diff --git a/django/utils/archive.py b/django/utils/archive.py
index 13f8afa..f8032d8 100644
--- a/django/utils/archive.py
+++ b/django/utils/archive.py
@@ -27,6 +27,7 @@
 import zipfile
 
 from django.utils import six
+from django.utils._os import safe_join
 
 
 class ArchiveException(Exception):
@@ -146,7 +147,7 @@ def extract(self, to_path):
             name = member.name
             if leading:
                 name = self.split_leading_dir(name)[1]
-            filename = os.path.join(to_path, name)
+            filename = safe_join(to_path, name)
             if member.isdir():
                 if filename and not os.path.exists(filename):
                     os.makedirs(filename)
@@ -187,11 +188,13 @@ def extract(self, to_path):
             data = self._archive.read(name)
             if leading:
                 name = self.split_leading_dir(name)[1]
-            filename = os.path.join(to_path, name)
+            if not name:
+                continue
+            filename = safe_join(to_path, name)
             dirname = os.path.dirname(filename)
             if dirname and not os.path.exists(dirname):
                 os.makedirs(dirname)
-            if filename.endswith(('/', '\\')):
+            if name.endswith(('/', '\\')):
                 # A directory
                 if not os.path.exists(filename):
                     os.makedirs(filename)
diff --git a/tests/utils_tests/archives/absolute.tar b/tests/utils_tests/archives/absolute.tar
new file mode 100644
index 0000000..4522447
Binary files /dev/null and b/tests/utils_tests/archives/absolute.tar differ
diff --git a/tests/utils_tests/archives/dotdot.tar b/tests/utils_tests/archives/dotdot.tar
new file mode 100644
index 0000000..30cf436
Binary files /dev/null and b/tests/utils_tests/archives/dotdot.tar differ
diff --git a/tests/utils_tests/test_archive.py b/tests/utils_tests/test_archive.py
index d1dc5f2..929d22a 100644
--- a/tests/utils_tests/test_archive.py
+++ b/tests/utils_tests/test_archive.py
@@ -3,6 +3,7 @@
 import tempfile
 import unittest
 
+from django.core.exceptions import SuspiciousFileOperation
 from django.utils._os import upath
 from django.utils.archive import Archive, extract
 
@@ -60,6 +61,29 @@ def check_files(self, tmpdir):
         self.assertTrue(os.path.isfile(os.path.join(self.tmpdir, 'foo', 'bar', '2')))
 
 
+class TestSafeUnarchival(unittest.TestCase):
+
+    def setUp(self):
+        """
+        Create temporary directory for testing extraction.
+        """
+        self.old_cwd = os.getcwd()
+        self.tmpdir = tempfile.mkdtemp()
+        self.addCleanup(shutil.rmtree, self.tmpdir)
+        # Always start off in TEST_DIR.
+        os.chdir(TEST_DIR)
+
+    def test_absolute_path(self):
+        path = os.path.join(TEST_DIR, 'absolute.tar')
+        with self.assertRaises(SuspiciousFileOperation):
+            extract(path)
+
+    def test_no_dotdot_in_path(self):
+        path = os.path.join(TEST_DIR, 'dotdot.tar')
+        with self.assertRaises(SuspiciousFileOperation):
+            extract(path)
+
+
 class TestZip(ArchiveTester, unittest.TestCase):
     archive = 'foobar.zip'

