From b371c028ad31180b4c73f92b45c4ca8f5fff259e Mon Sep 17 00:00:00 2001 From: redmatrix Date: Mon, 2 May 2016 22:28:27 -0700 Subject: more security stuff --- Zotlabs/Module/Admin.php | 21 +++++++----- include/bbcode.php | 2 +- include/oembed.php | 84 +++++++++++++++++++-------------------------- view/tpl/admin_security.tpl | 16 ++------- 4 files changed, 52 insertions(+), 71 deletions(-) diff --git a/Zotlabs/Module/Admin.php b/Zotlabs/Module/Admin.php index 6dad11ab8..e1eaa6e0e 100644 --- a/Zotlabs/Module/Admin.php +++ b/Zotlabs/Module/Admin.php @@ -580,8 +580,8 @@ class Admin extends \Zotlabs\Web\Controller { $bc = $this->trim_array_elems(explode("\n",$_POST['blacklisted_channels'])); set_config('system','blacklisted_channels',$bc); - $embed_coop = ((x($_POST,'embed_coop')) ? True : False); - set_config('system','embed_coop',$embed_coop); + $embed_sslonly = ((x($_POST,'embed_sslonly')) ? True : False); + set_config('system','embed_sslonly',$embed_sslonly); $we = $this->trim_array_elems(explode("\n",$_POST['embed_allow'])); set_config('system','embed_allow',$we); @@ -589,6 +589,12 @@ class Admin extends \Zotlabs\Web\Controller { $be = $this->trim_array_elems(explode("\n",$_POST['embed_deny'])); set_config('system','embed_deny',$be); + $ts = ((x($_POST,'transport_security')) ? True : False); + set_config('system','transport_security_header',$ts); + + $cs = ((x($_POST,'content_security')) ? True : False); + set_config('system','content_security_policy',$cs); + goaway(z_root() . '/admin/security'); } @@ -713,7 +719,7 @@ class Admin extends \Zotlabs\Web\Controller { } $embedhelp2 = t("The recommended setting is to only allow unfiltered HTML from the following sites:"); - $embedhelp3 = t("youtube.com
youtu.be
twitter.com
vimeo.com
soundcloud.com
wikipedia.com
"); + $embedhelp3 = t("https://youtube.com/
https://www.youtube.com/
https://youtu.be/
https://vimeo.com/
https://soundcloud.com/
"); $embedhelp4 = t("All other embedded content will be filtered, unless embedded content from that site is explicitly blocked."); $t = get_markup_template('admin_security.tpl'); @@ -722,18 +728,17 @@ class Admin extends \Zotlabs\Web\Controller { '$page' => t('Security'), '$form_security_token' => get_form_security_token('admin_security'), '$block_public' => array('block_public', t("Block public"), get_config('system','block_public'), t("Check to block public access to all otherwise public personal pages on this site unless you are currently authenticated.")), + '$transport_security' => array('transport_security', t('Set "Transport Security" HTTP header'),intval(get_config('system','transport_security_header')),''), + '$content_security' => array('content_security', t('Set "Content Security Policy" HTTP header'),intval(get_config('system','content_security_policy')),''), '$whitelisted_sites' => array('whitelisted_sites', t('Allow communications only from these sites'), $whitesites_str, t('One site per line. Leave empty to allow communication from anywhere by default')), '$blacklisted_sites' => array('blacklisted_sites', t('Block communications from these sites'), $blacksites_str, ''), '$whitelisted_channels' => array('whitelisted_channels', t('Allow communications only from these channels'), $whitechannels_str, t('One channel (hash) per line. Leave empty to allow from any channel by default')), '$blacklisted_channels' => array('blacklisted_channels', t('Block communications from these channels'), $blackchannels_str, ''), - '$embed_allow' => array('embed_allow', t('Allow unfiltered embedded HTML content only from these domains'), $whiteembeds_str, t('One site per line. Leave empty to allow from any site by default')), + '$embed_sslonly' => array('embed_sslonly',t('Only allow embeds from secure (SSL) websites and links.'), intval(get_config('system','embed_sslonly')),''), + '$embed_allow' => array('embed_allow', t('Allow unfiltered embedded HTML content only from these domains'), $whiteembeds_str, t('One site per line. By default embedded content is filtered.')), '$embed_deny' => array('embed_deny', t('Block embedded HTML from these domains'), $blackembeds_str, ''), // '$embed_coop' => array('embed_coop', t('Cooperative embed security'), $embed_coop, t('Enable to share embed security with other compatible sites/hubs')), - '$embedhelp1' => $embedhelp1, - '$embedhelp2' => $embedhelp2, - '$embedhelp3' => $embedhelp3, - '$embedhelp4' => $embedhelp4, '$submit' => t('Submit') )); diff --git a/include/bbcode.php b/include/bbcode.php index 5bd5301cc..7a7ea8ce6 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -629,7 +629,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false) } if($tryoembed) { if (strpos($Text,'[/url]') !== false) { - $Text = preg_replace_callback("/\[url\]([$URLSearchString]*)\[\/url\]/ism", 'tryoembed', $Text); + $Text = preg_replace_callback("/[^\^]\[url\]([$URLSearchString]*)\[\/url\]/ism", 'tryoembed', $Text); } } if (strpos($Text,'[/url]') !== false) { diff --git a/include/oembed.php b/include/oembed.php index af5e51a6f..1e5c51172 100755 --- a/include/oembed.php +++ b/include/oembed.php @@ -1,14 +1,16 @@ ' . $embedurl . ''; + $result = oembed_action($embedurl); + if($result['action'] === 'block') { + return '' . $result['url'] . ''; } - $j = oembed_fetch_url($embedurl); + $j = oembed_fetch_url($result['url']); $s = oembed_format_object($j); return $s; } @@ -17,22 +19,11 @@ function oembed_replacecb($matches){ function oembed_action($embedurl) { $host = ''; + $action = 'filter'; - $action = 'allow'; - - // The default action is 'allow'. This is insecure. We might want to - // change this to 'filter' except it will be a support burden because - // then youtube videos won't work out of the box and will need to be - // explicitly enabled. - - $embedurl = str_replace('&','&', $embedurl); + $embedurl = trim(str_replace('&','&', $embedurl)); - logger('oembed_action: ' . $embedurl); - - $p = parse_url($embedurl); - - if($p) - $host = $p['host']; + logger('oembed_action: ' . $embedurl, LOGGER_DEBUG, LOG_INFO); // These media files should now be caught in bbcode.php // left here as a fallback in case this is called from another source @@ -40,6 +31,11 @@ function oembed_action($embedurl) { $noexts = array("mp3","mp4","ogg","ogv","oga","ogm","webm","opus"); $ext = pathinfo(strtolower($embedurl),PATHINFO_EXTENSION); + if(strpos($embedurl,'http://') === 0) { + if(intval(get_config('system','embed_sslonly'))) { + $action = 'block'; + } + } // site white/black list @@ -65,26 +61,10 @@ function oembed_action($embedurl) { if($x) { foreach($x as $ll) { $t = trim($ll); - $has_slash = ((strpos($t,'/') !== false) ? true : false); - - // don't allow somebody to provide a url like https://foobar.com/something/youtube - // to bypass an allow of youtube. Note they could still get through this - // with something like https://youtube.com.foobar.com/something so this is tagged with - // @FIXME, otherwise to fully secure a site will require every possible variation - // of every allowed service base URL. http vs. https, www. vs nothing, - // youtube.[com|org|whatever], youtu.be, and this is just for one service. - - if($t) { - if(strpos($t,$host) !== false) { - $found = true; - $action = 'allow'; - break; - } - elseif(($has_slash) && (strpos($embedurl,$t) !== false)) { - $found = true; - $action = 'allow'; - break; - } + if(($t) && (strpos($embedurl,$t) !== false) && ($action !== 'block')) { + $found = true; + $action = 'allow'; + break; } } } @@ -95,7 +75,7 @@ function oembed_action($embedurl) { // allow individual members to block something that wasn't blocked already. // They cannot over-ride the site to allow or change the filtering on an - // embed that is not allowed by the site. + // embed that is not allowed by the site admin. if(local_channel()) { if(($x = get_pconfig(local_channel(),'system','embed_deny'))) { @@ -113,9 +93,12 @@ function oembed_action($embedurl) { } } - logger('action: ' . $action . ' url: ' . $embedurl, LOGGER_DEBUG,LOG_DEBUG); + $arr = array('url' => $embedurl, 'action' => $action); + call_hooks('oembed_action',$arr); + + logger('action: ' . $arr['action'] . ' url: ' . $arr['url'], LOGGER_DEBUG,LOG_DEBUG); - return $action; + return $arr; } @@ -139,9 +122,10 @@ function oembed_fetch_url($embedurl){ $noexts = array("mp3","mp4","ogg","ogv","oga","ogm","webm","opus"); $ext = pathinfo(strtolower($embedurl),PATHINFO_EXTENSION); - $action = oembed_action($embedurl); + $result = oembed_action($embedurl); - $embedurl = str_replace('&','&', $embedurl); + $embedurl = $result['url']; + $action = $result['action']; $txt = null; @@ -222,12 +206,14 @@ function oembed_fetch_url($embedurl){ $j = json_decode($txt); - if($j->html && $action === 'filter') { - $orig = $j->html; - $allow_position = (($zrl) ? true : false); - $j->html = purify_html($j->html,$allow_position); - if($j->html != $orig) { - logger('oembed html was purified. original: ' . $orig . ' purified: ' . $j->html, LOGGER_DEBUG, LOG_INFO); + if($action === 'filter') { + if($j->html) { + $orig = $j->html; + $allow_position = (($zrl) ? true : false); + $j->html = purify_html($j->html,$allow_position); + if($j->html != $orig) { + logger('oembed html was purified. original: ' . $orig . ' purified: ' . $j->html, LOGGER_DEBUG, LOG_INFO); + } } } diff --git a/view/tpl/admin_security.tpl b/view/tpl/admin_security.tpl index 39f389e54..721b5f38f 100755 --- a/view/tpl/admin_security.tpl +++ b/view/tpl/admin_security.tpl @@ -7,7 +7,9 @@ {{include file="field_checkbox.tpl" field=$block_public}} - + {{include file="field_checkbox.tpl" field=$transport_security}} + {{include file="field_checkbox.tpl" field=$content_security}} + {{include file="field_checkbox.tpl" field=$embed_sslonly}} {{include file="field_textarea.tpl" field=$whitelisted_sites}} {{include file="field_textarea.tpl" field=$blacklisted_sites}} @@ -15,18 +17,6 @@ {{include file="field_textarea.tpl" field=$whitelisted_channels}} {{include file="field_textarea.tpl" field=$blacklisted_channels}} - {{if $embedhelp1}} -
{{$embedhelp1}}
- {{/if}} - -
-
{{$embedhelp2}}
-
-
{{$embedhelp3}}
-
-
{{$embedhelp4}}
-
- {{include file="field_textarea.tpl" field=$embed_allow}} {{include file="field_textarea.tpl" field=$embed_deny}} -- cgit v1.2.3