Issues (108)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

service/previewservice.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Gallery
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Olivier Paroz <[email protected]>
9
 *
10
 * @copyright Olivier Paroz 2014-2016
11
 */
12
13
namespace OCA\Gallery\Service;
14
15
use OCP\Files\File;
16
use OCP\ILogger;
17
18
use OCA\Gallery\Environment\Environment;
19
use OCA\Gallery\Preview\Preview;
20
21
/**
22
 * Generates previews
23
 *
24
 * @package OCA\Gallery\Service
25
 */
26
class PreviewService extends Service {
27
	use Base64Encode;
28
29
	/** @var Preview */
30
	private $previewManager;
31
32
	/**
33
	 * Constructor
34
	 *
35
	 * @param string $appName
36
	 * @param Environment $environment
37
	 * @param Preview $previewManager
38
	 * @param ILogger $logger
39
	 */
40
	public function __construct(
41
		$appName,
42
		Environment $environment,
43
		Preview $previewManager,
44
		ILogger $logger
45
	) {
46
		parent::__construct($appName, $environment, $logger);
47
48
		$this->previewManager = $previewManager;
49
	}
50
51
	/**
52
	 * Decides if we should download the file instead of generating a preview
53
	 *
54
	 * @param File $file
55
	 * @param bool $animatedPreview
56
	 *
57
	 * @return bool
58
	 */
59
	public function isPreviewRequired($file, $animatedPreview) {
60
		$mime = $file->getMimeType();
61
62
		if ($mime === 'image/svg+xml') {
63
			return $this->isSvgPreviewRequired();
64
		}
65
		if ($mime === 'image/gif') {
66
			return $this->isGifPreviewRequired($file, $animatedPreview);
67
		}
68
69
		return true;
70
	}
71
72
	/**
73
	 * Returns an array containing everything needed by the client to be able to display a preview
74
	 *
75
	 *    * fileid:  the file's ID
76
	 *    * mimetype: the file's media type
77
	 *    * preview: the preview's content
78
	 *
79
	 * Example logger
80
	 * $this->logger->debug(
81
	 * "[PreviewService] Path : {path} / mime: {mimetype} / fileid: {fileid}",
82
	 * [
83
	 * 'path'     => $preview['data']['path'],
84
	 * 'mimetype' => $preview['data']['mimetype'],
85
	 * 'fileid'   => $preview['fileid']
86
	 * ]
87
	 * );
88
	 *
89
	 * @todo Get the max size from the settings
90
	 *
91
	 * @param File $file
92
	 * @param int $maxX asked width for the preview
93
	 * @param int $maxY asked height for the preview
94
	 * @param bool $keepAspect
95
	 * @param bool $base64Encode
96
	 *
97
	 * @return array <string,\OC_Image|string>|false preview data
0 ignored issues
show
Should the return type not be array|false|array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
98
	 * @throws InternalServerErrorServiceException
99
	 */
100
	public function createPreview(
101
		$file, $maxX = 0, $maxY = 0, $keepAspect = true, $base64Encode = false
102
	) {
103
		try {
104
			$userId = $this->environment->getUserId();
105
			$imagePathFromFolder = $this->environment->getPathFromUserFolder($file);
106
			$this->previewManager->setupView($userId, $file, $imagePathFromFolder);
107
			$preview = $this->previewManager->preparePreview($maxX, $maxY, $keepAspect);
108
			if ($preview && $base64Encode) {
109
				$preview['preview'] = $this->encode($preview['preview']);
110
			}
111
112
			return $preview;
113
		} catch (\Exception $exception) {
114
			throw new InternalServerErrorServiceException('Preview generation has failed');
115
		}
116
	}
117
118
	/**
119
	 * Returns true if the passed mime type is supported
120
	 *
121
	 * In case of a failure, we just return that the media type is not supported
122
	 *
123
	 * @param string $mimeType
124
	 *
125
	 * @return boolean
126
	 */
127
	private function isMimeSupported($mimeType = '*') {
128
		try {
129
			return $this->previewManager->isMimeSupported($mimeType);
130
		} catch (\Exception $exception) {
131
			unset($exception);
132
133
			return false;
134
		}
135
	}
136
137
	/**
138
	 * Decides if we should download the SVG or generate a preview
139
	 *
140
	 * SVGs are downloaded if the SVG converter is disabled
141
	 * Files of any media type are downloaded if requested by the client
142
	 *
143
	 * @return bool
144
	 */
145
	private function isSvgPreviewRequired() {
146
		return $this->isMimeSupported('image/svg+xml');
147
	}
148
149
	/**
150
	 * Decides if we should download the GIF or generate a preview
151
	 *
152
	 * GIFs are downloaded if they're animated and we want to show
153
	 * animations
154
	 *
155
	 * @param File $file
156
	 * @param bool $animatedPreview
157
	 *
158
	 * @return bool
159
	 */
160
	private function isGifPreviewRequired($file, $animatedPreview) {
161
		$gifSupport = $this->isMimeSupported('image/gif');
162
		$animatedGif = $this->isGifAnimated($file);
163
164
		return $gifSupport && !($animatedGif && $animatedPreview);
165
	}
166
167
	/**
168
	 * Tests if a GIF is animated
169
	 *
170
	 * An animated gif contains multiple "frames", with each frame having a
171
	 * header made up of:
172
	 *    * a static 4-byte sequence (\x00\x21\xF9\x04)
173
	 *    * 4 variable bytes
174
	 *    * a static 2-byte sequence (\x00\x2C) (Photoshop uses \x00\x21)
175
	 *
176
	 * We read through the file until we reach the end of the file, or we've
177
	 * found at least 2 frame headers
178
	 *
179
	 * @link http://php.net/manual/en/function.imagecreatefromgif.php#104473
180
	 *
181
	 * @param File $file
182
	 *
183
	 * @return bool
184
	 */
185
	private function isGifAnimated($file) {
186
		$count = 0;
187
		$fileHandle = $this->isFileReadable($file);
188
		if ($fileHandle) {
189
			while (!\feof($fileHandle) && $count < 2) {
190
				$chunk = \fread($fileHandle, 1024 * 100); //read 100kb at a time
191
				$count += \preg_match_all(
192
					'#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches
193
				);
194
			}
195
			\fclose($fileHandle);
196
		}
197
198
		return $count > 1;
199
	}
200
201
	/**
202
	 * Determines if we can read the content of the file and returns a file pointer resource
203
	 *
204
	 * We can't use something like $node->isReadable() as it's too unreliable
205
	 * Some storage classes just check for the presence of the file
206
	 *
207
	 * @param File $file
208
	 *
209
	 * @return resource
210
	 * @throws InternalServerErrorServiceException
211
	 */
212
	private function isFileReadable($file) {
213
		try {
214
			$fileHandle = $file->fopen('rb');
215
			if (!$fileHandle) {
216
				throw new \Exception();
217
			}
218
		} catch (\Exception $exception) {
219
			throw new InternalServerErrorServiceException(
220
				'Something went wrong when trying to read' . $file->getPath()
221
			);
222
		}
223
224
		return $fileHandle;
225
	}
226
}
227