diff --git a/app/Http/Controllers/HumanVerification.php b/app/Http/Controllers/HumanVerification.php
index e3de31f753a9d312ecce18aa469c07801426aa56..def5420560a44971a1a5d12db0a0ab9f58ff465a 100644
--- a/app/Http/Controllers/HumanVerification.php
+++ b/app/Http/Controllers/HumanVerification.php
@@ -20,23 +20,25 @@ class HumanVerification extends Controller
         }
 
         if ($request->getMethod() == 'POST') {
-            $user = DB::table('humanverification')->where('id', $id)->first();
+            $user = DB::table('humanverification')->where('uid', $id)->first();
 
             $lockedKey = $user->lockedKey;
             $key = $request->input('captcha');
             $key = strtolower($key);
+
             if (!$hasher->check($key, $lockedKey)) {
                 $captcha = Captcha::create("default", true);
-                DB::table('humanverification')->where('id', $id)->update(['lockedKey' => $captcha["key"]]);
-                return view('captcha')->with('title', 'Bestätigung notwendig')
+                DB::table('humanverification')->where('uid', $id)->update(['lockedKey' => $captcha["key"]]);
+                return view('humanverification.captcha')->with('title', 'Bestätigung notwendig')
                     ->with('id', $id)
                     ->with('url', $url)
                     ->with('image', $captcha["img"])
-                    ->with('errorMessage', 'Bitte Captcha eingeben:');
+                    ->with('errorMessage', 'Fehler: Falsches Captcha eingegeben!');
             } else {
                 # If we can unlock the Account of this user we will redirect him to the result page
                 if ($user !== null && $user->locked === 1) {
-                    DB::table('humanverification')->where('id', $id)->update(['locked' => false]);
+                    # The Captcha was correct. We can remove the key from the user
+                    DB::table('humanverification')->where('uid', $id)->update(['locked' => false, 'lockedKey' => "", 'whitelist' => 1]);
                     return redirect($url);
                 } else {
                     return redirect('/');
@@ -44,8 +46,8 @@ class HumanVerification extends Controller
             }
         }
         $captcha = Captcha::create("default", true);
-        DB::table('humanverification')->where('id', $id)->update(['lockedKey' => $captcha["key"]]);
-        return view('captcha')->with('title', 'Bestätigung notwendig')
+        DB::table('humanverification')->where('uid', $id)->update(['lockedKey' => $captcha["key"]]);
+        return view('humanverification.captcha')->with('title', 'Bestätigung notwendig')
             ->with('id', $id)
             ->with('url', $url)
             ->with('image', $captcha["img"]);
@@ -56,10 +58,9 @@ class HumanVerification extends Controller
         if (!$request->has('mm')) {
             abort(404, "Keine Katze gefunden.");
         }
-        $id = md5($request->ip());
+
         if (HumanVerification::checkId($request, $request->input('mm'))) {
-            # Remove the entry from the database
-            DB::table('humanverification')->where('id', $id)->where('updated_at', '<', Carbon::NOW()->subSeconds(2))->delete();
+            HumanVerification::removeUser($request, $request->input('mm'));
         }
         return response(hex2bin('89504e470d0a1a0a0000000d494844520000000100000001010300000025db56ca00000003504c5445000000a77a3dda0000000174524e530040e6d8660000000a4944415408d76360000000020001e221bc330000000049454e44ae426082'), 200)
             ->header('Content-Type', 'image/png');
@@ -72,15 +73,47 @@ class HumanVerification extends Controller
         # If the user is correct and the password is we will delete any entry in the database
         $requiredPass = md5($mm . Carbon::NOW()->day . $url . env("PROXY_PASSWORD"));
         if (HumanVerification::checkId($request, $mm) && $requiredPass === $password) {
-            # Remove the entry from the database
-            DB::table('humanverification')->where('id', $mm)->where('updated_at', '<', Carbon::NOW()->subSeconds(2))->delete();
+            HumanVerification::removeUser($request, $mm);
         }
         return redirect($url);
     }
 
