Skip to content

Commit

Permalink
Perform optional schema validation (default: true)
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Dec 15, 2024
1 parent 6a84e5d commit 3b7b304
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 10 deletions.
48 changes: 42 additions & 6 deletions src/Binding.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@
*/
abstract class Binding
{
/**
* The schema to be used for schema validation
*
* @var string
*/
protected static string $schemaFile = 'resources/schemas/saml-schema-protocol-2.0.xsd';

/**
* Whether or not to perform schema validation
*
* @var bool
*/
protected bool $schemaValidation = true;

/**
* The RelayState associated with the message.
*
Expand Down Expand Up @@ -157,7 +171,20 @@ public function getDestination(): ?string


/**
* Set the RelayState associated with he message.
* Override the destination of a message.
*
* Set to null to use the destination set in the message.
*
* @param string|null $destination The destination the message should be delivered to.
*/
public function setDestination(?string $destination = null): void
{
$this->destination = $destination;
}


/**
* Set the RelayState associated with the message.
*
* @param string|null $relayState The RelayState.
*/
Expand All @@ -179,15 +206,24 @@ public function getRelayState(): ?string


/**
* Override the destination of a message.
* Set the schema validation for the message.
*
* Set to null to use the destination set in the message.
* @param bool $schemaValidation
*/
public function setSchemaValidation(bool $schemaValidation): void
{
$this->schemaValidation = $schemaValidation;
}


/**
* Get the schema validation setting.
*
* @param string|null $destination The destination the message should be delivered to.
* @return bool
*/
public function setDestination(?string $destination = null): void
public function getSchemaValidation(): bool
{
$this->destination = $destination;
return $this->schemaValidation;
}


Expand Down
6 changes: 4 additions & 2 deletions src/Binding/HTTPPost.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,11 @@ public function receive(ServerRequestInterface $request): AbstractMessage
}

$msgStr = base64_decode($msgStr, true);
$msgStr = DOMDocumentFactory::fromString($msgStr)->saveXML();

$document = DOMDocumentFactory::fromString($msgStr);
$document = DOMDocumentFactory::fromString(
xml: $msgStr,
schemaFile: $this->getSchemaValidation() ? self::$schemaFile : null,
);
Utils::getContainer()->debugMessage($document->documentElement, 'in');

$msg = MessageFactory::fromXML($document->documentElement);
Expand Down
5 changes: 4 additions & 1 deletion src/Binding/HTTPRedirect.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,10 @@ public function receive(ServerRequestInterface $request): AbstractMessage
throw new Exception('Error while inflating SAML message.');
}

$document = DOMDocumentFactory::fromString($message);
$document = DOMDocumentFactory::fromString(
xml: $message,
schemaFile: $this->getSchemaValidation() ? self::$schemaFile : null,
);
Utils::getContainer()->debugMessage($document->documentElement, 'in');
$message = MessageFactory::fromXML($document->documentElement);

Expand Down
6 changes: 5 additions & 1 deletion src/Binding/SOAP.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,12 @@ public function receive(/** @scrutinizer ignore-unused */ServerRequestInterface
$xpCache = XPath::getXPath($document->documentElement);
/** @var \DOMElement[] $results */
$results = XPath::xpQuery($xml, '/SOAP-ENV:Envelope/SOAP-ENV:Body/*[1]', $xpCache);
$document = DOMDocumentFactory::fromString(
xml: $results[0]->ownerDocument->saveXML($results[0]),
schemaFile: $this->getSchemaValidation() ? self::$schemaFile : null,
);

return MessageFactory::fromXML($results[0]);
return MessageFactory::fromXML($document->documentElement);
}


Expand Down
3 changes: 3 additions & 0 deletions src/SAML2/Entity/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ final class ServiceProvider
protected bool $responseWasSigned;

/**
* @param bool $performSchemaValidation Whether messages must be validated against the schema
* @param bool $encryptedAssertions Whether assertions must be encrypted
* @param bool $disableScoping Whether to send the samlp:Scoping element in requests
* @param bool $enableUnsolicited Whether to process unsolicited responses
Expand All @@ -68,6 +69,7 @@ final class ServiceProvider
public function __construct(
protected MetadataProviderInterface $metadataProvider,
protected Metadata\ServiceProvider $spMetadata,
protected readonly bool $performSchemaValidation = true,
protected readonly bool $encryptedAssertions = false,
protected readonly bool $disableScoping = false,
protected readonly bool $enableUnsolicited = false,
Expand Down Expand Up @@ -139,6 +141,7 @@ public function receiveResponse(ServerRequestInterface $request): Response
$binding->setSPMetadata($this->spMetadata);
}

$binding->setSchemaValidation($this->performSchemaValidation);
$rawResponse = $binding->receive($request);
Assert::isInstanceOf($rawResponse, Response::class, ResourceNotRecognizedException::class); // Wrong type of msg

Expand Down
11 changes: 11 additions & 0 deletions src/SOAPClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,17 @@ public function send(
);
}

$xpCache = XPath::getXPath($document->documentElement);

Check failure on line 175 in src/SOAPClient.php

View workflow job for this annotation

GitHub Actions / Quality control

Undefined variable: $document

Check failure on line 175 in src/SOAPClient.php

View workflow job for this annotation

GitHub Actions / Quality control

Undefined variable: $document
/** @var \DOMElement[] $results */
$results = XPath::xpQuery($xml, '/SOAP-ENV:Envelope/SOAP-ENV:Body/*[1]', $xpCache);

Check failure on line 177 in src/SOAPClient.php

View workflow job for this annotation

GitHub Actions / Quality control

Undefined variable: $xml

Check failure on line 177 in src/SOAPClient.php

View workflow job for this annotation

GitHub Actions / Quality control

Undefined variable: $xml

// This is already too late to perform schema validation.
// TODO: refactor the SOAPClient and artifact binding. The SOAPClient should be a generic tool from xml-soap
$document = DOMDocumentFactory::fromString(
xml: $results[0]->ownerDocument->saveXML(),
schemaFile: $this->getSchemaValidation() ? self::$schemaFile : null,

Check failure on line 183 in src/SOAPClient.php

View workflow job for this annotation

GitHub Actions / Quality control

Access to an undefined static property SimpleSAML\SAML2\SOAPClient::$schemaFile.

Check failure on line 183 in src/SOAPClient.php

View workflow job for this annotation

GitHub Actions / Quality control

Call to an undefined method SimpleSAML\SAML2\SOAPClient::getSchemaValidation().

Check failure on line 183 in src/SOAPClient.php

View workflow job for this annotation

GitHub Actions / Quality control

Access to an undefined static property SimpleSAML\SAML2\SOAPClient::$schemaFile.

Check failure on line 183 in src/SOAPClient.php

View workflow job for this annotation

GitHub Actions / Quality control

Call to an undefined method SimpleSAML\SAML2\SOAPClient::getSchemaValidation().
);

// Extract the message from the response
/** @var \SimpleSAML\XML\SerializableElementInterface[] $messages */
$messages = $env->getBody()->getElements();
Expand Down

0 comments on commit 3b7b304

Please sign in to comment.