Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 5 TokenMismatchException only in iFrame

Tags:

iframe

laravel

I have a working form:

    {!! Form::open() !!}
            <div class="form-group">
                <label for="name">Name</label>
                <input type="text" class="form-control" id="name" placeholder="Name">
            </div>
            <div class="form-group">
                <label for="division">Division</label>
                <input type="text" class="form-control" id="division" placeholder="Division">
            </div>
        {!! Form::submit('send', array('class'=>'btn btn-success pull-right')) !!}
    {!! Form::close() !!}

This works as a standalone page submitting and storing the inputs. Now I need to put this in an iframe so it can be called from another website. When I do this with:

<iframe src="http://1.1.1.1/register_user" style="width:600px;height:500px;"></iframe>

The form displays but when the user submits they get the following:

TokenMismatchException in VerifyCsrfToken.php line 53:
1. in VerifyCsrfToken.php line 53
2. at VerifyCsrfToken->handle(object(Request), object(Closure))
3. at call_user_func_array(array(object(VerifyCsrfToken), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
4. at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in ShareErrorsFromSession.php line 54
5. at ShareErrorsFromSession->handle(object(Request), object(Closure))
6. at call_user_func_array(array(object(ShareErrorsFromSession), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
7. at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in StartSession.php line 62
8. at StartSession->handle(object(Request), object(Closure))
9. at call_user_func_array(array(object(StartSession), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
10. at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in AddQueuedCookiesToResponse.php line 37
11. at AddQueuedCookiesToResponse->handle(object(Request), object(Closure))
12. at call_user_func_array(array(object(AddQueuedCookiesToResponse), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
13. at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in EncryptCookies.php line 59
14. at EncryptCookies->handle(object(Request), object(Closure))
15. at call_user_func_array(array(object(EncryptCookies), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
16. at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in CheckForMaintenanceMode.php line 42
17. at CheckForMaintenanceMode->handle(object(Request), object(Closure))
18. at call_user_func_array(array(object(CheckForMaintenanceMode), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
19. at Pipeline->Illuminate\Pipeline\{closure}(object(Request))
20. at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
21. at Pipeline->then(object(Closure)) in Kernel.php line 122
22. at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 87
23. at Kernel->handle(object(Request)) in index.php line 54

This is what I see in the logs:

[2015-08-10 00:52:21] production.ERROR: exception
'Illuminate\Session\TokenMismatchException' in /home/forge/default/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php:53
Stack trace:
#0 [internal function]: Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle(Object(Illuminate\Http\Request), Object(Closure))
#1 /home/forge/default/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(124): call_user_func_array(Array, Array)
#2 /home/forge/default/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(54): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#3 [internal function]: Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#4 /home/forge/default/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(124): call_user_func_array(Array, Array)
#5 /home/forge/default/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(62): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#6 [internal function]: Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#7 /home/forge/default/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(124): call_user_func_array(Array, Array)
#8 /home/forge/default/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#9 [internal function]: Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure))
#10 /home/forge/default/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(124): call_user_func_array(Array, Array)
#11 /home/forge/default/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(59): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#12 [internal function]: Illuminate\Cookie\Middleware\EncryptCookies->handle(Object(Illuminate\Http\Request), Object(Closure))
#13 /home/forge/default/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(124): call_user_func_array(Array, Array)
#14 /home/forge/default/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(42): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#15 [internal function]: Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure))
#16 /home/forge/default/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(124): call_user_func_array(Array, Array)
#17 [internal function]: Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#18 /home/forge/default/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): call_user_func(Object(Closure), Object(Illuminate\Http\Request))
#19 /home/forge/default/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(122): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#20 /home/forge/default/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(87): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#21 /home/forge/default/public/index.php(54): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#22 {main}  

What am I doing wrong to cause the mismatch in the iframe and how do I fix it?

like image 917
neil Avatar asked Aug 10 '15 01:08

neil


Video Answer


1 Answers

Laravel 5 has a global middleware enabled called VeryifyCsrfToken that checks all POST requests for a token to apply Cross-site request forgery protection.

Cross-site request forgeries are a type of malicious exploit whereby unauthorized commands are performed on behalf of the authenticated user.

Allowing users to submit your form from an iframe on a different domain is exactly the kind of thing Laravels CSRF protection is trying to prevent.

There is a way to disable CSRF verification for certain URL's. You can add a new item to the $except array to exclude that url from CSRF verification.

Http/Middleware/VerifyCsrfToken.php

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

class VerifyCsrfToken extends BaseVerifier
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        'your/uri'
    ];
}
like image 125
Jeemusu Avatar answered Oct 30 '22 11:10

Jeemusu