Issues (1208)

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.

src/LightSaml/Model/AbstractSamlModel.php (12 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
/*
4
 * This file is part of the LightSAML-Core package.
5
 *
6
 * (c) Milos Tomic <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace LightSaml\Model;
13
14
use LightSaml\Error\LightSamlXmlException;
15
use LightSaml\Model\Context\DeserializationContext;
16
use LightSaml\Model\Context\SerializationContext;
17
18
abstract class AbstractSamlModel implements SamlElementInterface
19
{
20
    /**
21
     * @param string               $name
22
     * @param null|string          $namespace
23
     * @param \DOMNode             $parent
24
     * @param SerializationContext $context
25
     *
26
     * @return \DOMElement
27
     */
28 27
    protected function createElement($name, $namespace, \DOMNode $parent, SerializationContext $context)
29
    {
30 27
        if ($namespace) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $namespace of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
31 27
            $result = $context->getDocument()->createElementNS($namespace, $name);
32
        } else {
33
            $result = $context->getDocument()->createElement($name);
34
        }
35 27
        $parent->appendChild($result);
36
37 27
        return $result;
38
    }
39
40
    /**
41
     * @param string               $name
42
     * @param \DOMNode             $parent
43
     * @param SerializationContext $context
44
     * @param string|null          $namespace
45
     *
46
     * @throws \LogicException
47
     */
48 27
    private function oneElementToXml($name, \DOMNode $parent, SerializationContext $context, $namespace = null)
49
    {
50 27
        $value = $this->getPropertyValue($name);
51 27
        if (null == $value) {
52 26
            return;
53
        }
54 21
        if ($value instanceof SamlElementInterface) {
55 20
            $value->serialize($parent, $context);
56 10
        } elseif (is_string($value)) {
57 10
            if ($namespace) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $namespace of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
58 10
                $node = $context->getDocument()->createElementNS($namespace, $name, $value);
59
            } else {
60
                $node = $context->getDocument()->createElement($name, $value);
61
            }
62 10
            $parent->appendChild($node);
63
        } else {
64
            throw new \LogicException(sprintf("Element '%s' must implement SamlElementInterface or be a string", $name));
65
        }
66 21
    }
67
68
    /**
69
     * @param array|string[]       $names
70
     * @param \DOMNode             $parent
71
     * @param SerializationContext $context
72
     * @param string|null          $namespace
73
     */
74 27
    protected function singleElementsToXml(array $names, \DOMNode $parent, SerializationContext $context, $namespace = null)
75
    {
76 27
        foreach ($names as $name) {
77 27
            $this->oneElementToXml($name, $parent, $context, $namespace);
78
        }
79 27
    }
80
81
    /**
82
     * @param array|null           $value
83
     * @param \DOMNode             $node
84
     * @param SerializationContext $context
85
     * @param null|string          $nodeName
86
     * @param null|string          $namespaceUri
87
     *
88
     * @throws \LogicException
89
     */
90 13
    protected function manyElementsToXml($value, \DOMNode $node, SerializationContext $context, $nodeName = null, $namespaceUri = null)
91
    {
92 13
        if (false == $value) {
93 13
            return;
94
        }
95
96 10
        if (false == is_array($value)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
97
            throw new \LogicException('value must be array or null');
98
        }
99
100 10
        foreach ($value as $object) {
101 10
            if ($object instanceof SamlElementInterface) {
102 10
                if ($nodeName) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $nodeName of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
103
                    throw new \LogicException('nodeName should not be specified when serializing array of SamlElementInterface');
104
                }
105 10
                $object->serialize($node, $context);
106 6
            } elseif ($nodeName) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $nodeName of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
107 6
                if ($namespaceUri) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $namespaceUri of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
108 6
                    $child = $context->getDocument()->createElementNS($namespaceUri, $nodeName, (string) $object);
109
                } else {
110
                    $child = $context->getDocument()->createElement($nodeName, (string) $object);
111
                }