+    private static function removeUser($request, $uid)
+    {
+        $id = hash("sha512", $request->ip());
+
+        $sum = DB::table('humanverification')->where('id', $id)->where('whitelist', false)->sum('unusedResultPages');
+        $user = DB::table('humanverification')->where('uid', $uid)->first();
+
+        if ($user === null) {
+            return;
+        }
+
+        # Check if we have to whitelist the user or if we can simply delete the data
+        if ($user->unusedResultPages < $sum && $user->whitelist === 0) {
+            # Whitelist
+            DB::table('humanverification')->where('uid', $uid)->update(['whitelist' => true, 'whitelistCounter' => 0]);
+            $user->whitelist = 1;
+            $user->whitelistCounter = 0;
+        }
+
+        if ($user->whitelist === 1) {
+            if (
+                DB::table('humanverification')->where('uid', $uid)->update(['unusedResultPages' => 0])
+                === 1
+            ) {
+                DB::table('usedurls')->where('uid', $uid)->delete();
+            }
+        } else {
+            DB::table('humanverification')->where('uid', $uid)->where('updated_at', '<', Carbon::NOW()->subSeconds(2))->delete();
+
+        }
+
+    }
+
     private static function checkId($request, $id)
     {
-        if (md5($request->ip()) === $id) {
+        if (hash("sha512", $request->ip() . $_SERVER["AGENT"]) === $id) {
             return true;
         } else {
             return false;
diff --git a/app/Http/Middleware/HumanVerification.php b/app/Http/Middleware/HumanVerification.php
index 5a37786be0a1b206f4d624053260c30e5a6a3156..0be2058000507fb79acf245d34a706eeb057117e 100644
--- a/app/Http/Middleware/HumanVerification.php
+++ b/app/Http/Middleware/HumanVerification.php
@@ -7,6 +7,7 @@ use Carbon;
 use Closure;
 use DB;
 use Illuminate\Http\Response;
+use URL;
 
 class HumanVerification
 {
@@ -20,7 +21,9 @@ class HumanVerification
     public function handle($request, Closure $next)
     {
         try {
-            $id = md5($request->ip());
+            $id = hash("sha512", $request->ip());
+            $uid = hash("sha512", $request->ip() . $_SERVER["AGENT"]);
+            unset($_SERVER["AGENT"]);
 
             /**
              * If the user sends a Password or a key
@@ -28,57 +31,102 @@ class HumanVerification
              * If someone that uses a bot finds this out we
              * might have to change it at some point.
              */
-            if ($request->has('password') || $request->filled('key') || $request->filled('appversion') || !env('BOT_PROTECTION', false)) {
+            if ($request->filled('password') || $request->filled('key') || $request->filled('appversion') || !env('BOT_PROTECTION', false)) {
                 return $next($request);
             }
 
-            $user = DB::table('humanverification')->where('id', $id)->first();
+            // The specific user
+            $user = DB::table('humanverification')->where('uid', $uid)->first();
+
             $createdAt = Carbon::now();
             $unusedResultPages = 1;
             $locked = false;
             # If this user doesn't have an entry we will create one
+
             if ($user === null) {
                 DB::table('humanverification')->insert(
-                    ['id' => $id, 'unusedResultPages' => 1, 'locked' => false, "lockedKey" => "", 'updated_at' => Carbon::now()]
+                    [
+                        'uid' => $uid,
+                        'id' => $id,
+                        'unusedResultPages' => 0,
+                        'whitelist' => false,
+                        'whitelistCounter' => 0,
+                        'locked' => false,
+                        "lockedKey" => "",
+                        'updated_at' => Carbon::now(),
+                    ]
                 );
                 # Insert the URL the user tries to reach
                 $url = url()->full();
-                DB::table('usedurls')->insert(['user_id' => $id, 'url' => $url]);
-                $user = DB::table('humanverification')->where('id', $id)->first();
-            } else if ($user->locked !== 1) {
-                $unusedResultPages = intval($user->unusedResultPages);
-                $unusedResultPages++;
-                # We have different security gates:
-                #   50, 75, 85, >=90 => Captcha validated Result Pages
-                # If the user shows activity on our result page the counter will be deleted
-                # Maybe I'll add a ban if the user reaches 100
-                if ($unusedResultPages === 50 || $unusedResultPages === 75 || $unusedResultPages === 85 || $unusedResultPages >= 90) {
-                    $locked = true;
+                DB::table('usedurls')->insert(['uid' => $uid, 'id' => $id, 'eingabe' => $request->input('eingabe', '')]);
+                $user = DB::table('humanverification')->where('uid', $uid)->first();
+            }
+
+            # Lock out everyone in a Bot network
+            # Find out how many requests this IP has made
+            $sum = DB::table('humanverification')->where('id', $id)->where('whitelist', false)->sum('unusedResultPages');
+
+            # A lot of automated requests are from websites that redirect users to our result page.
+            # We will detect those requests and put a captcha
+            $referer = URL::previous();
+            # Just the URL-Parameter
+            $refererLock = false;
+            if (stripos($referer, "?") !== false) {
+                $referer = substr($referer, stripos($referer, "?") + 1);
+                $referer = urldecode($referer);
+                if (preg_match("/http[s]{0,1}:\/\/metager\.de\/meta\/meta.ger3\?.*?eingabe=([\w\d]+\.){1,2}[\w\d]+/si", $referer) === 1) {
+                    $refererLock = true;
                 }
-                DB::table('humanverification')->where('id', $id)->update(['unusedResultPages' => $unusedResultPages, 'locked' => $locked, 'updated_at' => $createdAt]);
-                # Insert the URL the user tries to reach
-                DB::table('usedurls')->insert(['user_id' => $id, 'url' => url()->full()]);
+
             }
 
-            $request->request->add(['verification_id' => $id, 'verification_count' => $unusedResultPages]);
+            // Defines if this is the only user using that IP Adress
+            $alone = DB::table('humanverification')->where('id', $id)->count() === 1;
+            if ((!$alone && $sum >= 50 && $user->whitelist !== 1) || $refererLock) {
+                DB::table('humanverification')->where('uid', $uid)->update(['locked' => true]);
+                $user->locked = 1;
+            }
 
             # If the user is locked we will force a Captcha validation
             if ($user->locked === 1) {
                 $captcha = Captcha::create("default", true);
-                DB::table('humanverification')->where('id', $id)->update(['lockedKey' => $captcha["key"]]);
+                DB::table('humanverification')->where('uid', $uid)->update(['lockedKey' => $captcha["key"]]);
                 return
                 new Response(
-                    view('captcha')
+                    view('humanverification.captcha')
                         ->with('title', "Bestätigung erforderlich")
-                        ->with('id', $id)
+                        ->with('id', $uid)
                         ->with('url', url()->full())
                         ->with('image', $captcha["img"])
                 );
             }
+
+            $unusedResultPages = intval($user->unusedResultPages);
+            $unusedResultPages++;
+            $locked = false;
+
+            if ($alone || $user->whitelist === 1) {
+                # This IP doesn't need verification yet
+                # The user currently isn't locked
+
+                # We have different security gates:
+                #   50, 75, 85, >=90 => Captcha validated Result Pages
+                # If the user shows activity on our result page the counter will be deleted
+                # Maybe I'll add a ban if the user reaches 100
+
+                if ($unusedResultPages === 50 || $unusedResultPages === 75 || $unusedResultPages === 85 || $unusedResultPages >= 90) {
+                    $locked = true;
+                }
+
+            }
+            DB::table('humanverification')->where('uid', $uid)->update(['unusedResultPages' => $unusedResultPages, 'locked' => $locked]);
+            # Insert the URL the user tries to reach
+            DB::table('usedurls')->insert(['uid' => $uid, 'id' => $id, 'eingabe' => $request->input('eingabe', '')]);
+
         } catch (\Illuminate\Database\QueryException $e) {
             // Failure in contacting metager3.de
         }
-
+        $request->request->add(['verification_id' => $uid, 'verification_count' => $unusedResultPages]);
         return $next($request);
     }
 }
diff --git a/app/MetaGer.php b/app/MetaGer.php
index 0a03f4e4ffc395ee9b063177ccd81d5b7f99722f..57d89a841fd1ba1608578ce416f69c13ec96ba1e 100644
--- a/app/MetaGer.php
+++ b/app/MetaGer.php
@@ -934,7 +934,7 @@ class MetaGer
 
     public function parseFormData(Request $request)
     {
-        $this->request = $request;
+        
         # Sichert, dass der request in UTF-8 formatiert ist
         if ($request->input('encoding', 'utf8') !== "utf8") {
             # In früheren Versionen, als es den Encoding Parameter noch nicht gab, wurden die Daten in ISO-8859-1 übertragen
@@ -1051,6 +1051,8 @@ class MetaGer
         $this->verificationId = $request->input('verification_id', null);
         $this->verificationCount = intval($request->input('verification_count', '0'));
         $this->apiKey = $request->input('key', '');
+        // Remove Inputs that are not used
+        $this->request = $request->replace($request->except(['verification_id', 'uid', 'verification_count']));
 
         $this->validated = false;
         if (isset($this->password)) {
@@ -1492,6 +1494,14 @@ class MetaGer
 
 # Einfache Getter
 
+    public function getVerificationId() {
+        return $this->verificationId;
+    }
+
+    public function getVerificationCount() {
+        return $this->verificationCount;
+    }
+
     public function getSite()
     {
         return $this->site;
diff --git a/database/migrations/2018_04_26_114745_create_humanverification_table.php b/database/migrations/2018_04_26_114745_create_humanverification_table.php
index 95c94233c98e95c00a0a6381c478362e80bd9ff4..081612b3be8e193afa413d869ba037879e06311b 100644
--- a/database/migrations/2018_04_26_114745_create_humanverification_table.php
+++ b/database/migrations/2018_04_26_114745_create_humanverification_table.php
@@ -1,8 +1,8 @@
 <?php
 
-use Illuminate\Support\Facades\Schema;
-use Illuminate\Database\Schema\Blueprint;
 use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
 
 class CreateHumanverificationTable extends Migration
 {
@@ -14,9 +14,13 @@ class CreateHumanverificationTable extends Migration
     public function up()
     {
         Schema::create('humanverification', function (Blueprint $table) {
-            $table->string('id')->unique();
+            $table->string('uid')->unique();
+            $table->string('id');
             $table->integer('unusedResultPages');
+            $table->boolean('whitelist');
+            $table->integer('whitelistCounter');
             $table->boolean('locked');
+            $table->string('lockedKey');
             $table->timestamp('updated_at');
         });
     }
diff --git a/database/migrations/2018_05_03_101301_usedurls.php b/database/migrations/2018_05_03_101301_usedurls.php
index 341d0b664072a7095838b0adb61e769a084b8c91..a7cc0f956d785f8aec45f91641c7fd8ac26c0ccf 100644
--- a/database/migrations/2018_05_03_101301_usedurls.php
+++ b/database/migrations/2018_05_03_101301_usedurls.php
@@ -1,8 +1,8 @@
 <?php
 
-use Illuminate\Support\Facades\Schema;
-use Illuminate\Database\Schema\Blueprint;
 use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
 
 class Usedurls extends Migration
 {
@@ -14,11 +14,12 @@ class Usedurls extends Migration
     public function up()
     {
         Schema::create('usedurls', function (Blueprint $table) {
-            $table->increments('id')->unique();
-            $table->string('user_id');
-            $table->text('url');
+            $table->increments('number')->unique();
+            $table->string('uid');
+            $table->string('id');
+            $table->text('eingabe');
             $table->timestamp('created_at');
-            $table->foreign('user_id')->references('id')->on('humanverification')->onDelete('cascade');
+            $table->foreign('uid')->references('uid')->on('humanverification')->onDelete('cascade');
         });
     }
 
diff --git a/public/index.php b/public/index.php
index b67e0a6e9b0ce993d445cd7ffb898622f8f8d4c3..4334ce537cd2b6c2d2428f9ca992cb4ac220db04 100644
--- a/public/index.php
+++ b/public/index.php
@@ -13,6 +13,8 @@ if (isset($_SERVER["HTTP_FORWARDED"]) && isset($_SERVER["HTTP_X_FORWARDED_FOR"])
     unset($_SERVER["HTTP_FORWARDED"]);
 }
 
+$_SERVER["AGENT"] = $_SERVER["HTTP_USER_AGENT"];
+
 if (isset($_SERVER['HTTP_USER_AGENT'])) {
     $agentPieces = explode(" ", $_SERVER['HTTP_USER_AGENT']);
 
diff --git a/resources/views/captcha.blade.php b/resources/views/captcha.blade.php
deleted file mode 100644
index 250332fb52b521588324fca4068b1a206abd5898..0000000000000000000000000000000000000000
--- a/resources/views/captcha.blade.php
+++ /dev/null
@@ -1,22 +0,0 @@
-@extends('layouts.subPages')
-
-@section('title', $title )
-
-@section('content')
-    <h1>Entschuldigen Sie die Störung</h1>
-    <p>Wir haben Grund zur Annahme, dass von Ihrem Anschluss verstärkt automatisierte Abfragen abgeschickt wurden.
-    Deshalb bitten wir Sie, die nachfolgende Captcha Abfrage zu beantworten.</p>
-    <p>Sollten Sie diese Nachricht häufiger sehen oder handelt es sich dabei um einen Irrtum, schicken Sie uns gerne eine Nachricht über unser <a href="/kontakt">Kontaktformular</a>.</p>
-    <p>Nennen Sie uns in diesem Fall bitte unbedingt folgende Vorgangsnummer: {{ $id }}
-    <p>Wir schauen uns den Vorgang dann gerne im Detail an.</p>
-    <form method="post" action="{{ route('verification', ['id' => $id]) }}">
-        <input type="hidden" name="url" value="{!! $url !!}">
-        <input type="hidden" name="id" value="{{ $id }}">
-        <p><img src="{{ $image }}" /></p>
-        @if(isset($errorMessage))
-        <p><font color="red">{{$errorMessage}}</font></p>
-        @endif
-        <p><input type="text" name="captcha"></p>
-        <p><button type="submit" name="check">OK</button></p>
-    </form>
-@endsection
diff --git a/resources/views/humanverification/captcha.blade.php b/resources/views/humanverification/captcha.blade.php
new file mode 100644
index 0000000000000000000000000000000000000000..9f58d36e3122ab75bda226e399157b23fc58f110
--- /dev/null
+++ b/resources/views/humanverification/captcha.blade.php
@@ -0,0 +1,23 @@
+@extends('layouts.subPages')
+
+@section('title', $title )
+
+@section('content')
+    <h1>Entschuldigen Sie die Störung</h1>
+    <p>Sie befinden sich in einem Netzwerk aus dem wir verstärkt automatisierte Anfragen erhalten. Keine Sorge: Das bedeutet nicht unbedingt, dass diese Anfragen von Ihrem PC kommen.</p>
+    <p>Allerdings können wir Ihre Anfragen nicht von denen des "Robots" unterscheiden. Zum Schutz der von uns abgefragten Suchmaschinen müssen wir aber sicherstellen, dass diese nicht mit (automatisierten) Abfragen überflutet werden.</p>
+
+    <p>Bitte geben Sie deshalb die Zeichen aus dem Bild in die Eingabebox ein und bestätigen Sie mit "OK" um zur Ergebnisseite zu gelangen.</p>
+    <form method="post" action="{{ route('verification', ['id' => $id]) }}">
+        <input type="hidden" name="url" value="{!! $url !!}">
+        <input type="hidden" name="id" value="{{ $id }}">
+        <p><img src="{{ $image }}" /></p>
+        @if(isset($errorMessage))
+        <p><font color="red">{{$errorMessage}}</font></p>
+        @endif
+        <p><input type="text" class="form-control" name="captcha" placeholder="Captcha eingeben"  autofocus></p>
+        <p><button type="submit" class="btn btn-success" name="check">OK</button></p>
+    </form>
+    <p>Sollten Sie diese Nachricht häufiger sehen oder handelt es sich dabei um einen Irrtum, schicken Sie uns gerne eine Nachricht über unser <a href="/kontakt">Kontaktformular</a>.</p>
+    <p>Nennen Sie uns in diesem Fall bitte unbedingt folgende Vorgangsnummer: {{ $id }}
+@endsection
diff --git a/resources/views/layouts/resultPage.blade.php b/resources/views/layouts/resultPage.blade.php
index 6d3b6ab12eff9b843047fc6639fdca0af799e9b8..a8c3853481d645c18412363f11b57d2efb0ea8d1 100644
--- a/resources/views/layouts/resultPage.blade.php
+++ b/resources/views/layouts/resultPage.blade.php
@@ -9,8 +9,8 @@
 		<meta name="p" content="{{ getmypid() }}" />
 		<meta name="q" content="{{ $eingabe }}" />
 		<meta name="l" content="{{ LaravelLocalization::getCurrentLocale() }}" />
-		<meta name="mm" content="{{ Request::input('verification_id') }}" />
-		<meta name="mn" content="{{ Request::input('verification_count') }}" />
+		<meta name="mm" content="{{ $metager->getVerificationId() }}" />
+		<meta name="mn" content="{{ $metager->getVerificationCount() }}" />
 		<link rel="search" type="application/opensearchdescription+xml" title="{!! trans('resultPage.opensearch') !!}" href="{{  LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), action('StartpageController@loadPlugin', ['params' => base64_encode(serialize(Request::all()))])) }}">
 		<link type="text/css" rel="stylesheet" href="{{ mix('css/themes/default.css') }}" />
 		<link type="text/css" rel="stylesheet" href="/font-awesome/css/font-awesome.min.css" />
diff --git a/routes/web.php b/routes/web.php
index 7e3b997720a33862391f5bb4ea04abfd65cb3a80..f1ebb289a2c7cfd5ed37465d92e57eb96ac12300 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -164,6 +164,7 @@ Route::group(
         Route::match(['get', 'post'], 'meta/meta.ger3', 'MetaGerSearch@search')->middleware('humanverification');
         Route::post('img/cat.jpg', 'HumanVerification@remove');
         Route::get('r/metager/{mm}/{pw}/{url}', ['as' => 'humanverification', 'uses' => 'HumanVerification@removeGet']);
+        Route::post('img/dog.jpg', 'HumanVerification@whitelist');
 
         Route::get('meta/picture', 'Pictureproxy@get');
         Route::get('clickstats', 'LogController@clicklog');