[BUGFIX] Additions to fileDenyPattern give security warning in BE
[Packages/TYPO3.CMS.git] / typo3 / sysext / reports / reports / status / class.tx_reports_reports_status_securitystatus.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009-2011 Ingo Renner <ingo@typo3.org>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25
26 /**
27 * Performs several checks about the system's health
28 *
29 * @author Ingo Renner <ingo@typo3.org>
30 * @package TYPO3
31 * @subpackage reports
32 *
33 * $Id$
34 */
35 class tx_reports_reports_status_SecurityStatus implements tx_reports_StatusProvider {
36
37 /**
38 * Determines the Install Tool's status, mainly concerning its protection.
39 *
40 * @return array List of statuses
41 * @see typo3/sysext/reports/interfaces/tx_reports_StatusProvider::getStatus()
42 */
43 public function getStatus() {
44 $this->executeAdminCommand();
45
46 $statuses = array(
47 'adminUserAccount' => $this->getAdminAccountStatus(),
48 'encryptionKeyEmpty' => $this->getEncryptionKeyStatus(),
49 'fileDenyPattern' => $this->getFileDenyPatternStatus(),
50 'htaccessUpload' => $this->getHtaccessUploadStatus(),
51 'installToolEnabled' => $this->getInstallToolProtectionStatus(),
52 'installToolPassword' => $this->getInstallToolPasswordStatus(),
53 );
54
55 return $statuses;
56 }
57
58 /**
59 * Checks whether a an BE user account named admin with default password exists.
60 *
61 * @return tx_reports_reports_status_Status An tx_reports_reports_status_Status object representing whether a default admin account exists
62 */
63 protected function getAdminAccountStatus() {
64 $value = $GLOBALS['LANG']->getLL('status_ok');
65 $message = '';
66 $severity = tx_reports_reports_status_Status::OK;
67
68 $whereClause = 'username = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr('admin', 'be_users')
69 . ' AND password = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr('5f4dcc3b5aa765d61d8327deb882cf99', 'be_users')
70 . t3lib_BEfunc::deleteClause('be_users');
71 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
72 'uid, username, password',
73 'be_users',
74 $whereClause
75 );
76 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
77 $value = $GLOBALS['LANG']->getLL('status_insecure');
78 $severity = tx_reports_reports_status_Status::ERROR;
79
80 $editUserAccountUrl = 'alt_doc.php?returnUrl=mod.php?M=tools_txreportsM1&edit[be_users][' . $row['uid'] . ']=edit';
81 $message = sprintf(
82 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.backend_admin'),
83 '<a href="' . $editUserAccountUrl . '">',
84 '</a>'
85 );
86 }
87 $GLOBALS['TYPO3_DB']->sql_free_result($res);
88
89 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
90 $GLOBALS['LANG']->getLL('status_adminUserAccount'), $value, $message, $severity
91 );
92 }
93
94 /**
95 * Checks whether the encryption key is empty.
96 *
97 * @return tx_reports_reports_status_Status An tx_reports_reports_status_Status object representing whether the encryption key is empty or not
98 */
99 protected function getEncryptionKeyStatus() {
100 $value = $GLOBALS['LANG']->getLL('status_ok');
101 $message = '';
102 $severity = tx_reports_reports_status_Status::OK;
103
104 if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
105 $value = $GLOBALS['LANG']->getLL('status_insecure');
106 $severity = tx_reports_reports_status_Status::ERROR;
107
108 $url = 'install/index.php?redirect_url=index.php'
109 . urlencode('?TYPO3_INSTALL[type]=config#set_encryptionKey');
110
111 $message = sprintf(
112 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.install_encryption'),
113 '<a href="' . $url . '">',
114 '</a>'
115 );
116 }
117
118 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
119 $GLOBALS['LANG']->getLL('status_encryptionKey'), $value, $message, $severity
120 );
121 }
122
123 /**
124 * Checks if fileDenyPattern was changed which is dangerous on Apache
125 *
126 * @return tx_reports_reports_status_Status An tx_reports_reports_status_Status object representing whether the file deny pattern has changed
127 */
128 protected function getFileDenyPatternStatus() {
129 $value = $GLOBALS['LANG']->getLL('status_ok');
130 $message = '';
131 $severity = tx_reports_reports_status_Status::OK;
132
133 $defaultParts = t3lib_div::trimExplode('|', FILE_DENY_PATTERN_DEFAULT, TRUE);
134 $givenParts = t3lib_div::trimExplode('|', $GLOBALS['TYPO3_CONF_VARS']['BE']['fileDenyPattern'], TRUE);
135 $result = array_intersect($defaultParts, $givenParts);
136 if ($defaultParts !== $result) {
137 $value = $GLOBALS['LANG']->getLL('status_insecure');
138 $severity = tx_reports_reports_status_Status::ERROR;
139
140 $url = 'install/index.php?redirect_url=index.php'
141 . urlencode('?TYPO3_INSTALL[type]=config#set_encryptionKey');
142
143 $message = sprintf(
144 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.file_deny_pattern_partsNotPresent'),
145 '<br /><pre>'
146 . htmlspecialchars(FILE_DENY_PATTERN_DEFAULT)
147 . '</pre><br />'
148 );
149 }
150
151 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
152 $GLOBALS['LANG']->getLL('status_fileDenyPattern'), $value, $message, $severity
153 );
154 }
155
156 /**
157 * Checks if fileDenyPattern allows to upload .htaccess files which is
158 * dangerous on Apache.
159 *
160 * @return tx_reports_reports_status_Status An tx_reports_reports_status_Status object representing whether it's possible to upload .htaccess files
161 */
162 protected function getHtaccessUploadStatus() {
163 $value = $GLOBALS['LANG']->getLL('status_ok');
164 $message = '';
165 $severity = tx_reports_reports_status_Status::OK;
166
167 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['fileDenyPattern'] != FILE_DENY_PATTERN_DEFAULT && t3lib_div::verifyFilenameAgainstDenyPattern('.htaccess')) {
168 $value = $GLOBALS['LANG']->getLL('status_insecure');
169 $severity = tx_reports_reports_status_Status::ERROR;
170 $message = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.file_deny_htaccess');
171 }
172
173 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
174 $GLOBALS['LANG']->getLL('status_htaccessUploadProtection'), $value, $message, $severity
175 );
176 }
177
178 /**
179 * Checks whether memcached is configured, if that's the case we asume it's also used.
180 *
181 * @return boolean True if memcached is used, false otherwise.
182 */
183 protected function isMemcachedUsed() {
184 $memcachedUsed = FALSE;
185
186 $memcachedServers = $this->getConfiguredMemcachedServers();
187 if (count($memcachedServers)) {
188 $memcachedUsed = TRUE;
189 }
190
191 return $memcachedUsed;
192 }
193
194
195 /**
196 * Executes commands like removing the Install Tool enable file.
197 *
198 * @return void
199 */
200 protected function executeAdminCommand() {
201 $command = t3lib_div::_GET('adminCmd');
202
203 switch ($command) {
204 case 'remove_ENABLE_INSTALL_TOOL':
205 unlink(PATH_site . 'typo3conf/ENABLE_INSTALL_TOOL');
206 break;
207 }
208 }
209
210 /**
211 * Checks whether the Install Tool password is set to its default value.
212 *
213 * @return tx_reports_reports_status_Status An tx_reports_reports_status_Status object representing the security of the install tool password
214 */
215 protected function getInstallToolPasswordStatus() {
216 $value = $GLOBALS['LANG']->getLL('status_ok');
217 $message = '';
218 $severity = tx_reports_reports_status_Status::OK;
219
220 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword'] == md5('joh316')) {
221 $value = $GLOBALS['LANG']->getLL('status_insecure');
222 $severity = tx_reports_reports_status_Status::ERROR;
223
224 $changeInstallToolPasswordUrl = 'install/index.php?redirect_url=index.php'
225 . urlencode('?TYPO3_INSTALL[type]=about');
226
227 $message = sprintf(
228 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.install_password'),
229 '<a href="' . $changeInstallToolPasswordUrl . '">',
230 '</a>'
231 );
232 }
233
234 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
235 $GLOBALS['LANG']->getLL('status_installToolPassword'), $value, $message, $severity
236 );
237 }
238
239
240
241 /**
242 * Checks for the existance of the ENABLE_INSTALL_TOOL file.
243 *
244 * @return tx_reports_reports_status_Status An tx_reports_reports_status_Status object representing whether ENABLE_INSTALL_TOOL exists
245 */
246 protected function getInstallToolProtectionStatus() {
247 $enableInstallToolFile = PATH_site . 'typo3conf/ENABLE_INSTALL_TOOL';
248 $value = $GLOBALS['LANG']->getLL('status_disabled');
249 $message = '';
250 $severity = tx_reports_reports_status_Status::OK;
251
252 $enableInstallToolFileExists = is_file($enableInstallToolFile);
253
254 if ($enableInstallToolFileExists) {
255
256 if (trim(file_get_contents($enableInstallToolFile)) === 'KEEP_FILE') {
257
258 $severity = tx_reports_reports_status_Status::WARNING;
259
260 $disableInstallToolUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_URL')
261 . '&amp;adminCmd=remove_ENABLE_INSTALL_TOOL';
262
263 $value = $GLOBALS['LANG']->getLL('status_enabledPermanently');
264
265 $message = sprintf(
266 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.install_enabled'),
267 '<span style="white-space: nowrap;">' . $enableInstallToolFile . '</span>');
268 $message .= ' <a href="' . $disableInstallToolUrl . '">'
269 . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.install_enabled_cmd')
270 . '</a>';
271
272 } else {
273
274 $enableInstallToolFileTtl = filemtime($enableInstallToolFile) + 3600 - time();
275
276 if ($enableInstallToolFileTtl <= 0) {
277
278 unlink($enableInstallToolFile);
279
280 } else {
281
282 $severity = tx_reports_reports_status_Status::NOTICE;
283
284 $disableInstallToolUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_URL')
285 . '&amp;adminCmd=remove_ENABLE_INSTALL_TOOL';
286
287 $value = $GLOBALS['LANG']->getLL('status_enabledTemporarily');
288
289 $message = sprintf(
290 $GLOBALS['LANG']->getLL('status_installEnabledTemporarily'),
291 '<span style="white-space: nowrap;">' . $enableInstallToolFile . '</span>', floor($enableInstallToolFileTtl/60) );
292 $message .= ' <a href="' . $disableInstallToolUrl . '">'
293 . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.install_enabled_cmd')
294 . '</a>';
295 }
296 }
297 }
298
299 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
300 $GLOBALS['LANG']->getLL('status_installTool'), $value, $message, $severity
301 );
302 }
303
304 }
305
306
307 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/reports/reports/status/class.tx_reports_reports_status_securitystatus.php'])) {
308 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/reports/reports/status/class.tx_reports_reports_status_securitystatus.php']);
309 }
310
311 ?>