From 9323a93a3ef718b6cea4994e116ba508ba191cf5 Mon Sep 17 00:00:00 2001 From: Dominik Pfennig <dominik@suma-ev.de> Date: Thu, 9 Feb 2017 09:27:04 +0100 Subject: [PATCH] Nur zur Sicherung. Die Software funktioniert noch nicht optimal --- app/Http/Controllers/ProxyController.php | 400 +++++++++++++++++++---- app/Http/Middleware/CheckPassword.php | 3 +- composer.json | 3 +- composer.lock | 171 ++++++---- resources/views/ProxyPage.blade.php | 12 +- routes/web.php | 11 +- 6 files changed, 472 insertions(+), 128 deletions(-) diff --git a/app/Http/Controllers/ProxyController.php b/app/Http/Controllers/ProxyController.php index 8bef292..cde1c2c 100644 --- a/app/Http/Controllers/ProxyController.php +++ b/app/Http/Controllers/ProxyController.php @@ -2,17 +2,49 @@ namespace App\Http\Controllers; +use Cache; use Illuminate\Http\Request; class ProxyController extends Controller { public function proxyPage(Request $request, $password, $url) { - $targetUrl = str_rot13(base64_decode($url)); - + $targetUrl = str_replace("<<SLASH>>", "/", $url); + $targetUrl = str_rot13(base64_decode($targetUrl)); // Password already got checked by the middleware: - $newPW = md5(env('PROXY_PASSWORD') . date('dmy')); + $newPW = md5(env('PROXY_PASSWORD') . date('dmy')); + + # Check For URL-Parameters that don't belong to the Proxy but to the URL that needs to be proxied + $params = $request->except(['enableJS', 'enableCookies']); + if (sizeof($params) > 0) { + # There are Params that need to be passed to the page + # Most of the times this happens due to forms that are submitted on a proxied page + # Let's redirect to the correct URI + $proxyParams = $request->except(array_keys($params)); + $redirProxyUrl = $targetUrl; + if (strpos($redirProxyUrl, "?") === false) { + $redirProxyUrl .= "?"; + } + + foreach ($params as $key => $value) { + $redirProxyUrl .= $key . "=" . urlencode($value) . "&"; + } + + $redirProxyUrl = rtrim($redirProxyUrl, "&"); + + $pw = md5(env('PROXY_PASSWORD') . $redirProxyUrl); + + $redirProxyUrl = base64_encode(str_rot13($redirProxyUrl)); + $redirProxyUrl = urlencode(str_replace("/", "<<SLASH>>", $redirProxyUrl)); + + $proxyParams['url'] = $redirProxyUrl; + $proxyParams['password'] = $pw; + + $newLink = action('ProxyController@proxyPage', $proxyParams); + return redirect($newLink); + } + $toggles = "111000A"; # Script Toggle Url: @@ -46,15 +78,6 @@ class ProxyController extends Controller $params['url'] = $url; $cookieUrl = action('ProxyController@proxyPage', $params); - # IFrame URL - $urlToProxy = $targetUrl; - $urlToProxy = str_replace("=", "=3d", $urlToProxy); - $urlToProxy = str_replace("?", "=3f", $urlToProxy); - $urlToProxy = str_replace("%", "=25", $urlToProxy); - $urlToProxy = str_replace("&", "=26", $urlToProxy); - $urlToProxy = str_replace(";", "=3b", $urlToProxy); - $urlToProxy = preg_replace('/^(http[s]{0,1}):\/\//', '$1/', $urlToProxy); - $settings = "u0"; if ($cookiesEnabled && !$scriptsEnabled) { $settings = "O0"; @@ -64,16 +87,10 @@ class ProxyController extends Controller $settings = "80"; } - $urlToProxy = "/en/$settings/" . $urlToProxy; - - $params = $request->all(); - $params['password'] = urlencode($newPW); - $params['url'] = $urlToProxy; - - $iframeUrl = action('ProxyController@proxy', $params); + $urlToProxy = $this->proxifyUrl($targetUrl, $newPW, false); return view('ProxyPage') - ->with('iframeUrl', $iframeUrl) + ->with('iframeUrl', $urlToProxy) ->with('scriptsEnabled', $scriptsEnabled) ->with('scriptUrl', $scriptUrl) ->with('cookiesEnabled', $cookiesEnabled) @@ -81,74 +98,341 @@ class ProxyController extends Controller ->with('targetUrl', $targetUrl); } - public function redir(Request $request, $password, $url) + public function proxy(Request $request, $password, $url) { - $params = $request->all(); + $targetUrl = str_replace("<<SLASH>>", "/", $url); + $targetUrl = str_rot13(base64_decode($targetUrl)); + // Hash Value under which a possible cached file would've been stored + $hash = md5($targetUrl); + $result = []; + $httpcode = 200; + if (!Cache::has($hash) || 1 == 1) { + // Inits the Curl connection for being able to preload multiple URLs while using a keep-alive connection + $this->initCurl(); + if ($request->has("enableCookies")) { + $result = $this->getUrlContent($targetUrl, true); + } else { + $result = $this->getUrlContent($targetUrl, false); + } + # Für alle weiteren Aktonen auf der URL benötigen wir die URL-Parameter nicht mehr. Wir entfernen diese: + $targetUrl = preg_replace("/\?.*/si", "", $targetUrl); + + if (isset($result["http_code"]) && $result["http_code"] !== 0) { + $httpcode = $result["http_code"]; + } + + if (!$request->has('enableJS')) { + $result["data"] = $this->removeJavaScript($result["data"]); + } + + extract(parse_url($targetUrl)); + $base = $scheme . "://" . $host; + if (isset($path)) { + $base .= $path; + } + + $result["data"] = $this->parseRelativeToAbsolute($result["data"], $base); + if (isset($result["header"]["Content-Type"]) && stripos($result["header"]["Content-Type"], "text/html") !== false) { + $result["data"] = $this->convertTargetAttributes($result["data"]); + } + $result["data"] = $this->parseProxyLink($result["data"], $password, $request); + curl_close($this->ch); + + # We are gonna cache all files for 60 Minutes to reduce + # redundant file transfers: + + $val = base64_encode(serialize($result)); + + Cache::put($hash, $val, 60); + } else { + $result = Cache::get($hash); + // Base64 decode: + $result = base64_decode($result); + // Unserialize + $result = unserialize($result); + if (isset($result["http_code"]) && $result["http_code"] !== 0) { + $httpcode = $result["http_code"]; + } + } + + return response($result["data"], $httpcode) + ->withHeaders($result["header"]); - $params['password'] = urlencode($password); - $params['page'] = urlencode(base64_encode(str_rot13("/test/nph-proxy.cgi/" . $url))); - $newUrl = action('ProxyController@proxy', $params); - return redirect($newUrl); } + private function convertTargetAttributes($data) + { + $result = $data; - public function proxy(Request $request, $password, $url) + # The following html Elements can define a target attribute which will set the way in which Links are gonna be opened + # a, area, base, form (https://wiki.selfhtml.org/wiki/Referenz:HTML/Attribute/target) + # If the target is _blank we don't need to worry It'll be correct then + # We should make all other options Reference to _top because the link outside of the iframe needs to be changed then: + + # First change the ones that already have an target tag + $result = preg_replace("/(<\s*(?:a|area|base|form)[^>]+\starget\s*=\s*[\"\']{0,1}\s*)(?:(?!_blank|\s|\"|\').)+/si", "$1_top", $result); + # Now the ones that haven't got one + $result = preg_replace("/(<\s*(?:a|area|base|form)(?:(?!target=).)*?)([<>])/", "$1 target=_top $2", $result); + return $result; + } + private function removeJavaScript($html) { - $proxyUrl = "https://proxy.suma-ev.de/test/nph-proxy.cgi/" . ltrim($url, "/"); - $r = $this->getUrlContent($proxyUrl); - $httpcode = 200; - if (isset($r["http_code"]) && $r["http_code"] !== 0) { - $httpcode = $r["http_code"]; + // We could use DOMDocument from PHP but + // that would suggest that the given HTML is well formed which + // we cannot guarantee so we will use regex + $result = $html; + // We will simply remove every single script tag and it's contents + $result = preg_replace("/<[\s]*script.*?(:?\/\s*>|<\s*\/\s*script\s*>)/si", "", $result); + # Remove all Javascript that is placed in a href + $result = preg_replace('/(href=)(["\'])\s*javascript:[^\2]*?(\2)/si', "$1$2$3", $result); + # Remove all HTMl Event Handler + $result = preg_replace_callback("/<[^>]*?\bon[^=]+?=([\"\']).*?\\1[^>]*?>/si", "self::removeJsAttributes", $result); + # Remove all autofocus attributes: + $result = preg_replace("/(<[^>]*?)autofocus[=\"\']+([^>]*>)/si", "$1$2", $result); + + // The rest of a potentional JavaScript code will be blocked by our IFrame. It would be a waste of resources to remove them + + return $result; + } + + private function removeJsAttributes($match) + { + # This funktion gets a HTML Tag in $match[0] with javascript HTML Attributes in it (onclick=, etc...) + # This funktion schouls remove these from the string and return the replacement + $string = $match[0]; + + $string = preg_replace("/\bon[^=]+?=\s*([\"\']).*?\\1/si", "", $string); + return $string; + } + + private function parseRelativeToAbsolute($data, $base) + { + $result = $data; + $count = 1; + + # Convert every Link that starts with [ . | / ] but not with [ // ] + while (preg_match("/(href=|src=|url\(|action=|srcset=|@import |background=)(\s*[\"\']{0,1}\s*)((:?\.|\/[^\/])[^\"\'\s]+)([\"\'\s])/si", $result, $matches) === 1) { + $absoluteLink = $this->rel2abs($matches[3], $base); + $result = str_replace($matches[0], $matches[1] . $matches[2] . $absoluteLink . $matches[5], $result, $count); } + # Convert every Link that starts with a path and not with a slash + preg_match_all("/(href=|src=|url\(|action=|srcset=|@import |background=)\s*([\"\']{0,1})\s*([\w]+?[^\"\'\s>]+)/si", $result, $matches); + foreach ($matches[0] as $index => $value) { + $absoluteLink = $this->rel2abs($matches[3][$index], $base); + $result = str_replace($value, $matches[1][$index] . $matches[2][$index] . $absoluteLink, $result); + } + + $scheme = parse_url($base)["scheme"] . "://"; - $r["data"] = $this->parseProxyLink($r["data"], $password, $request); - return response($r["data"], $httpcode) - ->withHeaders($r["header"]); + while (preg_match("/(href=|src=|url\(|action=|srcset=|@import |background=)([\"\']{0,1})\/{2}/si", $result, $matches) === 1) { + $result = str_replace($matches[0], $matches[1] . $matches[2] . $scheme, $result, $count); + } - return var_dump($r); + # Form tags that do not define a action will automatically target the same site we are on. + # To make it link to the correct page in the end we need to add an specific action: + $result = preg_replace("/(<\s*form(?:(?!action=).)+?)(>)/si", "$1 action=\"$base\"$2", $result); + return $result; } private function parseProxyLink($data, $password, $request) { $result = $data; + $count = 1; + # Zunächst ersetzen wir alle externen Links + preg_match_all("/<\s*(?:a|area|form)[^>]+?target=[\"\']{0,1}\s*(?:_top|_blank)\s*[^>]*?>/si", $result, $matches); + foreach ($matches[0] as $tag) { + $tmp = preg_replace_callback("/((?:href|action)=[\"\']{0,1})([^\"\'\s>]+)/si", "self::pregProxifyUrlTop", $tag); + $result = str_replace($tag, $tmp, $result, $count); + } + # Jetzt alle internen Links mit einem anderen target: + preg_match_all("/<\s*(?:a|area|form)[^>]+?target=[\"\']{0,1}\s*(?:(?!_top|_blank|>).)+?>/si", $result, $matches); + foreach ($matches[0] as $tag) { + $tmp = preg_replace_callback("/((?:href|action)=[\"\']{0,1})([^\"\'\s>]+)/si", "self::pregProxifyUrl", $tag); + $result = str_replace($tag, $tmp, $result, $count); + } + $result = preg_replace_callback("/((?:href=|src=|action=|url\(|srcset=|@import |background=)\s*[\"\']{0,1}\s*)([^\"\'\s\)>]+)/si", "self::pregProxifyUrl", $result); - $proxyLink = env('PROXY_URL'); - $host = $request->root(); - $result = str_replace($proxyLink, $host, $data); - $result = str_replace("/test/nph-proxy.cgi", "/proxy/$password", $result); return $result; } - private function getUrlContent($url) + private function pregProxifyUrl($matches) { - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)'); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); - curl_setopt($ch, CURLOPT_TIMEOUT, 5); - curl_setopt($ch, CURLOPT_HEADER, 1); - $data = curl_exec($ch); - - $httpcode = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE)); - - $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); - $header = substr($data, 0, $header_size); - $data = substr($data, $header_size); + $current = \Request::root(); + $iframeUrl = $matches[2]; - curl_close($ch); + if (strpos(strtolower($iframeUrl), "http") === 0 && strpos(strtolower($iframeUrl), $current) !== 0) { + $iframeUrl = $this->proxifyUrl($matches[2], null, false); + } + + return $matches[1] . $iframeUrl; + } + private function pregProxifyUrlTop($matches) + { + $current = \Request::root(); + $iframeUrl = $matches[2]; + if (strpos($iframeUrl, "http") === 0 && strpos($iframeUrl, $current) !== 0) { + $iframeUrl = $this->proxifyUrl($matches[2], null, true); + } + return $matches[1] . $iframeUrl; + } + + private function initCurl() + { + $this->ch = curl_init(); + curl_setopt($this->ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)'); + curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($this->ch, CURLOPT_CONNECTTIMEOUT, 5); + curl_setopt($this->ch, CURLOPT_TIMEOUT, 5); + curl_setopt($this->ch, CURLOPT_HEADER, 1); + } + + private function getUrlContent($url, $withCookies) + { + curl_setopt($this->ch, CURLOPT_URL, "$url"); + + $data = curl_exec($this->ch); + die(htmlspecialchars_decode($url)); + $httpcode = intval(curl_getinfo($this->ch, CURLINFO_HTTP_CODE)); + + $header_size = curl_getinfo($this->ch, CURLINFO_HEADER_SIZE); + $header = substr($data, 0, $header_size); + + $data = substr($data, $header_size); $headerArray = []; foreach (explode(PHP_EOL, $header) as $index => $value) { if ($index > 0) { $ar = explode(': ', $value); if (sizeof($ar) === 2) { - $headerArray[trim($ar[0])] = trim($ar[1]); + if ($withCookies && (strtolower($ar[0]) === "content-type" || strtolower($ar[0]) === "set-cookie")) { + $headerArray[trim($ar[0])] = trim($ar[1]); + } elseif (!$withCookies && strtolower($ar[0]) === "content-type") { + $headerArray[trim($ar[0])] = trim($ar[1]); + } elseif (strtolower($ar[0]) === "location") { + $headerArray[trim($ar[0])] = $this->proxifyUrl(trim($ar[1]), null, false); + } else { + #$headerArray[trim($ar[0])] = trim($ar[1]); + } + } + } + } + $headerArray["Content-Security-Policy"] = "default-src 'self' data: 'unsafe-inline' http://localhost"; + # Charset-Fix for people who forget to declare charset: + # If this won't work the default charset UTF-8 is set by laravel: + foreach ($headerArray as $key => $value) { + if (strtolower($key) === "content-type" && strpos(strtolower($value), "charset") === false) { + # We will see if there is a content-type with charset declared in the document: + if (preg_match("/<\s*meta[^>]+http-equiv=[\'\"]\s*content-type\s*[\'\"][^>]+?>/si", $data, $match)) { + if (strpos($match[0], "charset") !== false && preg_match("/content=[\'\"]([^\'\"]+)/si", $match[0], $contentType)) { + $headerArray[$key] = $contentType[1]; + break; + } else { + break; + } } else { - //die(var_dump($value) . var_dump($ar)); + break; } + } + } + return ['header' => $headerArray, 'data' => $data, 'http_code' => $httpcode]; } + + public function proxifyUrl($url, $password = null, $topLevel) + { + if (!$password) { + $password = urlencode(\Request::route('password')); + } + + $urlToProxy = base64_encode(str_rot13($url)); + $urlToProxy = str_replace("/", "<<SLASH>>", $urlToProxy); + $urlToProxy = urlencode($urlToProxy); + + if ($topLevel) { + $params = \Request::all(); + + # Password + $pw = md5(env('PROXY_PASSWORD') . $url); + $urlToProxy = base64_encode(str_rot13($url)); + $urlToProxy = urlencode(str_replace("/", "<<SLASH>>", $urlToProxy)); + + # Params + $params['password'] = $pw; + $params['url'] = $urlToProxy; + + $iframeUrl = action('ProxyController@proxyPage', $params); + } else { + $params = \Request::all(); + $params['password'] = $password; + $params['url'] = $urlToProxy; + + $iframeUrl = action('ProxyController@proxy', $params); + + } + + return $iframeUrl; + } + + private function rel2abs($rel, $base) + { + /* return if already absolute URL */ + if (parse_url($rel, PHP_URL_SCHEME) != '') { + return ($rel); + } + + /* queries and anchors */ + if ($rel[0] == '#' || $rel[0] == '?') { + return ($base . $rel); + } + + /* parse base URL and convert to local variables: + $scheme, $host, $path */ + extract(parse_url($base)); + + /* remove non-directory element from path */ + if (isset($path)) { + $path = preg_replace('#/[^/]*$#', '', $path); + } + + /* destroy path if relative url points to root */ + if ($rel[0] == '/') { + $path = ''; + } + + /* dirty absolute URL */ + $abs = ''; + + /* do we have a user in our URL? */ + if (isset($user)) { + $abs .= $user; + + /* password too? */ + if (isset($pass)) { + $abs .= ':' . $pass; + } + + $abs .= '@'; + } + + $abs .= $host; + /* did somebody sneak in a port? */ + if (isset($port)) { + $abs .= ':' . $port; + } + + if (isset($path)) { + $abs .= $path; + } + if (isset($rel)) { + $abs .= "/" . ltrim($rel, "/"); + } + /* replace '//' or '/./' or '/foo/../' with '/' */ + $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#'); + for ($n = 1; $n > 0; $abs = preg_replace($re, '/', $abs, -1, $n)) {} + + /* absolute URL is ready! */ + return ($scheme . '://' . $abs); + } } diff --git a/app/Http/Middleware/CheckPassword.php b/app/Http/Middleware/CheckPassword.php index d36d324..05ae246 100644 --- a/app/Http/Middleware/CheckPassword.php +++ b/app/Http/Middleware/CheckPassword.php @@ -23,7 +23,8 @@ class CheckPassword return $next($request); } } else { - $targetUrl = str_rot13(base64_decode($request->route('url'))); + $targetUrl = str_replace("<<SLASH>>", "/", $request->route('url')); + $targetUrl = str_rot13(base64_decode($targetUrl)); // Check Password: $checkPw = md5(env('PROXY_PASSWORD') . $targetUrl); $password = $request->route('password'); diff --git a/composer.json b/composer.json index e5f2117..3b67754 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,8 @@ "require": { "php": ">=5.6.4", "laravel/framework": "5.4.*", - "laravel/tinker": "~1.0" + "laravel/tinker": "~1.0", + "predis/predis": "^1.1" }, "require-dev": { "fzaninotto/faker": "~1.4", diff --git a/composer.lock b/composer.lock index a61f333..087f3f3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "8fbf13abc5809fa6ed63d1f60614100a", + "hash": "b55a30b47f5db670fdb0e038ba861000", + "content-hash": "0725c6f10f21493eb9918978c8e4de4f", "packages": [ { "name": "dnoegel/php-xdg-base-dir", @@ -37,7 +38,7 @@ "MIT" ], "description": "implementation of xdg base directory specification for php", - "time": "2014-10-24T07:27:01+00:00" + "time": "2014-10-24 07:27:01" }, { "name": "doctrine/inflector", @@ -104,7 +105,7 @@ "singularize", "string" ], - "time": "2015-11-06T14:35:42+00:00" + "time": "2015-11-06 14:35:42" }, { "name": "erusev/parsedown", @@ -146,7 +147,7 @@ "markdown", "parser" ], - "time": "2016-11-02T15:56:58+00:00" + "time": "2016-11-02 15:56:58" }, { "name": "jakub-onderka/php-console-color", @@ -189,7 +190,7 @@ "homepage": "http://www.acci.cz" } ], - "time": "2014-04-08T15:00:19+00:00" + "time": "2014-04-08 15:00:19" }, { "name": "jakub-onderka/php-console-highlighter", @@ -233,7 +234,7 @@ "homepage": "http://www.acci.cz/" } ], - "time": "2015-04-20T18:58:01+00:00" + "time": "2015-04-20 18:58:01" }, { "name": "laravel/framework", @@ -362,7 +363,7 @@ "framework", "laravel" ], - "time": "2017-01-27T19:27:15+00:00" + "time": "2017-01-27 19:27:15" }, { "name": "laravel/tinker", @@ -420,7 +421,7 @@ "laravel", "psysh" ], - "time": "2016-12-30T18:13:17+00:00" + "time": "2016-12-30 18:13:17" }, { "name": "league/flysystem", @@ -503,7 +504,7 @@ "sftp", "storage" ], - "time": "2017-01-30T17:41:17+00:00" + "time": "2017-01-30 17:41:17" }, { "name": "monolog/monolog", @@ -581,7 +582,7 @@ "logging", "psr-3" ], - "time": "2016-11-26T00:15:39+00:00" + "time": "2016-11-26 00:15:39" }, { "name": "mtdowling/cron-expression", @@ -625,7 +626,7 @@ "cron", "schedule" ], - "time": "2017-01-23T04:29:33+00:00" + "time": "2017-01-23 04:29:33" }, { "name": "nesbot/carbon", @@ -678,7 +679,7 @@ "datetime", "time" ], - "time": "2017-01-16T07:55:07+00:00" + "time": "2017-01-16 07:55:07" }, { "name": "nikic/php-parser", @@ -729,7 +730,7 @@ "parser", "php" ], - "time": "2016-12-06T11:30:35+00:00" + "time": "2016-12-06 11:30:35" }, { "name": "paragonie/random_compat", @@ -777,7 +778,57 @@ "pseudorandom", "random" ], - "time": "2016-11-07T23:38:38+00:00" + "time": "2016-11-07 23:38:38" + }, + { + "name": "predis/predis", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/nrk/predis.git", + "reference": "f0210e38881631afeafb56ab43405a92cafd9fd1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nrk/predis/zipball/f0210e38881631afeafb56ab43405a92cafd9fd1", + "reference": "f0210e38881631afeafb56ab43405a92cafd9fd1", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "suggest": { + "ext-curl": "Allows access to Webdis when paired with phpiredis", + "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol" + }, + "type": "library", + "autoload": { + "psr-4": { + "Predis\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniele Alessandri", + "email": "suppakilla@gmail.com", + "homepage": "http://clorophilla.net" + } + ], + "description": "Flexible and feature-complete Redis client for PHP and HHVM", + "homepage": "http://github.com/nrk/predis", + "keywords": [ + "nosql", + "predis", + "redis" + ], + "time": "2016-06-16 16:22:20" }, { "name": "psr/log", @@ -824,7 +875,7 @@ "psr", "psr-3" ], - "time": "2016-10-10T12:19:37+00:00" + "time": "2016-10-10 12:19:37" }, { "name": "psy/psysh", @@ -897,7 +948,7 @@ "interactive", "shell" ], - "time": "2017-01-15T17:54:13+00:00" + "time": "2017-01-15 17:54:13" }, { "name": "ramsey/uuid", @@ -979,7 +1030,7 @@ "identifier", "uuid" ], - "time": "2016-11-22T19:21:44+00:00" + "time": "2016-11-22 19:21:44" }, { "name": "swiftmailer/swiftmailer", @@ -1033,7 +1084,7 @@ "mail", "mailer" ], - "time": "2016-12-29T10:02:40+00:00" + "time": "2016-12-29 10:02:40" }, { "name": "symfony/console", @@ -1096,7 +1147,7 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2017-01-08T20:47:33+00:00" + "time": "2017-01-08 20:47:33" }, { "name": "symfony/css-selector", @@ -1149,7 +1200,7 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2017-01-02T20:32:22+00:00" + "time": "2017-01-02 20:32:22" }, { "name": "symfony/debug", @@ -1206,7 +1257,7 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2017-01-02T20:32:22+00:00" + "time": "2017-01-02 20:32:22" }, { "name": "symfony/event-dispatcher", @@ -1266,7 +1317,7 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2017-01-02T20:32:22+00:00" + "time": "2017-01-02 20:32:22" }, { "name": "symfony/finder", @@ -1315,7 +1366,7 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2017-01-02T20:32:22+00:00" + "time": "2017-01-02 20:32:22" }, { "name": "symfony/http-foundation", @@ -1368,7 +1419,7 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2017-01-08T20:47:33+00:00" + "time": "2017-01-08 20:47:33" }, { "name": "symfony/http-kernel", @@ -1450,7 +1501,7 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2017-01-12T21:36:33+00:00" + "time": "2017-01-12 21:36:33" }, { "name": "symfony/polyfill-mbstring", @@ -1509,7 +1560,7 @@ "portable", "shim" ], - "time": "2016-11-14T01:06:16+00:00" + "time": "2016-11-14 01:06:16" }, { "name": "symfony/process", @@ -1558,7 +1609,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2017-01-02T20:32:22+00:00" + "time": "2017-01-02 20:32:22" }, { "name": "symfony/routing", @@ -1633,7 +1684,7 @@ "uri", "url" ], - "time": "2017-01-02T20:32:22+00:00" + "time": "2017-01-02 20:32:22" }, { "name": "symfony/translation", @@ -1697,7 +1748,7 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2017-01-02T20:32:22+00:00" + "time": "2017-01-02 20:32:22" }, { "name": "symfony/var-dumper", @@ -1760,7 +1811,7 @@ "debug", "dump" ], - "time": "2017-01-03T08:53:57+00:00" + "time": "2017-01-03 08:53:57" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -1807,7 +1858,7 @@ ], "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", - "time": "2016-09-20T12:50:39+00:00" + "time": "2016-09-20 12:50:39" }, { "name": "vlucas/phpdotenv", @@ -1857,7 +1908,7 @@ "env", "environment" ], - "time": "2016-09-01T10:05:43+00:00" + "time": "2016-09-01 10:05:43" } ], "packages-dev": [ @@ -1913,7 +1964,7 @@ "constructor", "instantiate" ], - "time": "2015-06-14T21:17:01+00:00" + "time": "2015-06-14 21:17:01" }, { "name": "fzaninotto/faker", @@ -1961,7 +2012,7 @@ "faker", "fixtures" ], - "time": "2016-04-29T12:21:54+00:00" + "time": "2016-04-29 12:21:54" }, { "name": "hamcrest/hamcrest-php", @@ -2006,7 +2057,7 @@ "keywords": [ "test" ], - "time": "2015-05-11T14:41:42+00:00" + "time": "2015-05-11 14:41:42" }, { "name": "mockery/mockery", @@ -2071,7 +2122,7 @@ "test double", "testing" ], - "time": "2016-12-19T14:50:55+00:00" + "time": "2016-12-19 14:50:55" }, { "name": "myclabs/deep-copy", @@ -2113,7 +2164,7 @@ "object", "object graph" ], - "time": "2017-01-26T22:05:40+00:00" + "time": "2017-01-26 22:05:40" }, { "name": "phpdocumentor/reflection-common", @@ -2167,7 +2218,7 @@ "reflection", "static analysis" ], - "time": "2015-12-27T11:43:31+00:00" + "time": "2015-12-27 11:43:31" }, { "name": "phpdocumentor/reflection-docblock", @@ -2212,7 +2263,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2016-09-30T07:12:33+00:00" + "time": "2016-09-30 07:12:33" }, { "name": "phpdocumentor/type-resolver", @@ -2259,7 +2310,7 @@ "email": "me@mikevanriel.com" } ], - "time": "2016-11-25T06:54:22+00:00" + "time": "2016-11-25 06:54:22" }, { "name": "phpspec/prophecy", @@ -2322,7 +2373,7 @@ "spy", "stub" ], - "time": "2016-11-21T14:58:47+00:00" + "time": "2016-11-21 14:58:47" }, { "name": "phpunit/php-code-coverage", @@ -2385,7 +2436,7 @@ "testing", "xunit" ], - "time": "2017-01-20T15:06:43+00:00" + "time": "2017-01-20 15:06:43" }, { "name": "phpunit/php-file-iterator", @@ -2432,7 +2483,7 @@ "filesystem", "iterator" ], - "time": "2016-10-03T07:40:28+00:00" + "time": "2016-10-03 07:40:28" }, { "name": "phpunit/php-text-template", @@ -2473,7 +2524,7 @@ "keywords": [ "template" ], - "time": "2015-06-21T13:50:34+00:00" + "time": "2015-06-21 13:50:34" }, { "name": "phpunit/php-timer", @@ -2517,7 +2568,7 @@ "keywords": [ "timer" ], - "time": "2016-05-12T18:03:57+00:00" + "time": "2016-05-12 18:03:57" }, { "name": "phpunit/php-token-stream", @@ -2566,7 +2617,7 @@ "keywords": [ "tokenizer" ], - "time": "2016-11-15T14:06:22+00:00" + "time": "2016-11-15 14:06:22" }, { "name": "phpunit/phpunit", @@ -2648,7 +2699,7 @@ "testing", "xunit" ], - "time": "2017-01-28T06:14:33+00:00" + "time": "2017-01-28 06:14:33" }, { "name": "phpunit/phpunit-mock-objects", @@ -2707,7 +2758,7 @@ "mock", "xunit" ], - "time": "2016-12-08T20:27:08+00:00" + "time": "2016-12-08 20:27:08" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -2752,7 +2803,7 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2016-02-13T06:45:14+00:00" + "time": "2016-02-13 06:45:14" }, { "name": "sebastian/comparator", @@ -2816,7 +2867,7 @@ "compare", "equality" ], - "time": "2017-01-29T09:50:25+00:00" + "time": "2017-01-29 09:50:25" }, { "name": "sebastian/diff", @@ -2868,7 +2919,7 @@ "keywords": [ "diff" ], - "time": "2015-12-08T07:14:41+00:00" + "time": "2015-12-08 07:14:41" }, { "name": "sebastian/environment", @@ -2918,7 +2969,7 @@ "environment", "hhvm" ], - "time": "2016-11-26T07:53:53+00:00" + "time": "2016-11-26 07:53:53" }, { "name": "sebastian/exporter", @@ -2985,7 +3036,7 @@ "export", "exporter" ], - "time": "2016-11-19T08:54:04+00:00" + "time": "2016-11-19 08:54:04" }, { "name": "sebastian/global-state", @@ -3036,7 +3087,7 @@ "keywords": [ "global state" ], - "time": "2015-10-12T03:26:01+00:00" + "time": "2015-10-12 03:26:01" }, { "name": "sebastian/object-enumerator", @@ -3082,7 +3133,7 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2016-11-19T07:35:10+00:00" + "time": "2016-11-19 07:35:10" }, { "name": "sebastian/recursion-context", @@ -3135,7 +3186,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2016-11-19T07:33:16+00:00" + "time": "2016-11-19 07:33:16" }, { "name": "sebastian/resource-operations", @@ -3177,7 +3228,7 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" + "time": "2015-07-28 20:34:47" }, { "name": "sebastian/version", @@ -3220,7 +3271,7 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" + "time": "2016-10-03 07:35:21" }, { "name": "symfony/yaml", @@ -3275,7 +3326,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2017-01-03T13:51:32+00:00" + "time": "2017-01-03 13:51:32" }, { "name": "webmozart/assert", @@ -3325,7 +3376,7 @@ "check", "validate" ], - "time": "2016-11-23T20:04:58+00:00" + "time": "2016-11-23 20:04:58" } ], "aliases": [], diff --git a/resources/views/ProxyPage.blade.php b/resources/views/ProxyPage.blade.php index 3df57d3..849cdfa 100644 --- a/resources/views/ProxyPage.blade.php +++ b/resources/views/ProxyPage.blade.php @@ -36,7 +36,17 @@ </nav> <div class ="container-fluid"> </div> - <iframe id="site-proxy-iframe" src="{!!$iframeUrl!!}" > + <iframe + id="site-proxy-iframe" + src="{!!$iframeUrl!!}" + sandbox=" + allow-forms + allow-popups + allow-top-navigation + allow-same-origin + allow-scripts + " + > </iframe> <script src="/js/jquery.min.js"></script> diff --git a/routes/web.php b/routes/web.php index 4eb97e2..f2f1040 100644 --- a/routes/web.php +++ b/routes/web.php @@ -12,9 +12,10 @@ */ Route::get('/', function () { - $url = "https://facebook.de"; + $url = "https://metager.de"; $password = md5(env('PROXY_PASSWORD') . $url); - $target = urlencode(base64_encode(str_rot13($url))); + $url = base64_encode(str_rot13($url)); + $target = urlencode(str_replace("/", "<<SLASH>>", $url)); return "<a href=\"" . action('ProxyController@proxyPage', ['password' => $password, 'url' => $target]) . "\">$url</a>"; return md5(env('PROXY_PASSWORD') . "https://metager.de") . "<br>\n" . urlencode(base64_encode(str_rot13('https://metager.de'))); #return redirect('https://metager.de'); @@ -22,8 +23,4 @@ Route::get('/', function () { Route::get('{password}/{url}', 'ProxyController@proxyPage')->middleware('checkpw'); -Route::group(['prefix' => 'proxy/{password}', 'middleware' => ['checkpw:true']], function ($password) { - - Route::get('{url}', 'ProxyController@proxy')->where(['url' => '.*']); - -}); +Route::get('proxy/{password}/{url}', 'ProxyController@proxy')->middleware('checkpw:true'); -- GitLab