Skip to content

Commit 28879ed

Browse files
authored
Merge pull request #572 from WordPress/feature/ssl-add-input-validation
2 parents 2d600fb + 3b4950d commit 28879ed

2 files changed

Lines changed: 109 additions & 0 deletions

File tree

src/Ssl.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
namespace WpOrg\Requests;
1010

11+
use WpOrg\Requests\Exception\InvalidArgument;
12+
use WpOrg\Requests\Utility\InputValidator;
13+
1114
/**
1215
* SSL utilities for Requests
1316
*
@@ -28,8 +31,18 @@ final class Ssl {
2831
* @param string $host Host name to verify against
2932
* @param array $cert Certificate data from openssl_x509_parse()
3033
* @return bool
34+
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $host argument is not a string or a stringable object.
35+
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $cert argument is not an array or array accessible.
3136
*/
3237
public static function verify_certificate($host, $cert) {
38+
if (InputValidator::is_string_or_stringable($host) === false) {
39+
throw InvalidArgument::create(1, '$host', 'string|Stringable', gettype($host));
40+
}
41+
42+
if (InputValidator::has_array_access($cert) === false) {
43+
throw InvalidArgument::create(2, '$cert', 'array|ArrayAccess', gettype($cert));
44+
}
45+
3346
$has_dns_alt = false;
3447

3548
// Check the subjectAltName
@@ -82,8 +95,13 @@ public static function verify_certificate($host, $cert) {
8295
*
8396
* @param string $reference Reference dNSName
8497
* @return boolean Is the name valid?
98+
* @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not a string or a stringable object.
8599
*/
86100
public static function verify_reference_name($reference) {
101+
if (InputValidator::is_string_or_stringable($reference) === false) {
102+
throw InvalidArgument::create(1, '$reference', 'string|Stringable', gettype($reference));
103+
}
104+
87105
$parts = explode('.', $reference);
88106

89107
// Check the first part of the name
@@ -118,8 +136,13 @@ public static function verify_reference_name($reference) {
118136
* @param string $host Requested host
119137
* @param string $reference dNSName to match against
120138
* @return boolean Does the domain match?
139+
* @throws \WpOrg\Requests\Exception\InvalidArgument When either of the passed arguments is not a string or a stringable object.
121140
*/
122141
public static function match_domain($host, $reference) {
142+
if (InputValidator::is_string_or_stringable($host) === false) {
143+
throw InvalidArgument::create(1, '$host', 'string|Stringable', gettype($host));
144+
}
145+
123146
// Check if the reference is blocklisted first
124147
if (self::verify_reference_name($reference) !== true) {
125148
return false;

tests/SslTest.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace WpOrg\Requests\Tests;
44

5+
use stdClass;
6+
use WpOrg\Requests\Exception\InvalidArgument;
57
use WpOrg\Requests\Ssl;
68
use WpOrg\Requests\Tests\TestCase;
79

@@ -392,4 +394,88 @@ public function dataVerifyCertificateWithInvalidCertificates() {
392394
),
393395
);
394396
}
397+
398+
/**
399+
* Tests receiving an exception when an invalid input type is passed as $host.
400+
*
401+
* @dataProvider dataInvalidInputType
402+
*
403+
* @covers ::verify_certificate
404+
*
405+
* @param mixed $input Input data.
406+
*
407+
* @return void
408+
*/
409+
public function testVerifyCertificateInvalidInputHost($input) {
410+
$this->expectException(InvalidArgument::class);
411+
$this->expectExceptionMessage('Argument #1 ($host) must be of type string|Stringable');
412+
413+
Ssl::verify_certificate($input, array());
414+
}
415+
416+
/**
417+
* Tests receiving an exception when an invalid input type is passed as $cert.
418+
*
419+
* @dataProvider dataInvalidInputType
420+
*
421+
* @covers ::verify_certificate
422+
*
423+
* @param mixed $input Input data.
424+
*
425+
* @return void
426+
*/
427+
public function testVerifyCertificateInvalidInputCert($input) {
428+
$this->expectException(InvalidArgument::class);
429+
$this->expectExceptionMessage('Argument #2 ($cert) must be of type array|ArrayAccess');
430+
431+
Ssl::verify_certificate('host', $input);
432+
}
433+
434+
/**
435+
* Tests receiving an exception when an invalid input type is passed.
436+
*
437+
* @dataProvider dataInvalidInputType
438+
*
439+
* @covers ::verify_reference_name
440+
*
441+
* @param mixed $input Input data.
442+
*
443+
* @return void
444+
*/
445+
public function testVerifyReferenceNameInvalidInputType($input) {
446+
$this->expectException(InvalidArgument::class);
447+
$this->expectExceptionMessage('Argument #1 ($reference) must be of type string|Stringable');
448+
449+
Ssl::verify_reference_name($input);
450+
}
451+
452+
/**
453+
* Tests receiving an exception when an invalid input type is passed.
454+
*
455+
* @dataProvider dataInvalidInputType
456+
*
457+
* @covers ::match_domain
458+
*
459+
* @param mixed $input Input data.
460+
*
461+
* @return void
462+
*/
463+
public function testInvalidInputType($input) {
464+
$this->expectException(InvalidArgument::class);
465+
$this->expectExceptionMessage('Argument #1 ($host) must be of type string|Stringable');
466+
467+
Ssl::match_domain($input, 'reference');
468+
}
469+
470+
/**
471+
* Data Provider.
472+
*
473+
* @return array
474+
*/
475+
public function dataInvalidInputType() {
476+
return array(
477+
'null' => array(null),
478+
'plain object' => array(new stdClass()),
479+
);
480+
}
395481
}

0 commit comments

Comments
 (0)