112 6
                $node->appendChild($child);
113
            } else {
114 10
                throw new \LogicException('Can handle only array of AbstractSamlModel or strings with nodeName parameter specified');
115
            }
116
        }
117 10
    }
118
119
    /**
120
     * @param \DOMElement            $node
121
     * @param DeserializationContext $context
122
     * @param string                 $nodeName
123
     * @param string|null            $namespacePrefix
124
     * @param string                 $class
125
     * @param string                 $methodName
126
     *
127
     * @throws \LogicException
128
     */
129 47
    protected function manyElementsFromXml(\DOMElement $node, DeserializationContext $context, $nodeName, $namespacePrefix, $class, $methodName)
130
    {
131 47
        if ($namespacePrefix) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $namespacePrefix of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
132 47
            $query = sprintf('%s:%s', $namespacePrefix, $nodeName);
133
        } else {
134
            $query = sprintf('%s', $nodeName);
135
        }
136
137 47
        foreach ($context->getXpath()->query($query, $node) as $xml) {
138
            /* @var \DOMElement $xml */
139 44
            if ($class) {
140
                /** @var SamlElementInterface $object */
141 44
                $object = new $class();
142 44
                if (false == $object instanceof SamlElementInterface) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
143
                    throw new \LogicException(sprintf("Node '%s' class '%s' must implement SamlElementInterface", $nodeName, $class));
144
                }
145 44
                $object->deserialize($xml, $context);
146 44
                $this->{$methodName}($object);
147
            } else {
148 34
                $object = $xml->textContent;
149 44
                $this->{$methodName}($object);
150
            }
151
        }
152 47
    }
153
154
    /**
155
     * @param string      $name
156
     * @param \DOMElement $element
157
     *
158
     * @throws \LogicException
159
     *
160
     * @return bool True if property value is not empty and attribute was set to the element
161
     */
162 27
    protected function singleAttributeToXml($name, \DOMElement $element)
163
    {
164 27
        $value = $this->getPropertyValue($name);
165 27
        if (null !== $value && '' !== $value) {
166 27
            if (is_bool($value)) {
167 1
                $element->setAttribute($name, $value ? 'true' : 'false');
168
            } else {
169 27
                $element->setAttribute($name, $value);
170
            }
171
172 27
            return true;
173
        }
174
175 27
        return false;
176
    }
177
178
    /**
179
     * @param array|string[] $names
180
     * @param \DOMElement    $element
181
     */
182 27
    protected function attributesToXml(array $names, \DOMElement $element)
183
    {
184 27
        foreach ($names as $name) {
185 27
            $this->singleAttributeToXml($name, $element);
186
        }
187 27
    }
188
189
    /**
190
     * @param \DOMNode $node
191
     * @param string   $expectedName
192
     * @param string   $expectedNamespaceUri
193
     */
194 64
    protected function checkXmlNodeName(\DOMNode &$node, $expectedName, $expectedNamespaceUri)
195
    {
196 64
        if ($node instanceof \DOMDocument) {
197 47
            $node = $node->firstChild;
198
        }
199 64
        while ($node && $node instanceof \DOMComment) {
200 2
            $node = $node->nextSibling;
201
        }
202 64
        if (null === $node) {
203
            throw new LightSamlXmlException(sprintf(
204
                "Unable to find expected '%s' xml node and '%s' namespace",
205
                $expectedName,
206
                $expectedNamespaceUri
207
            ));
208 64
        } elseif ($node->localName != $expectedName || $node->namespaceURI != $expectedNamespaceUri) {
209 4
            throw new LightSamlXmlException(sprintf(
210 4
                "Expected '%s' xml node and '%s' namespace but got node '%s' and namespace '%s'",
211 4
                $expectedName,
212 4
                $expectedNamespaceUri,
213 4
                $node->localName,
214 4
                $node->namespaceURI
215
            ));
216
        }
217 62
    }
