Created
August 10, 2017 18:57
-
-
Save bkosborne/09a97126b727c5862bd3e9df05b9eade to your computer and use it in GitHub Desktop.
OS Hooks to prevent insecure embeds
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Implements hook_field_attach_validate(). | |
*/ | |
function pu_misc_field_attach_validate($entity_type, $entity, &$errors) { | |
// If this entity has the body field attached to it, scan it to ensure that | |
// the user is not saving any embedded content over http://. This will prevent | |
// mixed content warnings when the site is viewed over https://. | |
if (isset($entity->body)) { | |
foreach ($entity->body as $langcode => $items) { | |
foreach ($items as $delta => $item) { | |
if (_pu_misc_html_has_insecure_content($item['value'])) { | |
$errors['body'][$langcode][$delta][] = array( | |
'error' => 'pu_misc_mixed_content', | |
'message' => t('Embedded content (iframe, image, etc) detected with an http:// source. Only https:// sources are allowed to be embedded.'), | |
); | |
} | |
} | |
} | |
} | |
} | |
/** | |
* Implements hook_form_FORM_ID_alter(). | |
*/ | |
function pu_misc_form_boxes_box_form_alter(&$form, &$form_state) { | |
// Add a custom validation funxtion to the os_boxes_html box. | |
// This is the widget that allows users to add blocks of content to their | |
// layouts. | |
if (isset($form['plugin_key']['#value']) && $form['plugin_key']['#value'] == 'os_boxes_html') { | |
$form['#validate'][] = '_pu_misc_boxes_box_form_validate'; | |
} | |
} | |
/** | |
* Custom form validation for the boxes widget that OS uses. | |
*/ | |
function _pu_misc_boxes_box_form_validate($form, &$form_state) { | |
// Validate that there are no non-secure embedded resources in the content. | |
if (isset($form_state['values']['text']['value'])) { | |
$text = $form_state['values']['text']['value']; | |
if (_pu_misc_html_has_insecure_content($text)) { | |
form_set_error('text', t('Embedded content (iframe, image, etc) detected with an http:// source. Only https:// sources are allowed to be embedded.')); | |
} | |
} | |
} | |
function _pu_misc_html_has_insecure_content($html) { | |
// Scan the body content for all embedded content sources and extract | |
// their URLs. | |
$dom = filter_dom_load($html); | |
$urls = []; | |
$img = $dom->getElementsByTagName('img'); | |
$iframe = $dom->getElementsByTagName('iframe'); | |
$embed = $dom->getElementsByTagName('embed'); | |
$object = $dom->getElementsByTagName('object'); | |
$param = $dom->getElementsByTagName('param'); | |
$script = $dom->getElementsByTagName('script'); | |
foreach ([$img, $iframe, $embed, $object, $param, $script] as $nodes) { | |
for ($i = 0; $i < $nodes->length; $i++) { | |
$n = $nodes->item($i); | |
if ($n->hasAttribute('src')) { | |
$urls[] = $n->getAttribute('src'); | |
} | |
elseif ($n->hasAttribute('href')) { | |
$urls[] = $n->getAttribute('href'); | |
} | |
elseif ($n->hasAttribute('data')) { | |
$urls[] = $n->getAttribute('data'); | |
} | |
elseif ($n->hasAttribute('name') && $n->hasAttribute('value') && $n->getAttribute('name') == 'movie') { | |
$urls[] = $n->getAttribute('value'); | |
} | |
} | |
} | |
foreach ($urls as $url) { | |
// Do not allow secure websites to embed insecure content | |
if (strpos($url, 'http://') !== FALSE) { | |
return TRUE; | |
} | |
} | |
return FALSE; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment