/** * Check an input field isn't 'evil'. * * @param string The name of the parameter * @param string The value retrieved * @param ?boolean Whether the parameter is a POST parameter (NULL: undetermined) */ function check_input_field_string($name, &$val, $posted = false) { if (preg_match('#^\\s*((((j\\s*a\\s*v\\s*a\\s*)|(v\\s*b\\s*))?s\\s*c\\s*r\\s*i\\s*p\\s*t)|(d\\s*a\\s*t\\s*a\\s*))\\s*:#i', $val) != 0 && $name != 'value') { log_hack_attack_and_exit('SCRIPT_URL_HACK_2', $val); } // Security check for known URL fields. Check for specific things, plus we know we can be pickier in general $is_url = $name == 'from' || $name == 'preview_url' || $name == 'redirect' || $name == 'redirect_passon' || $name == 'url'; if ($is_url) { if ($is_url) { if (preg_match('#\\n|\\000|<|(".*[=<>])|^\\s*((((j\\s*a\\s*v\\s*a\\s*)|(v\\s*b\\s*))?s\\s*c\\s*r\\s*i\\s*p\\s*t)|(d\\s*a\\s*t\\s*a\\s*))\\s*:#mi', $val) != 0) { if ($name == 'page') { $_GET[$name] = ''; } // Stop loops log_hack_attack_and_exit('DODGY_GET_HACK', $name, $val); } // Don't allow external redirections if (!$posted) { $_val = str_replace('https://', 'http://', $val); if (looks_like_url($_val)) { $bus = array(get_base_url(false), get_forum_base_url(), 'http://ocportal.com/'); $ok = false; foreach ($bus as $bu) { if (substr($_val, 0, strlen($bu)) == $bu) { $ok = true; break; } } if (!$ok) { $val = get_base_url(false); } } } } } if ($GLOBALS['BOOTSTRAPPING'] == 0) { // Quickly depose of common spam attacks. Not really security, just a sensible barrier if ((!function_exists('is_guest') || is_guest()) && (strpos($val, '[url=http://') !== false || strpos($val, '[link') !== false) && strpos($val, '<a ') !== false) { log_hack_attack_and_exit('LAME_SPAM_HACK', $val); } // Additional checks for non-privileged users if (function_exists('has_specific_permission') && $name != 'page') { if (false) { hard_filter_input_data__html($val); hard_filter_input_data__filesystem($val); } } } }
/** * Filter HTML for safety. * * @param boolean Whether to explicitly execute this with admin rights. There are a few rare situations where this should be done, for data you know didn't come from a member, but is being evaluated by one. * @param MEMBER The member the evaluation is running as. This is a security issue, and you should only run as an administrator if you have considered where the comcode came from carefully * @param integer The offset of the tag in the Comcode * @param integer The length of the Comcode * @param LONG_TEXT The Comcode being parsed * @param boolean Whether the parser is/was in an HTML region * @param boolean Whether the parser is/was in a Semi-HTML region */ function filter_html($as_admin, $source_member, $pos, &$len, &$comcode, $in_html, $in_semihtml) { if (!$as_admin && !has_specific_permission($source_member, 'use_very_dangerous_comcode')) { global $POTENTIAL_JS_NAUGHTY_ARRAY; $comcode = preg_replace('#(\\\\)+(\\[/(html|semihtml)\\])#', '\\2', $comcode); // Stops sneaky trying to trick the end of the HTML tag to hack this function if ($in_html && $in_semihtml) { $ahead_end = max(strpos(strtolower($comcode), '[/html]', $pos), strpos(strtolower($comcode), '[/semihtml]', $pos)); } elseif ($in_html) { $ahead_end = strpos(strtolower($comcode), '[/html]', $pos); } elseif ($in_semihtml) { $ahead_end = strpos(strtolower($comcode), '[/semihtml]', $pos); } else { $ahead_end = false; } if ($ahead_end === false) { $ahead_end = strlen($comcode); } $ahead = substr($comcode, $pos, $ahead_end - $pos); require_code('input_filter'); hard_filter_input_data__html($ahead); // Tidy up $comcode = substr($comcode, 0, $pos) . $ahead . substr($comcode, $ahead_end); $len = strlen($comcode); } }