Skip to content

Instantly share code, notes, and snippets.

@trungPa
Created Jul 2, 2021
Embed
What would you like to do?
Sec Bug #81211
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index 9656480487..54e35d0282 100644
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -1381,6 +1381,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */
zend_class_entry *ce = p_obj->c;
phar_archive_object *phar_obj = p_obj->p;
php_stream_statbuf ssb;
+ char ch;
value = iter->funcs->get_current_data(iter);
@@ -1501,7 +1502,7 @@ phar_spl_fileinfo:
base = temp;
base_len = strlen(base);
- if (strstr(fname, base)) {
+ if ((fname == strstr(fname, base)) && ((ch = fname[base_len - IS_SLASH(base[base_len - 1])]) == '\0' || IS_SLASH(ch))) {
str_key_len = fname_len - base_len;
if (str_key_len <= 0) {
diff --git a/ext/phar/tests/bug81211.phpt b/ext/phar/tests/bug81211.phpt
new file mode 100644
index 0000000000..96b1401b40
--- /dev/null
+++ b/ext/phar/tests/bug81211.phpt
@@ -0,0 +1,45 @@
+--TEST--
+Bug #81211 (Symlinks are followed when creating PHAR archive)
+--SKIPIF--
+<?php
+if (!extension_loaded('phar')) die('skip phar extension is not available');
+if (PHP_OS_FAMILY === 'Windows') {
+ if (false === include __DIR__ . '/../../standard/tests/file/windows_links/common.inc') {
+ die('skip windows_links/common.inc is not available');
+ }
+ skipIfSeCreateSymbolicLinkPrivilegeIsDisabled(__FILE__);
+}
+?>
+--FILE--
+<?php
+mkdir(__DIR__ . '/bug81211');
+mkdir(__DIR__ . '/bug81211/foobar');
+mkdir(__DIR__ . '/bug81211/foo');
+
+file_put_contents(__DIR__ . '/bug81211/foobar/file', 'this file should NOT be included in the archive!');
+symlink(__DIR__ . '/bug81211/foobar/file', __DIR__ . '/bug81211/foo/symlink');
+
+$archive = new PharData(__DIR__ . '/bug81211/archive.tar');
+try {
+ $archive->buildFromDirectory(__DIR__ . '/bug81211/foo');
+} catch (UnexpectedValueException $ex) {
+ echo $ex->getMessage(), PHP_EOL;
+}
+try {
+ $archive->buildFromIterator(new RecursiveDirectoryIterator(__DIR__ . '/bug81211/foo', FilesystemIterator::SKIP_DOTS), __DIR__ . '/bug81211/foo');
+} catch (UnexpectedValueException $ex) {
+ echo $ex->getMessage(), PHP_EOL;
+}
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/bug81211/archive.tar');
+@unlink(__DIR__ . '/bug81211/foo/symlink');
+@unlink(__DIR__ . '/bug81211/foobar/file');
+@rmdir(__DIR__ . '/bug81211/foo');
+@rmdir(__DIR__ . '/bug81211/foobar');
+@rmdir(__DIR__ . '/bug81211');
+?>
+--EXPECTF--
+Iterator RecursiveIteratorIterator returned a path "%s%ebug81211%efoobar%efile" that is not in the base directory "%s%ebug81211%efoo"
+Iterator RecursiveDirectoryIterator returned a path "%s%ebug81211%efoobar%efile" that is not in the base directory "%s%ebug81211%efoo"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment