]> granicus.if.org Git - php/commitdiff
Fixed bug #65414
authorBishop Bettini <bishop.bettini@gmail.com>
Fri, 2 Feb 2018 02:29:37 +0000 (21:29 -0500)
committerJoe <krakjoe@php.net>
Thu, 8 Feb 2018 09:29:56 +0000 (10:29 +0100)
NEWS
ext/phar/phar_object.c
ext/phar/tests/bug65414.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 722bb2c472e361d0112106b546545e7b847e4b70..676f887a09418e5eb01c96d7031242d794a1e196 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,8 @@ PHP                                                                        NEWS
 - Phar:
   . Fixed bug #54289 (Phar::extractTo() does not accept specific directories to
     be extracted). (bishop)
+  . Fixed bug #65414 (deal with leading slash while adding files correctly). 
+    (bishopb)
 
 - ODBC:
   . Fixed bug #73725 (Unable to retrieve value of varchar(max) type). (Anatol)
index 5a85bf7ad98b71fdfd2d4d075db0a014d1cf3f54..c8767af0de4827c524d8afdde664d4d287c6f007 100644 (file)
@@ -3682,14 +3682,18 @@ PHP_METHOD(Phar, offsetGet)
  */
 static void phar_add_file(phar_archive_data **pphar, char *filename, int filename_len, char *cont_str, size_t cont_len, zval *zresource)
 {
+       int start_pos=0;
        char *error;
        size_t contents_len;
        phar_entry_data *data;
        php_stream *contents_file;
 
-       if (filename_len >= (int)sizeof(".phar")-1 && !memcmp(filename, ".phar", sizeof(".phar")-1) && (filename[5] == '/' || filename[5] == '\\' || filename[5] == '\0')) {
-               zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create any files in magic \".phar\" directory");
-               return;
+       if (filename_len >= (int)sizeof(".phar")-1) {
+               start_pos = ('/' == filename[0] ? 1 : 0); /* account for any leading slash: multiple-leads handled elsewhere */
+               if (!memcmp(&filename[start_pos], ".phar", sizeof(".phar")-1) && (filename[start_pos+5] == '/' || filename[start_pos+5] == '\\' || filename[start_pos+5] == '\0')) {
+                       zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create any files in magic \".phar\" directory");
+                       return;
+               }
        }
 
        if (!(data = phar_get_or_create_entry_data((*pphar)->fname, (*pphar)->fname_len, filename, filename_len, "w+b", 0, &error, 1))) {
diff --git a/ext/phar/tests/bug65414.phpt b/ext/phar/tests/bug65414.phpt
new file mode 100644 (file)
index 0000000..964ec72
--- /dev/null
@@ -0,0 +1,36 @@
+--TEST--
+Bug #65414 Injection (A1) in .phar files magic .phar directory
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.readonly = 0
+--FILE--
+<?php
+$phar = new \Phar(__DIR__ . '/bug65414.phar', 0, 'bug65414.phar');
+$bads = [
+    '.phar/injected-1.txt',
+    '/.phar/injected-2.txt',
+    '//.phar/injected-3.txt',
+    '/.phar/',
+];
+foreach ($bads as $bad) {
+    echo $bad . ':';
+    try {
+        $phar->addFromString($bad, 'this content is injected');
+        echo 'Failed to throw expected exception';
+    } catch (BadMethodCallException $ex) {
+        echo $ex->getMessage() . PHP_EOL;
+    }
+}
+echo 'done' . PHP_EOL;
+?>
+--CLEAN--
+<?php
+unlink(__DIR__ . '/bug65414.phar');
+?>
+--EXPECT--
+.phar/injected-1.txt:Cannot create any files in magic ".phar" directory
+/.phar/injected-2.txt:Cannot create any files in magic ".phar" directory
+//.phar/injected-3.txt:Entry //.phar/injected-3.txt does not exist and cannot be created: phar error: invalid path "//.phar/injected-3.txt" contains double slash
+/.phar/:Cannot create any files in magic ".phar" directory
+done