Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.6] Fix translation escaping #25858

Merged
merged 2 commits into from
Oct 2, 2018

Conversation

X-Coder264
Copy link
Contributor

Fixes #25515

d3c0a36 was a security fix because there was an XSS vulnerability when passing parameters as the second method to @lang. Unfortunately the fix escaped the whole output instead of only the parameters that were being replaced which resulted in a major breaking change (because people can no longer use HTML tags inside translations) -> #25408. This PR fixes that by escaping only the parameters that are being replaced so that there can't be any XSS, but doing it this way still allows people to have HTML in the translation files.

@X-Coder264 X-Coder264 force-pushed the fix-translation-escaping branch from 0df2141 to 8ea41e0 Compare October 1, 2018 20:13
@taylorotwell taylorotwell merged commit 1807c92 into laravel:5.6 Oct 2, 2018
@taylorotwell
Copy link
Member

This needs to go to 5.7.

@X-Coder264
Copy link
Contributor Author

@taylorotwell What do you mean? You've already merged this to 5.6 and you merge stuff upstream so this will get to 5.7 too, or I misunderstood something? 😄

@X-Coder264 X-Coder264 deleted the fix-translation-escaping branch October 2, 2018 13:53
@derekmd
Copy link
Contributor

derekmd commented Oct 2, 2018

Compared to the first @lang() attempt, I think you're going to find this commit will cause a louder backlash since it now affects __(), trans() and trans_choice() calls.

It's no longer possible to include HTML in replaced :keys strings (instead requiring new HtmlString() for every parameter), even when user-content is properly encoded and trusted. I know for the product I work on this will cause hundreds, if not thousands, of broken translation outputs now showing readable HTML.

I don't see why a translation service would be responsible for encoding HTML? Wouldn't that fall on the templating system and the end-user's choice? I personally have never touched the @lang() directive either. It seems like programmers should be using Blade {{ }} or {!! !!} to make encoding explicit?

@guidocella
Copy link
Contributor

guidocella commented Oct 2, 2018

Another issue with this approach is that everytime you use trans() in an email subject, you have to remember to wrap the placeholder replacements with new HtmlString().

For example
$this->subject(__('Welcome :name', ['name' => "O'Brien"]))
would result in the subject
Welcome O'Brien

This would probably happen with other notification drivers too like SMS and Slack.

@derekmd
Copy link
Contributor

derekmd commented Oct 3, 2018

It affects translations in JSON response bodies as well.

return response()->json([
    'status' => 'success',
    'data' => $company,
    'message' => __(':name successfully created!', ['name' => $company->name]),
]);
{"status":"success","data":{"id":1,"name":"..."},"message":"Ampersand & Sons successfully created!"}
    // What does JSON have to do with HTML?
    // Vue templating, etc. are responsible for encoding if output is shown in a DOM tree.
    'message' => __(':name successfully created!', ['name' => new HtmlString($company->name)]),
]);

If devs don't give a stuff about @lang() encoding, this will restore the old behavior whilst still allowing the ability to upgrade Laravel:

config/app.php

[
    'providers' => [
        // ...
        // Illuminate\Translation\TranslationServiceProvider::class,
        App\Providers\TranslationServiceProvider::class,

app/Providers/TranslationServiceProvider.php

namespace App\Providers;

use App\Support\Translator;
use Illuminate\Translation\TranslationServiceProvider as BaseTranslationServiceProvider;

class TranslationServiceProvider extends BaseTranslationServiceProvider
{
    public function register()
    {
        $this->registerLoader();

        $this->app->singleton('translator', function ($app) {
            $loader = $app['translation.loader'];

            $locale = $app['config']['app.locale'];

            $trans = new Translator($loader, $locale);

            $trans->setFallback($app['config']['app.fallback_locale']);

            return $trans;
        });
    }
}

app/Support/Translator.php

namespace App\Support;

use Illuminate\Support\Str;
use Illuminate\Translation\Translator as BaseTranslator;

class Translator extends BaseTranslator
{
    protected function makeReplacements($line, array $replace)
    {
        if (empty($replace)) {
            return $line;
        }

        $replace = $this->sortReplacements($replace);

        foreach ($replace as $key => $value) {
            $line = str_replace(
                [':'.$key, ':'.Str::upper($key), ':'.Str::ucfirst($key)],
                [$value, Str::upper($value), Str::ucfirst($value)],
                $line
            );
        }

        return $line;
    }
}

You just have to keep a watchful eye on these with every Composer version bump:

@royduin
Copy link
Contributor

royduin commented Oct 3, 2018

When can we expect a new release with this for 5.6?

TBlindaruk added a commit to TBlindaruk/laravel-framework that referenced this pull request Oct 7, 2018
I`m not sure, but probably we also should reverting `email lang template` ([laravel#25734](laravel#25734)) changes in 5.6 version

Since in prev 5.6 release we also had:
 - `Fixed translation escaping ([laravel#25858](laravel#25858), [4c46500](https://github.com/laravel/framework/commit/4c465007bbf51d7f269871cd76b6d99de7df90bb))` for fixed translation escaping

The same revert was in 5.7 (laravel#25963)
taylorotwell pushed a commit that referenced this pull request Oct 7, 2018
* [5.6] Revert email lang template changes.
I`m not sure, but probably we also should reverting `email lang template` ([#25734](#25734)) changes in 5.6 version

Since in prev 5.6 release we also had:
 - `Fixed translation escaping ([#25858](#25858), [4c46500](https://github.com/laravel/framework/commit/4c465007bbf51d7f269871cd76b6d99de7df90bb))` for fixed translation escaping

The same revert was in 5.7 (#25963)

* [5.6] Revert email lang template changes.
 - add `comma` after last value in array.
taylorotwell pushed a commit to illuminate/notifications that referenced this pull request Oct 7, 2018
* [5.6] Revert email lang template changes.
I`m not sure, but probably we also should reverting `email lang template` ([#25734](laravel/framework#25734)) changes in 5.6 version

Since in prev 5.6 release we also had:
 - `Fixed translation escaping ([#25858](laravel/framework#25858), [4c46500](https://github.com/laravel/framework/commit/4c465007bbf51d7f269871cd76b6d99de7df90bb))` for fixed translation escaping

The same revert was in 5.7 (laravel/framework#25963)

* [5.6] Revert email lang template changes.
 - add `comma` after last value in array.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants