From d7295a8216fda3f36605b6314fe6e2483785e692 Mon Sep 17 00:00:00 2001 From: Enrico Stahn Date: Tue, 6 Nov 2018 11:43:36 +1100 Subject: [PATCH 1/5] feat: Add blacklisting of endpoints with invalid media types - Fixes justinrainbow/json-schema#543 and justinrainbow/json-schema#540 --- src/JsonSchema/Uri/UriRetriever.php | 25 ++++++++++++++++++++++--- tests/Uri/UriRetrieverTest.php | 24 +++++++++++++++++++++++- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/JsonSchema/Uri/UriRetriever.php b/src/JsonSchema/Uri/UriRetriever.php index 65452788..085926b8 100644 --- a/src/JsonSchema/Uri/UriRetriever.php +++ b/src/JsonSchema/Uri/UriRetriever.php @@ -32,6 +32,14 @@ class UriRetriever implements BaseUriRetrieverInterface '|^https?://json-schema.org/draft-(0[34])/schema#?|' => 'package://dist/schema/json-schema-draft-$1.json' ); + /** + * @var array A blacklist for media type ceheck exclusion + */ + protected $mediaTypeBlacklist = array( + 'http://json-schema.org/', + 'https://json-schema.org/' + ); + /** * @var null|UriRetrieverInterface */ @@ -44,6 +52,16 @@ class UriRetriever implements BaseUriRetrieverInterface */ private $schemaCache = array(); + /** + * Adds an endpoint to the media type validation blacklist + * + * @param string $endpoint + */ + public function addBlacklistedEndpoint($endpoint) + { + $this->mediaTypeBlacklist[] = $endpoint; + } + /** * Guarantee the correct media type was encountered * @@ -65,9 +83,10 @@ public function confirmMediaType($uriRetriever, $uri) return; } - if (substr($uri, 0, 23) == 'http://json-schema.org/') { - //HACK; they deliver broken content types - return true; + for ($i = 0, $iMax = count($this->mediaTypeBlacklist); $i < $iMax; $i++) { + if (stripos($uri, $this->mediaTypeBlacklist[$i]) === 0) { + return true; + } } throw new InvalidSchemaMediaTypeException(sprintf('Media type %s expected', Validator::SCHEMA_MEDIA_TYPE)); diff --git a/tests/Uri/UriRetrieverTest.php b/tests/Uri/UriRetrieverTest.php index 8a67a08b..853c15be 100644 --- a/tests/Uri/UriRetrieverTest.php +++ b/tests/Uri/UriRetrieverTest.php @@ -330,7 +330,7 @@ public function testRetrieveSchemaFromPackage() $this->assertEquals('454f423bd7edddf0bc77af4130ed9161', md5(json_encode($schema))); } - public function testJsonSchemaOrgMediaTypeHack() + public function testJsonSchemaOrgMediaTypeBlacklistDefault() { $mock = $this->getMock('JsonSchema\Uri\UriRetriever', array('getContentType')); $mock->method('getContentType')->willReturn('Application/X-Fake-Type'); @@ -339,6 +339,28 @@ public function testJsonSchemaOrgMediaTypeHack() $this->assertTrue($retriever->confirmMediaType($mock, 'http://json-schema.org/')); } + /** + * @expectedException \JsonSchema\Exception\InvalidSchemaMediaTypeException + */ + public function testJsonSchemaOrgMediaTypeBlacklistUnknown() + { + $mock = $this->getMock('JsonSchema\Uri\UriRetriever', array('getContentType')); + $mock->method('getContentType')->willReturn('Application/X-Fake-Type'); + $retriever = new UriRetriever(); + + $retriever->confirmMediaType($mock, 'http://iglucentral.com'); + } + + public function testJsonSchemaOrgMediaTypeBlacklistAdded() + { + $mock = $this->getMock('JsonSchema\Uri\UriRetriever', array('getContentType')); + $mock->method('getContentType')->willReturn('Application/X-Fake-Type'); + $retriever = new UriRetriever(); + $retriever->addBlacklistedEndpoint('http://iglucentral.com'); + + $retriever->confirmMediaType($mock, 'http://iglucentral.com'); + } + public function testSchemaCache() { $retriever = new UriRetriever(); From 3003acd349e11f4905d3ceb6494d88c824650dc6 Mon Sep 17 00:00:00 2001 From: Enrico Stahn Date: Tue, 6 Nov 2018 11:55:46 +1100 Subject: [PATCH 2/5] fix: spelling mistake --- src/JsonSchema/Uri/UriRetriever.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/JsonSchema/Uri/UriRetriever.php b/src/JsonSchema/Uri/UriRetriever.php index 085926b8..12375959 100644 --- a/src/JsonSchema/Uri/UriRetriever.php +++ b/src/JsonSchema/Uri/UriRetriever.php @@ -33,7 +33,7 @@ class UriRetriever implements BaseUriRetrieverInterface ); /** - * @var array A blacklist for media type ceheck exclusion + * @var array A blacklist for media type check exclusion */ protected $mediaTypeBlacklist = array( 'http://json-schema.org/', From a72e0d4a559413480761994f55a3f41c05135721 Mon Sep 17 00:00:00 2001 From: Enrico Stahn Date: Tue, 6 Nov 2018 12:03:39 +1100 Subject: [PATCH 3/5] fix: use example.com as example domains --- tests/Uri/UriRetrieverTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Uri/UriRetrieverTest.php b/tests/Uri/UriRetrieverTest.php index 853c15be..1f6a47b9 100644 --- a/tests/Uri/UriRetrieverTest.php +++ b/tests/Uri/UriRetrieverTest.php @@ -348,7 +348,7 @@ public function testJsonSchemaOrgMediaTypeBlacklistUnknown() $mock->method('getContentType')->willReturn('Application/X-Fake-Type'); $retriever = new UriRetriever(); - $retriever->confirmMediaType($mock, 'http://iglucentral.com'); + $retriever->confirmMediaType($mock, 'http://example.com'); } public function testJsonSchemaOrgMediaTypeBlacklistAdded() @@ -356,9 +356,9 @@ public function testJsonSchemaOrgMediaTypeBlacklistAdded() $mock = $this->getMock('JsonSchema\Uri\UriRetriever', array('getContentType')); $mock->method('getContentType')->willReturn('Application/X-Fake-Type'); $retriever = new UriRetriever(); - $retriever->addBlacklistedEndpoint('http://iglucentral.com'); + $retriever->addBlacklistedEndpoint('http://example.com'); - $retriever->confirmMediaType($mock, 'http://iglucentral.com'); + $retriever->confirmMediaType($mock, 'http://example.com'); } public function testSchemaCache() From ae76ab2ae4a2d0bf6a136aba6ef69cf33fbd70d2 Mon Sep 17 00:00:00 2001 From: Enrico Stahn Date: Tue, 6 Nov 2018 13:35:30 +1100 Subject: [PATCH 4/5] fix: Adjustments based on code review - Change stripos to strpos to match case-insensitive - Rename $mediaTypeBlacklist to $allowedInvalidContentTypeEndpoints - Refactor for to foreach --- src/JsonSchema/Uri/UriRetriever.php | 14 +++++++------- tests/Uri/UriRetrieverTest.php | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/JsonSchema/Uri/UriRetriever.php b/src/JsonSchema/Uri/UriRetriever.php index 12375959..41147a2a 100644 --- a/src/JsonSchema/Uri/UriRetriever.php +++ b/src/JsonSchema/Uri/UriRetriever.php @@ -33,9 +33,9 @@ class UriRetriever implements BaseUriRetrieverInterface ); /** - * @var array A blacklist for media type check exclusion + * @var array A list of endpoints for media type check exclusion */ - protected $mediaTypeBlacklist = array( + protected $allowedInvalidContentTypeEndpoints = array( 'http://json-schema.org/', 'https://json-schema.org/' ); @@ -53,13 +53,13 @@ class UriRetriever implements BaseUriRetrieverInterface private $schemaCache = array(); /** - * Adds an endpoint to the media type validation blacklist + * Adds an endpoint to the media type validation exclusion list * * @param string $endpoint */ - public function addBlacklistedEndpoint($endpoint) + public function addInvalidContentTypeEndpoint($endpoint) { - $this->mediaTypeBlacklist[] = $endpoint; + $this->allowedInvalidContentTypeEndpoints[] = $endpoint; } /** @@ -83,8 +83,8 @@ public function confirmMediaType($uriRetriever, $uri) return; } - for ($i = 0, $iMax = count($this->mediaTypeBlacklist); $i < $iMax; $i++) { - if (stripos($uri, $this->mediaTypeBlacklist[$i]) === 0) { + foreach ($this->allowedInvalidContentTypeEndpoints as $endpoint) { + if (strpos($uri, $endpoint) === 0) { return true; } } diff --git a/tests/Uri/UriRetrieverTest.php b/tests/Uri/UriRetrieverTest.php index 1f6a47b9..ade94307 100644 --- a/tests/Uri/UriRetrieverTest.php +++ b/tests/Uri/UriRetrieverTest.php @@ -356,7 +356,7 @@ public function testJsonSchemaOrgMediaTypeBlacklistAdded() $mock = $this->getMock('JsonSchema\Uri\UriRetriever', array('getContentType')); $mock->method('getContentType')->willReturn('Application/X-Fake-Type'); $retriever = new UriRetriever(); - $retriever->addBlacklistedEndpoint('http://example.com'); + $retriever->addInvalidContentTypeEndpoint('http://example.com'); $retriever->confirmMediaType($mock, 'http://example.com'); } From fce347848476f03dc7f1203f546261ae016c6261 Mon Sep 17 00:00:00 2001 From: Enrico Stahn Date: Tue, 6 Nov 2018 13:53:17 +1100 Subject: [PATCH 5/5] fix: Cleanup test names --- tests/Uri/UriRetrieverTest.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/Uri/UriRetrieverTest.php b/tests/Uri/UriRetrieverTest.php index ade94307..24714a26 100644 --- a/tests/Uri/UriRetrieverTest.php +++ b/tests/Uri/UriRetrieverTest.php @@ -330,19 +330,20 @@ public function testRetrieveSchemaFromPackage() $this->assertEquals('454f423bd7edddf0bc77af4130ed9161', md5(json_encode($schema))); } - public function testJsonSchemaOrgMediaTypeBlacklistDefault() + public function testInvalidContentTypeEndpointsDefault() { $mock = $this->getMock('JsonSchema\Uri\UriRetriever', array('getContentType')); $mock->method('getContentType')->willReturn('Application/X-Fake-Type'); $retriever = new UriRetriever(); $this->assertTrue($retriever->confirmMediaType($mock, 'http://json-schema.org/')); + $this->assertTrue($retriever->confirmMediaType($mock, 'https://json-schema.org/')); } /** * @expectedException \JsonSchema\Exception\InvalidSchemaMediaTypeException */ - public function testJsonSchemaOrgMediaTypeBlacklistUnknown() + public function testInvalidContentTypeEndpointsUnknown() { $mock = $this->getMock('JsonSchema\Uri\UriRetriever', array('getContentType')); $mock->method('getContentType')->willReturn('Application/X-Fake-Type'); @@ -351,7 +352,7 @@ public function testJsonSchemaOrgMediaTypeBlacklistUnknown() $retriever->confirmMediaType($mock, 'http://example.com'); } - public function testJsonSchemaOrgMediaTypeBlacklistAdded() + public function testInvalidContentTypeEndpointsAdded() { $mock = $this->getMock('JsonSchema\Uri\UriRetriever', array('getContentType')); $mock->method('getContentType')->willReturn('Application/X-Fake-Type');