Issues (3882)

Security Analysis    39 potential vulnerabilities

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

  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.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  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.
  Response Splitting (9)
Response Splitting can be used to send arbitrary responses.
  File Manipulation (2)
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.
  File Exposure (7)
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.
  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.
  Code Injection (13)
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  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.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  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.
  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.
  Cross-Site Scripting (8)
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.
  Header Injection
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.

include/Loader.php (1 issue)

1
<?php
2
/* +**********************************************************************************
3
 * The contents of this file are subject to the vtiger CRM Public License Version 1.1
4
 * ("License"); You may not use this file except in compliance with the License
5
 * The Original Code is:  vtiger CRM Open Source
6
 * The Initial Developer of the Original Code is vtiger.
7
 * Portions created by vtiger are Copyright (C) vtiger.
8
 * All Rights Reserved.
9
 * Contributor(s): YetiForce S.A.
10
 * ********************************************************************************** */
11
12
class Vtiger_Loader
13
{
14
	protected static $includeCache = [];
15
	protected static $includePathCache = [];
16
	protected static $componentClassCache = [];
17
	protected static $loaderDirs = [
18
		'custom.modules.',
19
		'modules.',
20
	];
21
22
	/**
23
	 * Static function to resolve the qualified php filename to absolute path.
24
	 *
25
	 * @param string $qualifiedName
26
	 * @param mixed  $fileExtension
27 111
	 *
28
	 * @return string Absolute File Name
29 111
	 */
30 111
	public static function resolveNameToPath($qualifiedName, $fileExtension = 'php')
31 111
	{
32
		if ($file = self::resolveRelativePath($qualifiedName, $fileExtension)) {
33
			$file = ROOT_DIRECTORY . DIRECTORY_SEPARATOR . ('php' !== $fileExtension ? 'public_html' . DIRECTORY_SEPARATOR : '') . $file;
34 111
		}
35 111
		return $file;
36 1
	}
37
38
	/**
39 111
	 * Static function to resolve the qualified php filename to relative path.
40 4
	 *
41 4
	 * @param string $qualifiedName
42
	 * @param string $fileExtension
43 108
	 *
44 108
	 * @return string
45
	 */
46 111
	public static function resolveRelativePath(string $qualifiedName, string $fileExtension = 'php'): string
47
	{
48
		$allowedExtensions = ['php', 'js', 'css', 'less'];
49
		$file = '';
50
		if (\in_array($fileExtension, $allowedExtensions)) {
51
			if (0 === strpos($qualifiedName, '~')) {
52
				$file = str_replace('~', '', $qualifiedName);
53
			} else {
54
				$file = str_replace('.', DIRECTORY_SEPARATOR, $qualifiedName) . '.' . $fileExtension;
55
			}
56 4
		}
57
		return $file;
58 4
	}
59 1
60
	/**
61
	 * Returns canonicalized absolute pathname for css/js files.
62 4
	 *
63
	 * @param string $filePath
64 4
	 * @param string $fileExtension
65
	 * @param array  $layoutPaths
66
	 *
67
	 * @return string
68
	 */
69 4
	public static function getRealPathFile(string $filePath, string $fileExtension, array $layoutPaths): string
70
	{
71 4
		$realPath = '';
72
		$checkMin = \vtlib\Functions::getMinimizationOptions($fileExtension);
73 4
		foreach ($layoutPaths as $layoutPath) {
74
			$realPaths = [];
75 4
			$completeFilePath = ROOT_DIRECTORY . DIRECTORY_SEPARATOR . 'public_html' . DIRECTORY_SEPARATOR . $layoutPath . self::resolveRelativePath($filePath, $fileExtension);
76 4
			if ($checkMin && false === strpos($completeFilePath, '.min.')) {
77
				$realPaths[] = substr($completeFilePath, 0, -(\strlen($fileExtension) + 1)) . ".min.{$fileExtension}";
78 4
			}
79
			$realPaths[] = $completeFilePath;
80
			foreach ($realPaths as $path) {
81
				if ($path && is_file($path)) {
82
					$realPath = $path;
83
					break 2;
84
				}
85
			}
86
		}
87
		return $realPath;
88
	}
89
90
	/**
91
	 * Function to include a given php file through qualified file name.
92
	 *
93
	 * @param string $qualifiedName
94
	 *
95
	 * @return bool
96
	 */
97
	public static function includeOnce($qualifiedName)
98
	{
99
		if (isset(self::$includeCache[$qualifiedName])) {
100
			return true;
101
		}
102
103
		$file = self::resolveNameToPath($qualifiedName);
104
105
		if (!file_exists($file)) {
106
			return false;
107 106
		}
108
109
		// Check file inclusion before including it
110 106
		\vtlib\Deprecated::checkFileAccessForInclusion($file);
111
112 106
		$status = include_once $file;
113
114
		$success = (0 !== $status);
115 106
116
		if ($success) {
117 106
			self::$includeCache[$qualifiedName] = $file;
118 14
		}
119 14
		return $success;
120 14
	}
121 14
122 14
	public static function includePath($qualifiedName)
123 14
	{
124 14
		// Already included?
125 14
		if (isset(self::$includePathCache[$qualifiedName])) {
126 14
			return true;
127
		}
128 14
129 14
		$path = realpath(self::resolveNameToPath($qualifiedName));
130
		self::$includePathCache[$qualifiedName] = $path;
131
132
		set_include_path($path . PATH_SEPARATOR . get_include_path());
133 106
134
		return true;
135 106
	}
136 106
137 106
	/**
138 54
	 * Function to get the class name of a given Component, of given Type, for a given Module.
139
	 *
140
	 * @param string $componentType
141
	 * @param string $componentName
142 106
	 * @param string $moduleName
143 14
	 * @param mixed  $throwException
144 14
	 *
145 14
	 * @throws \App\Exceptions\AppException
146
	 *
147
	 * @return string Required Class Name
148
	 */
149
	public static function getComponentClassName($componentType, $componentName, $moduleName = 'Vtiger', $throwException = true)
150
	{
151 106
		$cacheKey = "$componentType|$componentName|$moduleName";
152 14
		if (isset(self::$componentClassCache[$cacheKey])) {
153 14
			return self::$componentClassCache[$cacheKey];
154 14
		}
155
		// Change component type from view to views, action to actions to navigate to the right path.
156
		$componentTypeDirectory = strtolower($componentType) . 's';
157
		// Change the Module directory & class, along with intermediate fall back directory and class, if module names has submodule as well
158
		if (false !== strpos($moduleName, ':')) {
159
			$load = [
160 106
				str_replace(':', '_', $moduleName) => str_replace(':', '.', $moduleName),
161 106
			];
162 106
			$moduleHierarchyParts = explode(':', $moduleName);
163 86
			$actualModule = $moduleHierarchyParts[\count($moduleHierarchyParts) - 1];
164
			if ('Users' !== $actualModule) {
165
				$baseModule = $moduleHierarchyParts[0];
166
				if ('Settings' === $baseModule) {
167 1
					$baseModule = 'Settings:Vtiger';
168
				}
169
				$load[str_replace(':', '_', $baseModule)] = str_replace(':', '.', $baseModule);
170
			}
171 1
			$load[$actualModule] = $actualModule;
172
			$load['Vtiger'] = 'Vtiger';
173
		} else {
174
			$load = [
175
				$moduleName => $moduleName,
176
				'Vtiger' => 'Vtiger',
177
			];
178
		}
179
		foreach ($load as $classPath => $classDir) {
180
			foreach (self::$loaderDirs as $dir) {
181 14
				if (file_exists(self::resolveNameToPath("$dir$classDir.$componentTypeDirectory.$componentName"))) {
182
					return self::$componentClassCache[$cacheKey] = "{$classPath}_{$componentName}_{$componentType}";
183 14
				}
184 14
			}
185 14
		}
186 4
		if ($throwException) {
187
			\App\Log::error("Error Vtiger_Loader::getComponentClassName($componentType, $componentName, $moduleName): Handler not found");
188 4
			throw new \App\Exceptions\AppException('LBL_HANDLER_NOT_FOUND');
189 4
		}
190
		return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
191
	}
192 4
193 4
	/**
194 4
	 * Function to auto load the required class files matching the directory pattern modules/xyz/types/Abc.php for class xyz_Abc_Type.
195
	 *
196 4
	 * @param string $className
197 3
	 *
198
	 * @return bool
199
	 */
200
	public static function autoLoad($className)
201 13
	{
202
		$parts = explode('_', $className);
203
		$noOfParts = \count($parts);
204
		if ($noOfParts > 2) {
205
			foreach (self::$loaderDirs as $filePath) {
206
				// Append modules and sub modules names to the path
207
				for ($i = 0; $i < ($noOfParts - 2); ++$i) {
208
					$filePath .= $parts[$i] . '.';
209
				}
210
211
				$fileName = $parts[$noOfParts - 2];
212
				$fileComponentName = strtolower($parts[$noOfParts - 1]) . 's';
213
				$filePath .= $fileComponentName . '.' . $fileName;
214
				if (file_exists(self::resolveNameToPath($filePath))) {
215
					return self::includeOnce($filePath);
216
				}
217
			}
218
		}
219
		return false;
220
	}
221
}
222
223
spl_autoload_register('Vtiger_Loader::autoLoad');
224