Issues (85)

Security Analysis    no request data  

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
Response Splitting can be used to send arbitrary responses.
  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.
  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.
  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
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
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.

src/XML/samlp/AbstractMessage.php (2 issues)

Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\SAML2\XML\samlp;
6
7
use DateTimeImmutable;
8
use DOMElement;
9
use SimpleSAML\SAML2\Assert\Assert;
10
use SimpleSAML\SAML2\Constants as C;
11
use SimpleSAML\SAML2\Exception\ProtocolViolationException;
12
use SimpleSAML\SAML2\Utils;
13
use SimpleSAML\SAML2\Utils\XPath;
14
use SimpleSAML\SAML2\XML\ExtendableElementTrait;
15
use SimpleSAML\SAML2\XML\saml\Issuer;
16
use SimpleSAML\SAML2\XML\SignableElementTrait;
17
use SimpleSAML\SAML2\XML\SignedElementTrait;
18
use SimpleSAML\XML\Utils\Random as RandomUtils;
19
use SimpleSAML\XMLSecurity\XML\SignableElementInterface;
20
use SimpleSAML\XMLSecurity\XML\SignedElementInterface;
21
22
use function array_pop;
23
24
/**
25
 * Base class for all SAML 2 messages.
26
 *
27
 * Implements what is common between the samlp:RequestAbstractType and
28
 * samlp:StatusResponseType element types.
29
 *
30
 * @package simplesamlphp/saml2
31
 */
