Issues (3948)

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.

app/Foundation/Ldap/User.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
/*
4
 * This file is part of Jitamin.
5
 *
6
 * Copyright (C) Jitamin Team
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Jitamin\Foundation\Ldap;
13
14
use Jitamin\Foundation\Security\Role;
15
use Jitamin\Services\Identity\LdapUserProvider;
16
use LogicException;
17
18
/**
19
 * LDAP User Finder.
20
 */
21
class User
22
{
23
    /**
24
     * Query.
25
     *
26
     * @var Query
27
     */
28
    protected $query;
29
30
    /**
31
     * LDAP Group object.
32
     *
33
     * @var Group
34
     */
35
    protected $group;
36
37
    /**
38
     * Constructor.
39
     *
40
     * @param Query $query
41
     * @param Group $group
42
     */
43
    public function __construct(Query $query, Group $group = null)
44
    {
45
        $this->query = $query;
46
        $this->group = $group;
47
    }
48
49
    /**
50
     * Get user profile.
51
     *
52
     * @static
53
     *
54
     * @param Client $client
55
     * @param string $username
56
     *
57
     * @return LdapUserProvider
58
     */
59
    public static function getUser(Client $client, $username)
60
    {
61
        $self = new static(new Query($client), new Group(new Query($client)));
62
63
        return $self->find($self->getLdapUserPattern($username));
64
    }
65
66
    /**
67
     * Find user.
68
     *
69
     * @param string $query
70
     *
71
     * @return LdapUserProvider
72
     */
73 View Code Duplication
    public function find($query)
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...
74
    {
75
        $this->query->execute($this->getBasDn(), $query, $this->getAttributes());
76
        $user = null;
77
78
        if ($this->query->hasResult()) {
79
            $user = $this->build();
80
        }
81
82
        return $user;
83
    }
84
85
    /**
86
     * Get user groupIds (DN).
87
     *
88
     * 1) If configured, use memberUid and posixGroup
89
     * 2) Otherwise, use memberOf
90
     *
91
     * @param Entry  $entry
92
     * @param string $username
93
     *
94
     * @return string[]
95
     */
96
    protected function getGroups(Entry $entry, $username)
97
    {
98
        $groupIds = [];
99
100
        if (!empty($username) && $this->group !== null && $this->hasGroupUserFilter()) {
101
            $groups = $this->group->find(sprintf($this->getGroupUserFilter(), $username));
102
103
            foreach ($groups as $group) {
104
                $groupIds[] = $group->getExternalId();
105
            }
106
        } else {
107
            $groupIds = $entry->getAll($this->getAttributeGroup());
108
        }
109
110
        return $groupIds;
111
    }
112
113
    /**
114
     * Get role from LDAP groups.
115
     *
116
     * Note: Do not touch the current role if groups are not configured
117
     *
118
     * @param string[] $groupIds
119
     *
120
     * @return string
121
     */
122
    protected function getRole(array $groupIds)
123
    {
124
        if (!$this->hasGroupsConfigured()) {
125
            return;
126
        }
127
128
        foreach ($groupIds as $groupId) {
129
            $groupId = strtolower($groupId);
130
131
            if ($groupId === strtolower($this->getGroupAdminDn())) {
132
                return Role::APP_ADMIN;
133
            } elseif ($groupId === strtolower($this->getGroupManagerDn())) {
134
                return Role::APP_MANAGER;
135
            }
136
        }
137
138
        return Role::APP_USER;
139
    }
140
141
    /**
142
     * Build user profile.
143
     *
144
     * @return LdapUserProvider
145
     */
146
    protected function build()
147
    {
148
        $entry = $this->query->getEntries()->getFirstEntry();
149
        $username = $entry->getFirstValue($this->getAttributeUsername());
150
        $groupIds = $this->getGroups($entry, $username);
151
152
        return new LdapUserProvider(
153
            $entry->getDn(),
154
            $username,
155
            $entry->getFirstValue($this->getAttributeName()),
156
            $entry->getFirstValue($this->getAttributeEmail()),
157
            $this->getRole($groupIds),
158
            $groupIds,
159
            $entry->getFirstValue($this->getAttributePhoto()),
160
            $entry->getFirstValue($this->getAttributeLanguage())
161
        );
162
    }
163
164
    /**
165
     * Ge the list of attributes to fetch when reading the LDAP user entry.
166
     *
167
     * Must returns array with index that start at 0 otherwise ldap_search returns a warning "Array initialization wrong"
168
     *
169
     * @return array
170
     */
171
    public function getAttributes()
172
    {
173
        return array_values(array_filter([
174
            $this->getAttributeUsername(),
175
            $this->getAttributeName(),
176
            $this->getAttributeEmail(),
177
            $this->getAttributeGroup(),
178
            $this->getAttributePhoto(),
179
            $this->getAttributeLanguage(),
180
        ]));
181
    }
182
183
    /**
184
     * Get LDAP account id attribute.
185
     *
186
     * @return string
187
     */
188
    public function getAttributeUsername()
189
    {
190
        if (!LDAP_USER_ATTRIBUTE_USERNAME) {
191
            throw new LogicException('LDAP username attribute empty, check the parameter LDAP_USER_ATTRIBUTE_USERNAME');
192
        }
193
194
        return strtolower(LDAP_USER_ATTRIBUTE_USERNAME);
195
    }
196
197
    /**
198
     * Get LDAP user name attribute.
199
     *
200
     * @return string
201
     */
202
    public function getAttributeName()
203
    {
204
        if (!LDAP_USER_ATTRIBUTE_FULLNAME) {
205
            throw new LogicException('LDAP full name attribute empty, check the parameter LDAP_USER_ATTRIBUTE_FULLNAME');
206
        }
207
208
        return strtolower(LDAP_USER_ATTRIBUTE_FULLNAME);
209
    }
210
211
    /**
212
     * Get LDAP account email attribute.
213
     *
214
     * @return string
215
     */
216
    public function getAttributeEmail()
217
    {
218
        if (!LDAP_USER_ATTRIBUTE_EMAIL) {
219
            throw new LogicException('LDAP email attribute empty, check the parameter LDAP_USER_ATTRIBUTE_EMAIL');
220
        }
221
222
        return strtolower(LDAP_USER_ATTRIBUTE_EMAIL);
223
    }
224
225
    /**
226
     * Get LDAP account memberOf attribute.
227
     *
228
     * @return string
229
     */
230
    public function getAttributeGroup()
231
    {
232
        return strtolower(LDAP_USER_ATTRIBUTE_GROUPS);
233
    }
234
235
    /**
236
     * Get LDAP profile photo attribute.
237
     *
238
     * @return string
239
     */
240
    public function getAttributePhoto()
241
    {
242
        return strtolower(LDAP_USER_ATTRIBUTE_PHOTO);
243
    }
244
245
    /**
246
     * Get LDAP language attribute.
247
     *
248
     * @return string
249
     */
250
    public function getAttributeLanguage()
251
    {
252
        return strtolower(LDAP_USER_ATTRIBUTE_LANGUAGE);
253
    }
254
255
    /**
256
     * Get LDAP Group User filter.
257
     *
258
     * @return string
259
     */
260
    public function getGroupUserFilter()
261
    {
262
        return LDAP_GROUP_USER_FILTER;
263
    }
264
265
    /**
266
     * Return true if LDAP Group User filter is defined.
267
     *
268
     * @return string
269
     */
270
    public function hasGroupUserFilter()
271
    {
272
        return $this->getGroupUserFilter() !== '' && $this->getGroupUserFilter() !== null;
273
    }
274
275
    /**
276
     * Return true if LDAP Group mapping are configured.
277
     *
278
     * @return bool
279
     */
280
    public function hasGroupsConfigured()
281
    {
282
        return $this->getGroupAdminDn() || $this->getGroupManagerDn();
283
    }
284
285
    /**
286
     * Get LDAP admin group DN.
287
     *
288
     * @return string
289
     */
290
    public function getGroupAdminDn()
291
    {
292
        return strtolower(LDAP_GROUP_ADMIN_DN);
293
    }
294
295
    /**
296
     * Get LDAP application manager group DN.
297
     *
298
     * @return string
299
     */
300
    public function getGroupManagerDn()
301
    {
302
        return LDAP_GROUP_MANAGER_DN;
303
    }
304
305
    /**
306
     * Get LDAP user base DN.
307
     *
308
     * @return string
309
     */
310
    public function getBasDn()
311
    {
312
        if (!LDAP_USER_BASE_DN) {
313
            throw new LogicException('LDAP user base DN empty, check the parameter LDAP_USER_BASE_DN');
314
        }
315
316
        return LDAP_USER_BASE_DN;
317
    }
318
319
    /**
320
     * Get LDAP user pattern.
321
     *
322
     * @param string $username
323
     * @param string $filter
324
     *
325
     * @return string
326
     */
327
    public function getLdapUserPattern($username, $filter = LDAP_USER_FILTER)
328
    {
329
        if (!$filter) {
330
            throw new LogicException('LDAP user filter empty, check the parameter LDAP_USER_FILTER');
331
        }
332
333
        return str_replace('%s', $username, $filter);
334
    }
335
}
336