Skip to content

Commit

Permalink
Merge pull request #462 from VitorVieira20/fix/XSS
Browse files Browse the repository at this point in the history
fix: add uri and params validations in guest-reservation, view-schedu…
  • Loading branch information
effgarces authored Dec 9, 2024
2 parents 9978bf2 + 673f2d3 commit 9ed39a2
Show file tree
Hide file tree
Showing 12 changed files with 500 additions and 0 deletions.
13 changes: 13 additions & 0 deletions Pages/Reservation/GuestReservationPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class GuestReservationPage extends NewReservationPage implements IGuestReservati
{
public function PageLoad()
{
$this->RouteValidation();

if (Configuration::Instance()->GetSectionKey(ConfigSection::PRIVACY, ConfigKeys::PRIVACY_ALLOW_GUEST_BOOKING, new BooleanConverter())) {
$this->presenter = $this->GetPresenter();
$this->presenter->PageLoad();
Expand Down Expand Up @@ -79,4 +81,15 @@ public function GetTermsOfServiceAcknowledgement()
{
return $this->GetCheckbox(FormKeys::TOS_ACKNOWLEDGEMENT);
}

protected function RouteValidation()
{
URIScriptValidator::validate($_SERVER['REQUEST_URI'], '/dashboard.php');

if (preg_match('/(?:\?|&)(redirect)=([^&]+)/', $_SERVER['REQUEST_URI'])) {
ParamsValidator::validate(RouteParamsKeys::GUEST_RESERVATION_FROM_CALENDAR, $_SERVER['REQUEST_URI'], '/view-calendar.php', false);
} else {
ParamsValidator::validate(RouteParamsKeys::GUEST_RESERVATION_FROM_SCHEDULE, $_SERVER['REQUEST_URI'], '/view-schedule.php', false);
}
}
}
3 changes: 3 additions & 0 deletions Pages/ViewCalendarPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ public function __construct()

public function DisplayPage()
{
URIScriptValidator::validate($_SERVER['REQUEST_URI'], '/view-calendar.php');
ParamsValidator::validate(RouteParamsKeys::VIEW_CALENDAR, $_SERVER['REQUEST_URI'], '/view-calendar.php', true);

$this->Set('pageUrl', Pages::VIEW_CALENDAR);
$this->Set('CreateReservationPage', Pages::GUEST_RESERVATION);
$this->Set('HideCreate', !Configuration::Instance()->GetSectionKey(ConfigSection::PRIVACY, ConfigKeys::PRIVACY_ALLOW_GUEST_BOOKING, new BooleanConverter()));
Expand Down
3 changes: 3 additions & 0 deletions Pages/ViewSchedulePage.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ public function __construct()

public function ProcessPageLoad()
{
URIScriptValidator::validate($_SERVER['REQUEST_URI'], '/view-schedule.php');
ParamsValidator::validate(RouteParamsKeys::VIEW_SCHEDULE, $_SERVER['REQUEST_URI'], '/view-schedule.php', true);

$user = new NullUserSession();
$this->_presenter->PageLoad($user);

Expand Down
98 changes: 98 additions & 0 deletions lib/Common/Validators/URI/IParamsValidatorMethods.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

interface IParamsValidatorMethods
{
/**
* Check if param is a numerical value
*
* @param string $param - Query param in URI
* @param string $requestURI - Request URI to check the param
*
* @return bool Returns true if is valid
*/
public static function numericalValidator(string $param, string $requestURI): bool;

/**
* Check if param exists in URI
*
* @param string $param - Query param in URI
* @param string $requestURI - Request URI to check the param
*
* @return bool Returns true if is valid
*/
public static function existsInURLValidator(string $param, string $requestURI): bool;

/**
* Check if param is a valid date (YYYY-MM-DD)
*
* @param string $param - Query param in URI
* @param string $requestURI - Request URI to check the param
*
* @return bool Returns true if is valid
*/
public static function dateValidator(string $param, string $requestURI): bool;

/**
* Check if param is a valid date (YYYY-MM-DD) and (YYYY-M-D)
* This can be a list a of date
*
* @param string $param - Query param in URI
* @param string $requestURI - Request URI to check the param
*
* @return bool Returns true if is valid
*/
public static function simpleDateValidatorList(string $param, string $requestURI): bool;

/**
* Check if params is a valid date (YYYY-MM-DD HH:MM), hours and minutes can have one or two digits
*
* @param string $param - Query param in URI
* @param string $requestURI - Request URI to check the param
*
* @return bool Returns true if is valid
*/
public static function simpleDateTimeValidator(string $param, string $requestURI): bool;

/**
* Check if params is a valid date (YYYY-MMM-DD HH:MM:SS)
*
* @param string $param - Query param in URI
* @param string $requestURI - Request URI to check the param
*
* @return bool Returns true if is valid
*/
public static function complexDateTimedateValidator(string $param, string $requestURI): bool;


/**
* Check if param is a valid redirect in guest-reservation route
*
* @param string $param - Query param in URI
* @param string $requestURI - Request URI to check the param
*
* @return bool Returns true if is valid
*/
public static function redirectGuestReservationValidator(string $requestURI): bool;

/**
* Check if param is a valid boolean value
*
* @param string $param - Query param in URI
* @param string $requestURI - Request URI to check the param
*
* @return bool Returns true if is valid
*/
public static function booleanValidator(string $param, string $requestURI): bool;


/**
* Check if param match with expecter value
*
* @param string $param - Query param in URI
* @param string $expectedValue - Expected value to perform the match
* @param string $requestURI - Request URI to check the param
*
* @return bool Returns true if is valid
*/
public static function matchValidator(string $param, string $expectedValue, string $requestURI): bool;
}
16 changes: 16 additions & 0 deletions lib/Common/Validators/URI/IURIScriptValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

interface IURIScriptValidator
{
/**
* Validates a given URI for malicious scripts or harmful data.
*
* This function checks the URI for some commonly scripts patterns (<script></script>; ''; "")
*
* @param string $requestURI - The request URI to be validated for malicious content.
* @param string $redirectURL - The URL to which the user will be redirected if the URI is invalid.
*
* @return void - No return value. Redirection occurs if the URI is invalid.
*/
public static function validate(string $requestURI, string $redirectURL): void;
}
116 changes: 116 additions & 0 deletions lib/Common/Validators/URI/ParamsValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php

class ParamsValidator
{

/**
* Validates the parameters in the request URI based on predefined rules.
*
* @param array $params An associative array where the key is the parameter name and the value is the validation rule(s).
* @param string $requestURI The full URI of the request.
* @param string $redirectURL The URL to redirect to if validation fails.
* @param bool $optional A flag indicating if the validation is optional. If set to `true`, the absence of parameters won't cause a redirection.
*
* @return void
*/
public static function validate(array $params, string $requestURI, string $redirectURL, bool $optional): void
{
$segments = explode('?', $requestURI);

// If there are no params and the validation is optional, return without doing anything
if (empty($segments[1])) {
if (!$optional) {
header("Location: " . $redirectURL);
exit;
}
return;
}

$valid = true;

foreach ($params as $key => $validationType) {

// If is an array of validations
if (is_array($validationType)) {
$allFailed = true;
$allMatchValid = true;
foreach ($validationType as $validation) {

// If the validation is an array so its a mecth validation
if (is_array($validation)) {
foreach ($validation as $index => $expectedValue) {
if (self::runValidation($key, ParamsValidatorKeys::MATCH, $expectedValue, $requestURI)) {
$allMatchValid = false;
break;
}
}
} else {
if (self::runValidation($key, $validation, null, $requestURI)) {
$allFailed = false;
break;
}
}
}

if ($allFailed && $allMatchValid) {
$valid = false;
}
} else {
if (!self::runValidation($key, $validationType, null, $requestURI)) {
$valid = false;
}
}
}

if (!$valid) {
header("Location: " . $redirectURL);
exit;
}
}


/**
* Executes a specific validation based on the validation type.
*
* @param string $value The parameter value to validate.
* @param string $validationType The type of validation to run.
* @param mixed $expectedValue The expected value for match validation (optional).
* @param string $requestURI The full URI of the request.
*
* @return bool Returns `true` if validation passes, otherwise `false`.
*/
private static function runValidation(string $value, string $validationType, $expectedValue, string $requestURI): bool
{
switch ($validationType) {
case ParamsValidatorKeys::NUMERICAL:
return ParamsValidatorMethods::numericalValidator($value, $requestURI);

case ParamsValidatorKeys::DATE:
return ParamsValidatorMethods::dateValidator($value, $requestURI);

case ParamsValidatorKeys::SIMPLE_DATE:
return ParamsValidatorMethods::simpleDateValidatorList($value, $requestURI);

case ParamsValidatorKeys::SIMPLE_DATETIME:
return ParamsValidatorMethods::simpleDateTimeValidator($value, $requestURI);

case ParamsValidatorKeys::COMPLEX_DATETIME:
return ParamsValidatorMethods::complexDateTimedateValidator($value, $requestURI);

case ParamsValidatorKeys::EXISTS:
return ParamsValidatorMethods::existsInURLValidator($value, $requestURI);

case ParamsValidatorKeys::REDIRECT_GUEST_RESERVATION:
return ParamsValidatorMethods::redirectGuestReservationValidator($requestURI);

case ParamsValidatorKeys::BOOLEAN:
return ParamsValidatorMethods::booleanValidator($value, $requestURI);

case ParamsValidatorKeys::MATCH:
return ParamsValidatorMethods::matchValidator($value, $expectedValue, $requestURI);

default:
return false;
}
}
}
Loading

0 comments on commit 9ed39a2

Please sign in to comment.