Skip to content

Instantly share code, notes, and snippets.

@bkosborne
Created August 10, 2017 18:57
Show Gist options
  • Save bkosborne/09a97126b727c5862bd3e9df05b9eade to your computer and use it in GitHub Desktop.
Save bkosborne/09a97126b727c5862bd3e9df05b9eade to your computer and use it in GitHub Desktop.
OS Hooks to prevent insecure embeds
<?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