Projet

Général

Profil

Paste
Télécharger (2,37 ko) Statistiques
| Branche: | Révision:

root / drupal7 / misc / typo3 / drupal-security / PharExtensionInterceptor.php @ cd5c298a

1
<?php
2

    
3
namespace Drupal\Core\Security;
4

    
5
use TYPO3\PharStreamWrapper\Assertable;
6
use TYPO3\PharStreamWrapper\Helper;
7
use TYPO3\PharStreamWrapper\Exception;
8

    
9
/**
10
 * An alternate PharExtensionInterceptor to support phar-based CLI tools.
11
 *
12
 * @see \TYPO3\PharStreamWrapper\Interceptor\PharExtensionInterceptor
13
 */
14
class PharExtensionInterceptor implements Assertable {
15

    
16
  /**
17
   * Determines whether phar file is allowed to execute.
18
   *
19
   * The phar file is allowed to execute if:
20
   * - the base file name has a ".phar" suffix.
21
   * - it is the CLI tool that has invoked the interceptor.
22
   *
23
   * @param string $path
24
   *   The path of the phar file to check.
25
   * @param string $command
26
   *   The command being carried out.
27
   *
28
   * @return bool
29
   *   TRUE if the phar file is allowed to execute.
30
   *
31
   * @throws Exception
32
   *   Thrown when the file is not allowed to execute.
33
   */
34
  public function assert($path, $command) {
35
    if ($this->baseFileContainsPharExtension($path)) {
36
      return TRUE;
37
    }
38
    throw new Exception(
39
      sprintf(
40
        'Unexpected file extension in "%s"',
41
        $path
42
      ),
43
      1535198703
44
    );
45
  }
46

    
47
  /**
48
   * Determines if a path has a .phar extension or invoked execution.
49
   *
50
   * @param string $path
51
   *   The path of the phar file to check.
52
   *
53
   * @return bool
54
   *   TRUE if the file has a .phar extension or if the execution has been
55
   *   invoked by the phar file.
56
   */
57
  private function baseFileContainsPharExtension($path) {
58
    $baseFile = Helper::determineBaseFile($path);
59
    if ($baseFile === NULL) {
60
      return FALSE;
61
    }
62
    // If the stream wrapper is registered by invoking a phar file that does
63
    // not not have .phar extension then this should be allowed. For
64
    // example, some CLI tools recommend removing the extension.
65
    $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
66
    // Find the last entry in the backtrace containing a 'file' key as
67
    // sometimes the last caller is executed outside the scope of a file. For
68
    // example, this occurs with shutdown functions.
69
    do {
70
      $caller = array_pop($backtrace);
71
    } while (empty($caller['file']) && !empty($backtrace));
72
    if (isset($caller['file']) && $baseFile === Helper::determineBaseFile($caller['file'])) {
73
      return TRUE;
74
    }
75
    $fileExtension = pathinfo($baseFile, PATHINFO_EXTENSION);
76
    return strtolower($fileExtension) === 'phar';
77
  }
78

    
79
}