Issues (493)

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.

lib/carddav/addressbook.php (4 issues)

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
 * ownCloud - Addressbook
4
 *
5
 * @author Thomas Tanghus
6
 * @copyright 2012-2014 Thomas Tanghus ([email protected])
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
10
 * License as published by the Free Software Foundation; either
11
 * version 3 of the License, or any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public
19
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
23
namespace OCA\Contacts\CardDAV;
24
25
use OCA\Contacts;
26
27
/**
28
 * This class overrides __construct to get access to $addressBookInfo and
29
 * $carddavBackend, \Sabre\CardDAV\AddressBook::getACL() to return read/write
30
 * permissions based on user and shared state and it overrides
31
 * \Sabre\CardDAV\AddressBook::getChild(), \Sabre\CardDAV\AddressBook::getChildren()
32
 * and \Sabre\CardDAV\AddressBook::getMultipleChildren()
33
 * to instantiate \OCA\Contacts\CardDAV\Cards.
34
*/
35
class AddressBook extends \Sabre\CardDAV\AddressBook {
36
37
	/**
38
	* CardDAV backend
39
	*
40
	* @var \Sabre\CardDAV\Backend\AbstractBackend
41
	*/
42
	protected $carddavBackend;
43
44
	/**
45
	* Constructor
46
	*
47
	* @param \Sabre\CardDAV\Backend\AbstractBackend $carddavBackend
48
	* @param array $addressBookInfo
49
	*/
50
	public function __construct(
51
		\Sabre\CardDAV\Backend\AbstractBackend $carddavBackend,
52
		array $addressBookInfo
53
	) {
54
55
		$this->carddavBackend = $carddavBackend;
56
		$this->addressBookInfo = $addressBookInfo;
57
		parent::__construct($carddavBackend, $addressBookInfo);
58
59
	}
60
61
	/**
62
	* Returns a list of ACE's for this node.
63
	*
64
	* Each ACE has the following properties:
65
	*   * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
66
	*     currently the only supported privileges
67
	*   * 'principal', a url to the principal who owns the node
68
	*   * 'protected' (optional), indicating that this ACE is not allowed to
69
	*      be updated.
70
	*
71
	* @return array
72
	*/
73
	public function getACL() {
74
75
		$readprincipal = $this->getOwner();
76
		$writeprincipal = $this->getOwner();
77
		$createprincipal = $this->getOwner();
78
		$deleteprincipal = $this->getOwner();
79
		$uid = $this->carddavBackend->userIDByPrincipal($this->getOwner());
80
81
		$currentUid = \OC::$server->getUserSession()->getUser()->getUId();
82
83
		$readWriteACL = array(
84
			array(
85
				'privilege' => '{DAV:}read',
86
				'principal' => 'principals/' . $currentUid,
87
				'protected' => true,
88
			),
89
			array(
90
				'privilege' => '{DAV:}write',
91
				'principal' => 'principals/' . $currentUid,
92
				'protected' => true,
93
			),
94
		);
95
96
		if($uid !== $currentUid) {
97
			list(, $id) = explode('::', $this->addressBookInfo['id']);
98
			$sharedAddressbook = \OCP\Share::getItemSharedWithBySource('addressbook', $id);
99
			if($sharedAddressbook) {
100
				if(($sharedAddressbook['permissions'] & \OCP\PERMISSION_CREATE)
101
					&& ($sharedAddressbook['permissions'] & \OCP\PERMISSION_UPDATE)
102
					&& ($sharedAddressbook['permissions'] & \OCP\PERMISSION_DELETE)
103
				) {
104
					return $readWriteACL;
105
				}
106
				if ($sharedAddressbook['permissions'] & \OCP\PERMISSION_CREATE) {
107
					$createprincipal = 'principals/' . $currentUid;
108
				}
109
				if ($sharedAddressbook['permissions'] & \OCP\PERMISSION_READ) {
110
					$readprincipal = 'principals/' . $currentUid;
111
				}
112
				if ($sharedAddressbook['permissions'] & \OCP\PERMISSION_UPDATE) {
113
					$writeprincipal = 'principals/' . $currentUid;
114
				}
115
				if ($sharedAddressbook['permissions'] & \OCP\PERMISSION_DELETE) {
116
					$deleteprincipal = 'principals/' . $currentUid;
117
				}
118
			}
119
		} else {
120
			return parent::getACL();
121
		}
122
123
		return array(
124
			array(
125
				'privilege' => '{DAV:}read',
126
				'principal' => $readprincipal,
127
				'protected' => true,
128
			),
129
			array(
130
				'privilege' => '{DAV:}write-content',
131
				'principal' => $writeprincipal,
132
				'protected' => true,
133
			),
134
			array(
135
				'privilege' => '{DAV:}bind',
136
				'principal' => $createprincipal,
137
				'protected' => true,
138
			),
139
			array(
140
				'privilege' => '{DAV:}unbind',
141
				'principal' => $deleteprincipal,
142
				'protected' => true,
143
			),
144
		);
145
146
	}
147
148
	public function getSupportedPrivilegeSet() {
149
150
		return array(
151
			'privilege'  => '{DAV:}all',
152
			'abstract'   => true,
153
			'aggregates' => array(
154
				array(
155
					'privilege'  => '{DAV:}read',
156
					'aggregates' => array(
157
						array(
158
							'privilege' => '{DAV:}read-acl',
159
							'abstract'  => true,
160
						),
161
						array(
162
							'privilege' => '{DAV:}read-current-user-privilege-set',
163
							'abstract'  => true,
164
						),
165
					),
166
				), // {DAV:}read
167
				array(
168
					'privilege'  => '{DAV:}write',
169
					'aggregates' => array(
170
						array(
171
							'privilege' => '{DAV:}write-acl',
172
							'abstract'  => true,
173
						),
174
						array(
175
							'privilege' => '{DAV:}write-properties',
176
							'abstract'  => true,
177
						),
178
						array(
179
							'privilege' => '{DAV:}write-content',
180
							'abstract'  => false,
181
						),
182
						array(
183
							'privilege' => '{DAV:}bind',
184
							'abstract'  => false,
185
						),
186
						array(
187
							'privilege' => '{DAV:}unbind',
188
							'abstract'  => false,
189
						),
190
						array(
191
							'privilege' => '{DAV:}unlock',
192
							'abstract'  => true,
193
						),
194
					),
195
				), // {DAV:}write
196
			),
197
		); // {DAV:}all
198
199
	}
200
201
	/**
202
	* Returns a card
203
	*
204
	* @param string $name
205
	* @return Card
206
	*/
207
	public function getChild($name) {
208
209
		$obj = $this->carddavBackend->getCard($this->addressBookInfo['id'],$name);
210
		if (!$obj) {
211
			throw new \Sabre\DAV\Exception\NotFound('Card not found');
212
		}
213
		return new Card($this->carddavBackend,$this->addressBookInfo,$obj);
214
215
	}
216
217
	/**
218
	* Returns the full list of cards
219
	*
220
	* @return array
221
	*/
222 View Code Duplication
	public function getChildren() {
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
223
224
		$objs = $this->carddavBackend->getCards($this->addressBookInfo['id']);
225
		$children = array();
226
		foreach($objs as $obj) {
227
			$children[] = new Card($this->carddavBackend,$this->addressBookInfo,$obj);
228
		}
229
		return $children;
230
231
	}
232
233
	/**
234
	 * This method receives a list of paths in it's first argument.
235
	 * It must return an array with Node objects.
236
	 *
237
	 * If any children are not found, you do not have to return them.
238
	 *
239
	 * @return array
240
	 */
241 View Code Duplication
	function getMultipleChildren(array $paths) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for getMultipleChildren.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
242
243
		$objs = $this->carddavBackend->getMultipleCards($this->addressBookInfo['id'], $paths);
244
		$children = [];
245
		foreach($objs as $obj) {
246
#			$obj['acl'] = $this->getChildACL();
247
			$children[] = new Card($this->carddavBackend,$this->addressBookInfo,$obj);
248
		}
249
		return $children;
250
251
	}
252
253
	/**
254
	* Returns the last modification date as a unix timestamp.
255
	*
256
	* @return int|null
257
	*/
258
	public function getLastModified() {
259
260
		return $this->carddavBackend->lastModifiedAddressBook($this->addressBookInfo['id']);
261
262
	}
263
}
264