32
abstract class AbstractMessage extends AbstractSamlpElement implements SignableElementInterface, SignedElementInterface
33
{
34
    use ExtendableElementTrait;
35
    use SignableElementTrait;
0 ignored issues
show
The trait SimpleSAML\SAML2\XML\SignableElementTrait requires some properties which are not provided by SimpleSAML\SAML2\XML\samlp\AbstractMessage: $ownerDocument, $documentElement
Loading history...
36
    use SignedElementTrait {
0 ignored issues
show
The trait SimpleSAML\SAML2\XML\SignedElementTrait requires some properties which are not provided by SimpleSAML\SAML2\XML\samlp\AbstractMessage: $ownerDocument, $documentElement
Loading history...
37
        SignedElementTrait::getBlacklistedAlgorithms insteadof SignableElementTrait;
38
    }
39
40
41
    /** @var bool */
42
    protected bool $messageContainedSignatureUponConstruction = false;
43
44
    /**
45
     * The original signed XML
46
     *
47
     * @var \DOMElement
48
     * @psalm-suppress PropertyNotSetInConstructor
49
     */
50
    protected DOMElement $xml;
51
52
53
    /**
54
     * Initialize a message.
55
     *
56
     * @param \SimpleSAML\SAML2\XML\saml\Issuer|null $issuer
57
     * @param string|null $id
58
     * @param string $version
59
     * @param \DateTimeImmutable|null $issueInstant
60
     * @param string|null $destination
61
     * @param string|null $consent
62
     * @param \SimpleSAML\SAML2\XML\samlp\Extensions $extensions
63
     *
64
     * @throws \Exception
65
     */
66
    protected function __construct(
67
        protected ?Issuer $issuer = null,
68
        protected ?string $id = null,
69
        protected string $version = '2.0',
70
        protected ?DateTimeImmutable $issueInstant = null,
71
        protected ?string $destination = null,
72
        protected ?string $consent = null,
73
        ?Extensions $extensions = null,
74
    ) {
75
        Assert::nullOrSame($issueInstant?->getTimeZone()->getName(), 'Z', ProtocolViolationException::class);
76
        Assert::nullOrValidNCName($id); // Covers the empty string
77
        Assert::nullOrValidURI($destination);
78
        Assert::nullOrValidURI($consent);
79
80
        $this->setExtensions($extensions);
81
    }
82
83
84
    /**
85
     * Retrieve the identifier of this message.
86
     *
87
     * @return string The identifier of this message
88
     */
89
    public function getId(): string
90
    {
91
        if ($this->id === null) {
92
            return (new RandomUtils())->generateId();
93
        }
94
95
        return $this->id;
96
    }
97
98
99
    /**
100
     * Retrieve the version of this message.
101
     *
102
     * @return string The version of this message
103
     */
104
    public function getVersion(): string
105
    {
106
        return $this->version;
107
    }
108
109
110
    /**
111
     * Retrieve the issue timestamp of this message.
112
     *
113
     * @return \DateTimeImmutable The issue timestamp of this message, as an UNIX timestamp
114
     */
115
    public function getIssueInstant(): DateTimeImmutable
116
    {
117
        if ($this->issueInstant === null) {
118
            return Utils::getContainer()->getClock()->now();
119
        }
120
121
        return $this->issueInstant;
122
    }
123
124
125
    /**
126
     * Retrieve the destination of this message.
127
     *
128
     * @return string|null The destination of this message, or NULL if no destination is given
129
     */
130
    public function getDestination(): ?string
131
    {
132
        return $this->destination;
133
    }
134
135
136
    /**
137
     * Get the given consent for this message.
138
     * Most likely (though not required) a value of urn:oasis:names:tc:SAML:2.0:consent.
139
     *
140
     * @see \SimpleSAML\SAML2\Constants
141
     * @return string|null Consent
142
     */
143
    public function getConsent(): ?string
144
    {
145
        return $this->consent;
146
    }
147
148
149
    /**
150
     * Retrieve the issuer if this message.
151
     *
152
     * @return \SimpleSAML\SAML2\XML\saml\Issuer|null The issuer of this message, or NULL if no issuer is given
153
     */
154
    public function getIssuer(): ?Issuer
155
    {
156
        return $this->issuer;
157
    }
158
159
160
    /**
161
     * Query whether or not the message contained a signature at the root level when the object was constructed.
162
     *
163
     * @return bool
164
     */
165
    public function isMessageConstructedWithSignature(): bool
166
    {
167
        return $this->messageContainedSignatureUponConstruction;
168
    }
169
170
171
    /**
172
     * Get the XML element.
173
     *
174
     * @return \DOMElement
175
     */
176
    public function getXML(): DOMElement
177
    {
178
        return $this->xml;
179
    }
180
181
182
    /**
183
     * Set the XML element.
184
     *
185
     * @param \DOMElement $xml
186
     */
187
    protected function setXML(DOMElement $xml): void
188
    {
189
        $this->xml = $xml;
190
    }
191
192
193
    /**
194
     * @return \DOMElement
195
     */
196
    protected function getOriginalXML(): DOMElement
197
    {
198
        return $this->xml ?? $this->toUnsignedXML();
199
    }
200
201
202
    /**
203
     * Convert this message to an unsigned XML document.
204
     * This method does not sign the resulting XML document.
205
     *
206
     * @return \DOMElement The root element of the DOM tree
207
     */
208
    protected function toUnsignedXML(?DOMElement $parent = null): DOMElement
209
    {
210
        $root = $this->instantiateParentElement($parent);
211
212
        /* Ugly hack to add another namespace declaration to the root element. */
213
        $root->setAttributeNS(C::NS_SAML, 'saml:tmp', 'tmp');
214
        $root->removeAttributeNS(C::NS_SAML, 'tmp');
215
216
        $root->setAttribute('Version', $this->getVersion());
217
        $root->setAttribute('ID', $this->getId());
218
        $root->setAttribute('IssueInstant', $this->getIssueInstant()->format(C::DATETIME_FORMAT));
219
220
        if ($this->getDestination() !== null) {
221
            $root->setAttribute('Destination', $this->getDestination());
222
        }
223
224
        if ($this->getConsent() !== null && $this->getConsent() !== C::CONSENT_UNSPECIFIED) {
225
            $root->setAttribute('Consent', $this->getConsent());
226
        }
227
228
        $this->getIssuer()?->toXML($root);
229
230
        $extensions = $this->getExtensions();
231
        if ($extensions !== null && !$extensions->isEmptyElement()) {
232
            $extensions->toXML($root);
233
        }
234
235
        return $root;
236
    }
237
238
239
    /**
240
     * Create XML from this class
241
     *
242
     * @param \DOMElement|null $parent
243
     * @return \DOMElement
244
     */
245
    public function toXML(?DOMElement $parent = null): DOMElement
246
    {
247
        if ($this->isSigned() === true && $this->signer === null) {
248
            // We already have a signed document and no signer was set to re-sign it
249
            if ($parent === null) {
250
                return $this->xml;
251
            }
252
253
            $node = $parent->ownerDocument?->importNode($this->getXML(), true);
254
            $parent->appendChild($node);
255
            return $parent;
256
        }
257
258
        $e = $this->toUnsignedXML($parent);
259
260
        if ($this->signer !== null) {
261
            $signedXML = $this->doSign($e);
262
263
            // Test for an Issuer
264
            $messageElements = XPath::xpQuery($signedXML, './saml_assertion:Issuer', XPath::getXPath($signedXML));
265
            $issuer = array_pop($messageElements);
266
267
            $signedXML->insertBefore($this->signature?->toXML($signedXML), $issuer->nextSibling);
268
            return $signedXML;
269
        }
270
271
        return $e;
272
    }
273
}
274