Best way to output html via blade in Laravel, with XSS protection - laravel

I need to output some html from database, which was filled by users via CKEeditor. So it may have some <script>alert('something');</script> or some other stuff. If i escape html output via blade {{ $news->body }} - i will get html as plain text which is not what i need. But if i use {!! $news->body !!} i will get normal html with working alert. Is there any clean way to deal with it?

For Laravel 5 and later there is Purifier which integrates the aforementioned HTMLPurifier nicely into Laravel.
Install it using composer require mews/purifier and then use
{!! clean($news->body) !!}
to output HTML that has been properly escaped with the default HTMLPurifier settings.

Related

Laravel (5.2) Blade - How to prevent a Blade Directive in an email address from being parsed?

Update This is a bug in Laravel 5.2 & 5.3
I've got a weird one here. A user's email address on our client's system has a domain with the following substring in it '#parent'. I am not including the whole thing just for the sake of privacy.
Because #parent is a Blade directive, Laravel seems to either process or ignore the #parent and strips it out of the rendered email address on the page.
For example, let's say the email address is john#parentstuff.com. Laravel will render the following on the page: johnstuff.com. See how it removes #parent from the email?
What I've tried to fix it:
1. {!! $user->email !!}
2. {{ e($user->email) }}
I know that this is an issue with Blade as AJAX & jQuery rendered content with this same email address is displayed just fine elsewhere on the site.
UPDATE
Upon further investigation, it appears this may be a bug in how Blade processes the #parent directive. I set up 3 new Laravel projects for the following versions: 5.2, 5.3 and 5.4. The project in question is a Laravel 5.2 project, FYI.
I created the following setup for each of the above mentioned versions to test the bug.
Route
Route::get('/test', function () {
$foo = 'john#parentingstuff.org';
return view('test')->with('foo', $foo);
});
Templates
Base
<html>
<head>
<title>App Name - #yield('title')</title>
</head>
<body>
<div class="container">
#yield('content')
</div>
</body>
</html>
Test View
#extends('test-base')
#section('content')
{{$foo}}
#endsection
Outputs
L5.2: johningstuff.org
L5.3: johningstuff.org
L5.4: john#parentingstuff.org
Theories
One very interesting case I noticed while running these tests was that having the {{$foo}} variable inside of a #section directive vs moving it outside of the #section directive led to two different outputs.
Example
{{$foo}}
#section('content')
{{$foo}}
#endsection
The output of this was...
john#parentingstuff.org
johningstuff.org
Conclusion
So, does anyone know how to patch this bug in Laravel 5.2 or Laravel 5.3? Currently, upgrading to L5.4 is not an option for our client.
Anyone have any clever tricks they can think of that might help?
I believe the problem is elsewhere. You are doing probably something more than you wrote.
Sample controller method content
return view('test', ['email' => 'john#parentstuff.com'];
Sample view:
Email is: {{ $email }}
Result is:
Email is: john#parentstuff.com
so I believe you are doing something more than you wrote.
Something very screwy is going on in your setup, because that shouldn't be possible. Laravel processes Blade instructions before interpreting any variables.
I tested with a very simple example:
Route::get('test', function() {
$foo = 'john#parentstuff.com';
return view('test')->with('foo', $foo);
});
and a Blade template of:
{{ $foo }}
and it works just fine. #parent is not interpreted.
This is a bug in Laravel verions prior to 5.4. See the following:
https://github.com/laravel/framework/issues/10068
https://github.com/laravel/framework/pull/16033
This is a bug in Laravel 5.1 too.
A quick solution could be to change the # sign to
#
to fix it.

Obfuscate css and html in blade template

Is there a way to make life harder on users which trying to copy my html source in laravel blade templates?
Is it possible to obfuscate blade template without javascript? I know about this for example {{ HTML::obfuscate('me#gmail.com') }} it is working with emails..

vue.js component using laravel blade for the template

My idea is to use laravel blade in the <template></template> of a vue/vueify component. I am not sure how to get the blade processor to run and output the html into the template inside the .vue file or in an imported template file.
I don't believe what he's trying to do is preposterous.
I find that there're things that Laravel blade does better than Vue and just want to get a prepared blade run template to be returned asynchronously using vue resource.
What you can do is actually make vue blade templates. That are actually then passed by Laravel via a route that returns a view that has vue code. That way it enables the user of blade templates to do what he does best in PHP and blade them return a good vue template that had code.
If you have the template inline then you can output whatever you want inside of it ( from your something.blade.php file ):
<super-duper-component inline-template >
{!! $some_php_variable_sent_to_the_view !!}
#{{ $data.someVueDataProperty | json }}
</super-duper-component>
You can use the blade #include('path-to.super-duper-component') to include this snippet from a simple super-duper-component.blade.php file so you can keep the component's template in one location for maintaining the template in the future.

how can i customiz the laravel 5.1 Login and register view pages?

im using the laravel 5.1 and building web app
i just bought HTML theme and directly copy all the css and Js files to public/assets ( not using any task runner such as gulp or grunt). i try to customize the login and register view page and if i use the default routing its fail to load the js and CSS ( just load plain HTML ) but if i point it directly by
Route::get('login','AuthController#getLogin')
its working . how can i fix the JS and CSS problem ?
*all the other pages works right and load the CSS and JS *
here are the screen shots from other pages and login page :
here is from my login page that fail to load :
if i use route to directly link to the page not passing through the Auth controller and after submit send data to login function ( like simple normal forms) its working but if goes through the controller system its fail . also if i use :
Route:resource('contact','contactcontroller')
my contact pages such as index, create , etc all are fail to load CSS but if i directly link to them like:
Route:get('contact','contactController#index')
it will successfully load the CSS and my page will be shows fine .
this question may help you with that !
Laravel stylesheets and javascript don't load for non-base routes
BTW : look at your page with firefox(chrome) Inspect Element Or Firebug to see the http requests!
Try using this way script and style link
{!! HTML::script('js/bootstrap.min.js') !!}
{!! HTML::style('css/bootstrap.min.css') !!}
<link href="{{URL::asset('../assets/css/bootstrap.css')}}" rel="stylesheet">
<script src="{{URL::asset('../assets/js/jquery.js')}}"></script>
I use these methods works 10/10.

Including CSS in Laravel 5 or 4.3

TL;DR: What is the correct way to link to a stylesheet in Laravel 5?
Background:
I'm using the dev version of Laravel 4.3 (5) because I want to use Socialite, and it makes sense to develop with that from the start. I am having a problem getting templates transferred from 4.2
I've moved my blade layout files to the new directory structure (resources/templates) and placed my CSS in the public/css/ folder.
When I load my route /test/ all I get is "Whoops, looks like something went wrong."
For testing purposes I've removed all blade layout syntax from my layouts - the raw HTML works, but there is no styling (as there is no linked stylesheet). That tells me the routes, views and controllers work.
The problem:
In my layouts, if I remove the following, the layouts work:
{{ HTML::style('css/bootstrap.min.css') }}
{{ HTML::style('css/style.css') }}
Question:
What is the correct location and syntax for Blade Stylesheet inclusion in Laravel 5 and what I should be using instead?
The HtmlBuilder has been removed from Laravel's core, so HTML::style() is no longer available.
If you want to use it in laravel 5, add the following to your composer.json file, under the require key:
"laravelcollective/html": "~5.0"
Also note, since HTML::style() returns HTML code, you don't want it escaped. Use the raw brackets:
{!! HTML::style('css/style.css') !!}
Adding to #joseph's answer, for the users preferring not to switch to the new syntax, you can use
Blade::setRawTags('{{', '}}');
and continue with the old syntax . this can be set almost anywhere, but a better choice would be a service provider, say legacy service provide for l4 . you can find further discussion on this at laracasts, where you can find taylor otwells thoughts on this .
If you want to use plain HTML then use like this-
<link rel="stylesheet" href="/css/folder/style.css">

Resources