/** * Returns a URL parameter array containing parameters for secure downloads by "jumpurl". * Helper function for filelink() * * The array returned has the following structure: * juSecure => is always 1, * locationData => information about the record that created the jumpUrl, * juHash => the hash that will be checked before the file is downloadable * [mimeType => the mime type of the file] * * @param string $jumpUrl The URL to jump to, basically the filepath * @param array $configuration TypoScript properties for the "jumpurl.secure" property of "filelink" * @return array URL parameters required for jumpUrl secure * */ protected function getParametersForSecureFile($jumpUrl, array $configuration) { $parameters = array('juSecure' => 1, 'locationData' => $this->getTypoScriptFrontendController()->id . ':' . $this->getContentObjectRenderer()->currentRecord); $pathInfo = pathinfo($jumpUrl); if (!empty($pathInfo['extension'])) { $mimeTypes = GeneralUtility::trimExplode(',', $configuration['mimeTypes'], true); foreach ($mimeTypes as $mimeType) { list($fileExtension, $mimeType) = GeneralUtility::trimExplode('=', $mimeType, false, 2); if (strtolower($pathInfo['extension']) === strtolower($fileExtension)) { $parameters['mimeType'] = $mimeType; break; } } } $parameters['juHash'] = JumpUrlUtility::calculateHashSecure($jumpUrl, $parameters['locationData'], $parameters['mimeType']); return $parameters; }
/** * If the submitted hash is correct and the user has access to the * related content element the contents of the submitted file will * be output to the user. * * @param string $jumpUrl The URL to the file that should be output to the user * @throws \Exception */ protected function forwardJumpUrlSecureFileData($jumpUrl) { // Set the parameters required for handling a secure jumpUrl link // The locationData GET parameter, containing information about the record that created the URL $locationData = (string) GeneralUtility::_GP('locationData'); // The optional mimeType GET parameter $mimeType = (string) GeneralUtility::_GP('mimeType'); // The jump Url Hash GET parameter $juHash = (string) GeneralUtility::_GP('juHash'); // validate the hash GET parameter against the other parameters if ($juHash !== JumpUrlUtility::calculateHashSecure($jumpUrl, $locationData, $mimeType)) { throw new \Exception('The calculated Jump URL secure hash ("juHash") did not match the submitted "juHash" query parameter.', 1294585196); } if (!$this->isLocationDataValid($locationData)) { throw new \Exception('The calculated secure location data "' . $locationData . '" is not accessible.', 1294585195); } // Allow spaces / special chars in filenames. $jumpUrl = rawurldecode($jumpUrl); // Deny access to files that match TYPO3_CONF_VARS[SYS][fileDenyPattern] and whose parent directory // is typo3conf/ (there could be a backup file in typo3conf/ which does not match against the fileDenyPattern) $absoluteFileName = GeneralUtility::getFileAbsFileName(GeneralUtility::resolveBackPath($jumpUrl), false); if (!GeneralUtility::isAllowedAbsPath($absoluteFileName) || !GeneralUtility::verifyFilenameAgainstDenyPattern($absoluteFileName) || GeneralUtility::isFirstPartOfStr($absoluteFileName, PATH_site . 'typo3conf')) { throw new \Exception('The requested file was not allowed to be accessed through Jump URL. The path or file is not allowed.', 1294585194); } try { $resourceFactory = $this->getResourceFactory(); $file = $resourceFactory->retrieveFileOrFolderObject($absoluteFileName); $this->readFileAndExit($file, $mimeType); } catch (\Exception $e) { throw new \Exception('The requested file "' . $jumpUrl . '" for Jump URL was not found..', 1294585193); } }
/** * @test * @dataProvider jumpUrlSecureFailsOnForbiddenFileLocationDataProvider * @expectedException \Exception * @expectedExceptionCode 1294585194 * @param string $path * @param string $path */ public function jumpUrlSecureFailsOnForbiddenFileLocation($path) { $this->jumpUrlHandler->expects($this->once())->method('isLocationDataValid')->with('')->will($this->returnValue(true)); $hash = \FoT3\Jumpurl\JumpUrlUtility::calculateHashSecure($path, '', ''); $_GET['jumpurl'] = $path; $_GET['juSecure'] = '1'; $_GET['juHash'] = $hash; $_GET['locationData'] = ''; $this->jumpUrlHandler->canHandleCurrentUrl(); $this->jumpUrlHandler->handle(); }