Browse Source

Allow iframe from YouTube and Vimeo

pull/97/head
swentel 1 year ago
parent
commit
4c8fc24c1f
6 changed files with 62 additions and 0 deletions
  1. +4
    -0
      controllers/Parse.php
  2. +10
    -0
      lib/XRay/Formats/Format.php
  3. +2
    -0
      lib/XRay/Parser.php
  4. +9
    -0
      lib/helpers.php
  5. +18
    -0
      tests/SanitizeTest.php
  6. +19
    -0
      tests/data/sanitize.example/entry-with-iframe-video

+ 4
- 0
controllers/Parse.php View File

@ -71,6 +71,10 @@ class Parse {
$opts['include-mf1'] = $request->get('include-mf1') == 'false' ? false : true;
}
if($request->get('allow-iframe-video')) {
$opts['allowIframeVideo'] = $request->get('allow-iframe-video') == 'true';
}
$url = $request->get('url');
$html = $request->get('html') ?: $request->get('body');

+ 10
- 0
lib/XRay/Formats/Format.php View File

@ -67,6 +67,16 @@ abstract class Format implements iFormat {
$config = HTMLPurifier_Config::createDefault();
$config->set('Cache.DefinitionImpl', null);
if (\p3k\XRay\allow_iframe_video()) {
$allowed[] = 'iframe';
$config->set('HTML.SafeIframe', true);
$config->set('URI.SafeIframeRegexp', '%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%');
$config->set('AutoFormat.RemoveEmpty', true);
// Removes iframe in case it has no src. This strips the non-allowed domains.
$config->set('AutoFormat.RemoveEmpty.Predicate', array('iframe' => array(0 => 'src')));
}
$config->set('HTML.AllowedElements', $allowed);
if($baseURL) {

+ 2
- 0
lib/XRay/Parser.php View File

@ -12,6 +12,8 @@ class Parser {
}
public function parse($http_response, $opts=[]) {
$allowIframeVideo = isset($opts['allowIframeVideo']) ? $opts['allowIframeVideo'] : false;
allow_iframe_video($allowIframeVideo);
$document = $this->parse_document($http_response, $opts);
// If a target parameter was provided, make sure a link to it exists in the parsed document

+ 9
- 0
lib/helpers.php View File

@ -58,3 +58,12 @@ function phpmf2_version() {
}
return $version;
}
function allow_iframe_video($value = NULL) {
static $allow_iframe_video = false;
if (isset($value))
$allow_iframe_video = $value;
return $allow_iframe_video;
}

+ 18
- 0
tests/SanitizeTest.php View File

@ -115,6 +115,24 @@ class SanitizeTest extends PHPUnit_Framework_TestCase {
$this->assertEquals('This content has some <i>HTML escaped</i> entities such as &amp; ampersand, " quote, escaped &lt;code&gt; HTML tags, an ümlaut, an @at sign.', $data['data']['content']['html']);
}
public function testAllowIframeVideo() {
$url = 'http://sanitize.example/entry-with-iframe-video';
$response = $this->parse(['url' => $url]);
$body = $response->getContent();
$data = json_decode($body, true);
$html = $data['data']['content']['html'];
$this->assertNotContains('<iframe>', $html);
$response = $this->parse(['url' => $url, 'allow-iframe-video' => 'true']);
$body = $response->getContent();
$data = json_decode($body, true);
$html = $data['data']['content']['html'];
file_put_contents('html', $html);
$this->assertContains('youtube.com', $html);
$this->assertNotContains('https://attack-domain.com', $html);
$this->assertNotContains('<iframe width="580" height="345"', $html);
}
public function testSanitizeJavascriptURLs() {
$url = 'http://sanitize.example/h-entry-with-javascript-urls';
$response = $this->parse(['url' => $url]);

+ 19
- 0
tests/data/sanitize.example/entry-with-iframe-video View File

@ -0,0 +1,19 @@
HTTP/1.1 200 OK
Server: Apache
Date: Wed, 09 Dec 2015 03:29:14 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
<html>
<head>
<title>Test</title>
</head>
<body class="h-entry">
<div class="e-content">
<p>This is a nice video!</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/y9FSPcmybT8" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>This is a not a nice video!</p>
<iframe width="580" height="345" src="https://attack-domain.com" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</body>
</html>

Loading…
Cancel
Save