Skip to content

Commit

Permalink
Merge pull request #572 from WordPress/feature/ssl-add-input-validation
Browse files Browse the repository at this point in the history
  • Loading branch information
schlessera authored Oct 29, 2021
2 parents 2d600fb + 3b4950d commit 28879ed
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/Ssl.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

namespace WpOrg\Requests;

use WpOrg\Requests\Exception\InvalidArgument;
use WpOrg\Requests\Utility\InputValidator;

/**
* SSL utilities for Requests
*
Expand All @@ -28,8 +31,18 @@ final class Ssl {
* @param string $host Host name to verify against
* @param array $cert Certificate data from openssl_x509_parse()
* @return bool
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $host argument is not a string or a stringable object.
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $cert argument is not an array or array accessible.
*/
public static function verify_certificate($host, $cert) {
if (InputValidator::is_string_or_stringable($host) === false) {
throw InvalidArgument::create(1, '$host', 'string|Stringable', gettype($host));
}

if (InputValidator::has_array_access($cert) === false) {
throw InvalidArgument::create(2, '$cert', 'array|ArrayAccess', gettype($cert));
}

$has_dns_alt = false;

// Check the subjectAltName
Expand Down Expand Up @@ -82,8 +95,13 @@ public static function verify_certificate($host, $cert) {
*
* @param string $reference Reference dNSName
* @return boolean Is the name valid?
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not a string or a stringable object.
*/
public static function verify_reference_name($reference) {
if (InputValidator::is_string_or_stringable($reference) === false) {
throw InvalidArgument::create(1, '$reference', 'string|Stringable', gettype($reference));
}

$parts = explode('.', $reference);

// Check the first part of the name
Expand Down Expand Up @@ -118,8 +136,13 @@ public static function verify_reference_name($reference) {
* @param string $host Requested host
* @param string $reference dNSName to match against
* @return boolean Does the domain match?
* @throws \WpOrg\Requests\Exception\InvalidArgument When either of the passed arguments is not a string or a stringable object.
*/
public static function match_domain($host, $reference) {
if (InputValidator::is_string_or_stringable($host) === false) {
throw InvalidArgument::create(1, '$host', 'string|Stringable', gettype($host));
}

// Check if the reference is blocklisted first
if (self::verify_reference_name($reference) !== true) {
return false;
Expand Down
86 changes: 86 additions & 0 deletions tests/SslTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace WpOrg\Requests\Tests;

use stdClass;
use WpOrg\Requests\Exception\InvalidArgument;
use WpOrg\Requests\Ssl;
use WpOrg\Requests\Tests\TestCase;

Expand Down Expand Up @@ -392,4 +394,88 @@ public function dataVerifyCertificateWithInvalidCertificates() {
),
);
}

/**
* Tests receiving an exception when an invalid input type is passed as $host.
*
* @dataProvider dataInvalidInputType
*
* @covers ::verify_certificate
*
* @param mixed $input Input data.
*
* @return void
*/
public function testVerifyCertificateInvalidInputHost($input) {
$this->expectException(InvalidArgument::class);
$this->expectExceptionMessage('Argument #1 ($host) must be of type string|Stringable');

Ssl::verify_certificate($input, array());
}

/**
* Tests receiving an exception when an invalid input type is passed as $cert.
*
* @dataProvider dataInvalidInputType
*
* @covers ::verify_certificate
*
* @param mixed $input Input data.
*
* @return void
*/
public function testVerifyCertificateInvalidInputCert($input) {
$this->expectException(InvalidArgument::class);
$this->expectExceptionMessage('Argument #2 ($cert) must be of type array|ArrayAccess');

Ssl::verify_certificate('host', $input);
}

/**
* Tests receiving an exception when an invalid input type is passed.
*
* @dataProvider dataInvalidInputType
*
* @covers ::verify_reference_name
*
* @param mixed $input Input data.
*
* @return void
*/
public function testVerifyReferenceNameInvalidInputType($input) {
$this->expectException(InvalidArgument::class);
$this->expectExceptionMessage('Argument #1 ($reference) must be of type string|Stringable');

Ssl::verify_reference_name($input);
}

/**
* Tests receiving an exception when an invalid input type is passed.
*
* @dataProvider dataInvalidInputType
*
* @covers ::match_domain
*
* @param mixed $input Input data.
*
* @return void
*/
public function testInvalidInputType($input) {
$this->expectException(InvalidArgument::class);
$this->expectExceptionMessage('Argument #1 ($host) must be of type string|Stringable');

Ssl::match_domain($input, 'reference');
}

/**
* Data Provider.
*
* @return array
*/
public function dataInvalidInputType() {
return array(
'null' => array(null),
'plain object' => array(new stdClass()),
);
}
}

1 comment on commit 28879ed

@jouhrocha

This comment was marked as spam.

Please sign in to comment.