				$variable[$key] = self::filter($val);
			}
		} else {
			// Prevent XSS abuse
			$variable = preg_replace_callback('#</?([a-z]+)(\s.*)?/?>#i', function($matches) {
				$tag = strtolower($matches[1]);

				// Allowed tags
				if (in_array($tag, array(
					'b', 'strong', 'small', 'i', 'em', 'u', 's', 'sub', 'sup', 'a', 'button', 'img', 'br',
					'font', 'span', 'blockquote', 'q', 'abbr', 'address', 'code', 'hr',
					'audio', 'video', 'source', 'iframe',
					'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
					'ul', 'ol', 'li', 'dl', 'dt', 'dd',
					'div', 'p', 'var',
					'table', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td', 'colgroup', 'col',
					'section', 'article', 'aside'))) {
					return $matches[0];
				} else if (in_array($tag, array('script', 'link'))) {
					return '';
				} else {
					return htmlentities($matches[0]);
				}
			}, $variable);
		}

		return $variable;
	}

	/**
	 * Retrieves the HTTP Method used by the client.
	 *
	 * @return string Either GET|POST|PUT|DEL...
	 */
	public static function getMethod() {
		return $_SERVER['REQUEST_METHOD'];
	}

	/**
	 * Checks that the $url matches current route.
	 *
	 * @param string $url
	 * @param string $method (default = 'POST')
	 * @return bool
	 */
	public static function hasDataForURL($url, $method = 'POST') {
		$route = WRoute::parseURL($url);
		$current_route = WRoute::route();

		return self::getMethod() == strtoupper($method)
			&& $route['app'] == $current_route['app']
			&& (!isset($current_route['params'][0]) || !isset($route['params'][0]) || $current_route['params'][0] == $route['params'][0]);
	}
}

?>

The software does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.