218
219
    /**
220
     * @param \DOMElement $node
221
     * @param string      $attributeName
222
     */
223 62
    protected function singleAttributeFromXml(\DOMElement $node, $attributeName)
224
    {
225 62
        $value = $node->getAttribute($attributeName);
226 62
        if ('' !== $value) {
227 54
            $setter = 'set'.$attributeName;
228 54
            if (method_exists($this, $setter)) {
229 54
                $this->{$setter}($value);
230
            }
231
        }
232 62
    }
233
234
    /**
235
     * @param \DOMElement            $node
236
     * @param DeserializationContext $context
237
     * @param string                 $elementName
238
     * @param string                 $class
239
     * @param string                 $namespacePrefix
240
     *
241
     * @throws \LogicException
242
     */
243 62
    protected function oneElementFromXml(\DOMElement $node, DeserializationContext $context, $elementName, $class, $namespacePrefix)
244
    {
245 62
        if ($namespacePrefix) {
246 62
            $query = sprintf('./%s:%s', $namespacePrefix, $elementName);
247
        } else {
248
            $query = sprintf('./%s', $elementName);
249
        }
250 62
        $arr = $context->getXpath()->query($query, $node);
251 62
        $value = $arr->length > 0 ? $arr->item(0) : null;
252
253 62
        if ($value) {
254 50
            $setter = 'set'.$elementName;
255 50
            if (false == method_exists($this, $setter)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
256
                throw new \LogicException(sprintf(
257
                    "Unable to find setter for element '%s' in class '%s'",
258
                    $elementName,
259
                    get_class($this)
260
                ));
261
            }
262
263 50
            if ($class) {
264
                /** @var AbstractSamlModel $object */
265 41
                $object = new $class();
266 41
                if (false == $object instanceof \LightSaml\Model\SamlElementInterface) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
267
                    throw new \LogicException(sprintf(
268
                        "Specified class '%s' for element '%s' must implement SamlElementInterface",
269
                        $class,
270
                        $elementName
271
                    ));
272
                }
273
274 41
                $object->deserialize($value, $context);
275
            } else {
276 16
                $object = $value->textContent;
277
            }
278
279 50
            $this->{$setter}($object);
280
        }
281 62
    }
282
283
    /**
284
     * @param \DOMElement            $node
285
     * @param DeserializationContext $context
286
     * @param array                  $options elementName=>class
287
     */
288 62
    protected function singleElementsFromXml(\DOMElement $node, DeserializationContext $context, array $options)
289
    {
290 62
        foreach ($options as $elementName => $info) {
291 62
            $this->oneElementFromXml($node, $context, $elementName, $info[1], $info[0]);
292
        }
293 62
    }
294
295
    /**
296
     * @param \DOMElement $node
297
     * @param array       $attributeNames
298
     */
299 62
    protected function attributesFromXml(\DOMElement $node, array $attributeNames)
300
    {
301 62
        foreach ($attributeNames as $attributeName) {
302 62
            $this->singleAttributeFromXml($node, $attributeName);
303
        }
304 62
    }
305
306
    /**
307
     * @param string $name
308
     *
309
     * @return mixed
310
     *
311
     * @throws \LogicException
312
     */
313 27
    private function getPropertyValue($name)
314
    {
315 27
        if (false !== ($pos = strpos($name, ':'))) {
316
            $name = substr($name, $pos + 1);
317
        }
318 27
        $getter = 'get'.$name.'String';
319 27
        if (false == method_exists($this, $getter)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
320 27
            $getter = 'get'.$name;
321
        }
322 27
        if (false == method_exists($this, $getter)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
323
            throw new \LogicException(sprintf(
324
                "Unable to find getter method for '%s' on '%s'",
325
                $name,
326
                get_class($this)
327
            ));
328
        }
329 27
        $value = $this->{$getter}();
330
331 27
        return $value;
332
    }
333
}
334