Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 2 additions & 23 deletions src/Saml2/LogoutRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -390,29 +390,8 @@ public function isValid($retrieveParametersFromServer = false)
}

// Check destination
if ($dom->documentElement->hasAttribute('Destination')) {
$destination = $dom->documentElement->getAttribute('Destination');
if (empty($destination)) {
if (!$security['relaxDestinationValidation']) {
throw new ValidationError(
"The LogoutRequest has an empty Destination value",
ValidationError::EMPTY_DESTINATION
);
}
} else {
$urlComparisonLength = $security['destinationStrictlyMatches'] ? strlen($destination) : strlen($currentURL);
if (strncmp($destination, $currentURL, $urlComparisonLength) !== 0) {
$currentURLNoRouted = Utils::getSelfURLNoQuery();
$urlComparisonLength = $security['destinationStrictlyMatches'] ? strlen($destination) : strlen($currentURLNoRouted);
if (strncmp($destination, $currentURLNoRouted, $urlComparisonLength) !== 0) {
throw new ValidationError(
"The LogoutRequest was received at $currentURL instead of $destination",
ValidationError::WRONG_DESTINATION
);
}
}
}
}
Validator::$security = $security;
Validator::checkDestination($dom, $currentURL, 'LogoutRequest');

$nameId = static::getNameId($dom, $this->_settings->getSPkey());

Expand Down
26 changes: 3 additions & 23 deletions src/Saml2/LogoutResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,29 +182,9 @@ public function isValid($requestId = null, $retrieveParametersFromServer = false

$currentURL = Utils::getSelfRoutedURLNoQuery();

if ($this->document->documentElement->hasAttribute('Destination')) {
$destination = $this->document->documentElement->getAttribute('Destination');
if (empty($destination)) {
if (!$security['relaxDestinationValidation']) {
throw new ValidationError(
"The LogoutResponse has an empty Destination value",
ValidationError::EMPTY_DESTINATION
);
}
} else {
$urlComparisonLength = $security['destinationStrictlyMatches'] ? strlen($destination) : strlen($currentURL);
if (strncmp($destination, $currentURL, $urlComparisonLength) !== 0) {
$currentURLNoRouted = Utils::getSelfURLNoQuery();
$urlComparisonLength = $security['destinationStrictlyMatches'] ? strlen($destination) : strlen($currentURLNoRouted);
if (strncmp($destination, $currentURLNoRouted, $urlComparisonLength) !== 0) {
throw new ValidationError(
"The LogoutResponse was received at $currentURL instead of $destination",
ValidationError::WRONG_DESTINATION
);
}
}
}
}
// Check destination
Validator::$security = $security;
Validator::checkDestination($this->document, $currentURL, 'LogoutResponse');

if ($security['wantMessagesSigned'] && !isset($_GET['Signature'])) {
throw new ValidationError(
Expand Down
28 changes: 2 additions & 26 deletions src/Saml2/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -271,32 +271,8 @@ public function isValid($requestId = null)
}

// Check destination
if ($this->document->documentElement->hasAttribute('Destination')) {
$destination = $this->document->documentElement->getAttribute('Destination');
if (isset($destination)) {
$destination = trim($destination);
}
if (empty($destination)) {
if (!$security['relaxDestinationValidation']) {
throw new ValidationError(
"The response has an empty Destination value",
ValidationError::EMPTY_DESTINATION
);
}
} else {
$urlComparisonLength = $security['destinationStrictlyMatches'] ? strlen($destination) : strlen($currentURL);
if (strncmp($destination, $currentURL, $urlComparisonLength) !== 0) {
$currentURLNoRouted = Utils::getSelfURLNoQuery();
$urlComparisonLength = $security['destinationStrictlyMatches'] ? strlen($destination) : strlen($currentURLNoRouted);
if (strncmp($destination, $currentURLNoRouted, $urlComparisonLength) !== 0) {
throw new ValidationError(
"The response was received at $currentURL instead of $destination",
ValidationError::WRONG_DESTINATION
);
}
}
}
}
Validator::$security = $security;
Validator::checkDestination($this->document, $currentURL, 'Response');

// Check audience
$validAudiences = $this->getAudiences();
Expand Down
57 changes: 57 additions & 0 deletions src/Saml2/Validator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace OneLogin\Saml2;

use DOMDocument;

/**
* Class Validador
*
* This class provides methods to validate SAML messages.
*/
class Validator
{

/**
* Security settings.
*
* @var array
*/
public static array $security;

/**
* Checks the Destination attribute of a SAML message.
*
* @param DOMDocument $document The SAML message as a DOMDocument.
* @param string $currentURL The current URL where the message was received.
* @param string $method The method being validated (e.g., "AuthnRequest", "Response").
*
* @throws ValidationError If the Destination is invalid.
*/
public static function checkDestination(DOMDocument $document, string $currentURL, string $method)
{
$destination = $document->documentElement->getAttribute('Destination');
$destination = trim($destination);
if (empty($destination)) {
if (!self::$security['relaxDestinationValidation']) {
throw new ValidationError(
"The $method has an empty Destination value",
ValidationError::EMPTY_DESTINATION
);
}
} else {
$urlComparisonLength = self::$security['destinationStrictlyMatches'] ? strlen($destination) : strlen($currentURL);
if (strncmp($destination, $currentURL, $urlComparisonLength) !== 0) {
$currentURLNoRouted = Utils::getSelfURLNoQuery();
$urlComparisonLength = self::$security['destinationStrictlyMatches'] ? strlen($destination) : strlen($currentURLNoRouted);
if (strncmp($destination, $currentURLNoRouted, $urlComparisonLength) !== 0) {
throw new ValidationError(
"The $method was received at $currentURL instead of $destination",
ValidationError::WRONG_DESTINATION
);
}
}
}
}

}