diff --git a/app/Http/Controllers/HumanVerification.php b/app/Http/Controllers/HumanVerification.php index 5e745da76ee875d6013e451804fbee17e3371cf4..e3de31f753a9d312ecce18aa469c07801426aa56 100644 --- a/app/Http/Controllers/HumanVerification.php +++ b/app/Http/Controllers/HumanVerification.php @@ -2,66 +2,87 @@ namespace App\Http\Controllers; +use Captcha; +use Carbon; +use DB; +use Illuminate\Hashing\BcryptHasher as Hasher; use Illuminate\Http\Request; -use Validator; use Input; -use DB; -use Carbon; class HumanVerification extends Controller { - public static function captcha(Request $request, $id, $url){ - if($request->getMethod() == 'POST'){ - $rules = ['captcha' => 'required|captcha']; - $validator = Validator::make($request->all(), $rules); - if($validator->fails()){ - return view('captcha')->with('title', 'Bestätigung notwendig')->with('id', $id)->with('url', base64_decode($url))->with('errorMessage', 'Bitte Captcha eingeben:'); - }else{ - # If we can unlock the Account of this user we will redirect him to the result page - $id = $request->input('id'); - $url = $request->input('url'); + public static function captcha(Request $request, Hasher $hasher, $id, $url = null) + { + if ($url != null) { + $url = base64_decode(str_replace("<<SLASH>>", "/", $url)); + } else { + $url = $request->input('url'); + } - $user = DB::table('humanverification')->where('id', $id)->first(); - if($user !== null && $user->locked === 1){ + if ($request->getMethod() == 'POST') { + $user = DB::table('humanverification')->where('id', $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') + ->with('id', $id) + ->with('url', $url) + ->with('image', $captcha["img"]) + ->with('errorMessage', 'Bitte Captcha eingeben:'); + } 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]); return redirect($url); - }else{ + } else { return redirect('/'); } } } - return view('captcha')->with('title', 'Bestätigung notwendig')->with('id', $id)->with('url', base64_decode($url)); + $captcha = Captcha::create("default", true); + DB::table('humanverification')->where('id', $id)->update(['lockedKey' => $captcha["key"]]); + return view('captcha')->with('title', 'Bestätigung notwendig') + ->with('id', $id) + ->with('url', $url) + ->with('image', $captcha["img"]); } - public static function remove(Request $request){ - if(!$request->has('mm')){ + public static function remove(Request $request) + { + if (!$request->has('mm')) { abort(404, "Keine Katze gefunden."); } $id = md5($request->ip()); - if(HumanVerification::checkId($request, $request->input('mm'))){ + 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(); + DB::table('humanverification')->where('id', $id)->where('updated_at', '<', Carbon::NOW()->subSeconds(2))->delete(); } return response(hex2bin('89504e470d0a1a0a0000000d494844520000000100000001010300000025db56ca00000003504c5445000000a77a3dda0000000174524e530040e6d8660000000a4944415408d76360000000020001e221bc330000000049454e44ae426082'), 200) ->header('Content-Type', 'image/png'); } - public static function removeGet(Request $request, $mm, $password, $url){ - $url = base64_decode($url); + public static function removeGet(Request $request, $mm, $password, $url) + { + $url = base64_decode(str_replace("<<SLASH>>", "/", $url)); # 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){ + 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(); + DB::table('humanverification')->where('id', $mm)->where('updated_at', '<', Carbon::NOW()->subSeconds(2))->delete(); } return redirect($url); } - private static function checkId($request, $id){ - if(md5($request->ip()) === $id){ + private static function checkId($request, $id) + { + if (md5($request->ip()) === $id) { return true; - }else{ + } else { return false; } } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 3d09c78a379345664050c61c227711dd9e9aaa0a..94dcb17d3878ffff0de6803f1e167afe08314fc0 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -36,11 +36,6 @@ class Kernel extends HttpKernel ], 'session' => [ - \App\Http\Middleware\EncryptCookies::class, - \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, - \Illuminate\Session\Middleware\StartSession::class, - \Illuminate\View\Middleware\ShareErrorsFromSession::class, - \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ]; @@ -53,12 +48,12 @@ class Kernel extends HttpKernel * @var array */ protected $routeMiddleware = [ - 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, - 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, - 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, - 'can' => \Illuminate\Auth\Middleware\Authorize::class, - 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, - 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, + 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, + 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, + 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, + 'can' => \Illuminate\Auth\Middleware\Authorize::class, + 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, + 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'referer.check' => \App\Http\Middleware\RefererCheck::class, 'humanverification' => \App\Http\Middleware\HumanVerification::class, ]; diff --git a/app/Http/Middleware/HumanVerification.php b/app/Http/Middleware/HumanVerification.php index 7261043c218dcecd73e7f682a1b49ea02b10f79c..5a37786be0a1b206f4d624053260c30e5a6a3156 100644 --- a/app/Http/Middleware/HumanVerification.php +++ b/app/Http/Middleware/HumanVerification.php @@ -2,9 +2,11 @@ namespace App\Http\Middleware; +use Captcha; +use Carbon; use Closure; use DB; -use Carbon; +use Illuminate\Http\Response; class HumanVerification { @@ -17,50 +19,64 @@ class HumanVerification */ public function handle($request, Closure $next) { - $id = md5($request->ip()); + try { + $id = md5($request->ip()); - /** - * If the user sends a Password or a key - * We will not verificate the user. - * If someone that uses a bot finds this out we - * might have to change it at some point. - */ - if($request->filled('password') || $request->filled('key') || $request->filled('appversion') || !env('BOT_PROTECTION', false)){ - return $next($request); - } + /** + * If the user sends a Password or a key + * We will not verificate the user. + * 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)) { + return $next($request); + } - $user = DB::table('humanverification')->where('id', $id)->first(); - $createdAt = 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, 'updated_at' => now()] - ); - # Insert the URL the user tries to reach - DB::table('usedurls')->insert(['user_id' => $id, 'url' => url()->full()]); $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; + $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()] + ); + # 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('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()]); } - 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]); + $request->request->add(['verification_id' => $id, 'verification_count' => $unusedResultPages]); - # If the user is locked we will force a Captcha validation - if($user->locked === 1){ - return redirect('meta/verification/' . $id . '/' . urlencode(base64_encode(url()->full()))); + # 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"]]); + return + new Response( + view('captcha') + ->with('title', "Bestätigung erforderlich") + ->with('id', $id) + ->with('url', url()->full()) + ->with('image', $captcha["img"]) + ); + } + } catch (\Illuminate\Database\QueryException $e) { + // Failure in contacting metager3.de } return $next($request); diff --git a/resources/views/captcha.blade.php b/resources/views/captcha.blade.php index b6a26af7949b7171f848115460f3de8fd0a82d4c..250332fb52b521588324fca4068b1a206abd5898 100644 --- a/resources/views/captcha.blade.php +++ b/resources/views/captcha.blade.php @@ -4,21 +4,19 @@ @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. + <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"> - {{ csrf_field() }} + <form method="post" action="{{ route('verification', ['id' => $id]) }}"> <input type="hidden" name="url" value="{!! $url !!}"> <input type="hidden" name="id" value="{{ $id }}"> - <p>{!! captcha_img() !!}</p> + <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> - <p>Hinweis: Zum Zwecke der Autorisierung wird auf dieser Seite ein Session Cookie gesetzt. -@endsection \ No newline at end of file +@endsection diff --git a/routes/session.php b/routes/session.php index fc776d36b8f302ab40982233e822d371809f5fbe..cc96ecbba1b777c343ff68d6e07ac8c439c16f9e 100644 --- a/routes/session.php +++ b/routes/session.php @@ -1,7 +1,4 @@ <?php # In this File we collect all routes which require a session or other cookies to be active - -Route::get('captcha/api/{config?}', '\Mews\Captcha\CaptchaController@getCaptchaApi')->middleware('session'); -Route::get('captcha/{config?}', '\Mews\Captcha\CaptchaController@getCaptcha')->middleware('session'); -Route::match(['get', 'post'], 'meta/verification/{id}/{url}', 'HumanVerification@captcha'); \ No newline at end of file +Route::match(['get', 'post'], 'meta/verification/{id}/{url?}', 'HumanVerification@captcha')->name('verification');