Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion latte/en/guide.texy
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ Getting Started with Latte

Templates improve code organization, separate application logic from presentation, and enhance security. They offer far better features and expressive means for generating HTML than PHP itself.

Latte is the safest templating system for PHP. You will love its intuitive syntax. A wide range of useful features will significantly simplify your work. It provides top-notch protection against [critical vulnerabilities|safety-first] and allows you to focus on creating high-quality applications without worrying about their security.
When used with trusted templates, Latte is the safest templating system for PHP. You will love its intuitive syntax. A wide range of useful features will significantly simplify your work. It provides top-notch protection against [critical XSS vulnerabilities|safety-first] and allows you to focus on creating high-quality applications without worrying about their security.

To allow templates from untrusted sources, you can enable a built-in [sandbox|sandbox], that prohibits everything that is not explicitly allowed by the policy. This will protect your server from running arbitrary PHP code inside the template.


How to write templates using Latte?
Expand Down
30 changes: 20 additions & 10 deletions latte/en/safety-first.texy
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ Latte is Synonymous with Safety

<div class=perex>

Latte is the only PHP templating system with effective protection against the critical Cross-site Scripting (XSS) vulnerability. This is thanks to context-aware escaping. We will discuss:
When using a template engine, you should consider two potential security-critical scenarios: rendering untrusted templates and embedding untrusted user input.

When working with untrusted templates, use a built-in [sandbox|sandbox] to avoid running unwanted PHP code on the server. Still, templates by design can contain unsafe client-side JavaScript, so you also need to add protections against Cross-site Scripting (XSS).

As for the second scenario, Latte is the only PHP templating system with effective protection against the critical Cross-site Scripting (XSS) vulnerability exploited through embedding unsafe data. This is thanks to context-aware escaping. We will discuss:

- the principle of the XSS vulnerability and why it is so dangerous
- what makes Latte so effective in defending against XSS
Expand All @@ -22,6 +26,21 @@ What can such a script do? For example, it can send any content from the comprom
This is why XSS consistently ranks among the most dangerous vulnerabilities. If a vulnerability appears on a website, it must be removed as soon as possible to prevent exploitation.


Limits of Latte
===============

Latte is not a complete XSS protection for the entire application. We would be unhappy if you stopped thinking about security when using Latte. Latte's goal is to ensure that an attacker cannot alter the page structure or forge HTML elements or attributes. But it does not check the content correctness of the printed data. Nor the correctness of JavaScript behavior. That goes beyond the competence of the templating system. Verifying the correctness of data, especially data entered by the user and therefore untrusted, is an important task for the programmer.

Latte guards your website against XSS in the untrusted data embedded into the template. Here are the examples of what Latte does not prevent:

- XSS outside the templates: It is up to you to protect the rest of your website
- XSS in the template itself: Templates can contain arbitrary JavaScript by design
- DOM-based XSS: Your own JavaScript code can add untrusted data to the page on the client side

.[tip]
Do you want to test your knowledge of escaping in individual contexts? Try the [XSS vulnerability quiz |https://blog.nette.org/en/quiz-can-you-defend-against-xss-vulnerability].


How Does the Vulnerability Arise?
---------------------------------

Expand Down Expand Up @@ -400,14 +419,5 @@ Outputs:

The protection works automatically and requires no configuration.


Limits of Latte
===============

Latte is not a complete XSS protection for the entire application. We would be unhappy if you stopped thinking about security when using Latte. Latte's goal is to ensure that an attacker cannot alter the page structure or forge HTML elements or attributes. But it does not check the content correctness of the printed data. Nor the correctness of JavaScript behavior. That goes beyond the competence of the templating system. Verifying the correctness of data, especially data entered by the user and therefore untrusted, is an important task for the programmer.

.[tip]
Do you want to test your knowledge of escaping in individual contexts? Try the [XSS vulnerability quiz |https://blog.nette.org/en/quiz-can-you-defend-against-xss-vulnerability].

{{maintitle: PHP XSS Protection: Context-Aware Escaping in Latte}}
{{description: Why XSS is so dangerous and how Latte stops it: it knows where each value is printed and escapes it accordingly, which naive template systems cannot do.}}
53 changes: 30 additions & 23 deletions latte/en/sandbox.texy
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,48 @@ Sandbox
*******

.[perex]
Sandbox provides a security layer that gives you control over which tags, PHP functions, methods, etc., can be used in templates. Thanks to the sandbox mode, you can safely collaborate with a client or external coder on template creation without worrying about compromising the application or performing unwanted operations.
Sandbox provides a security layer that gives you control over which tags, PHP functions, methods, etc., can be used in templates. Thanks to the sandbox mode, you can safely collaborate with a client or external coder on template creation without worrying about compromising the application or performing unwanted server-side operations.

How does it work? We simply define what we want to allow in the template. Initially, everything is forbidden and we gradually grant permissions. The following code allows the template author to use the `{block}`, `{if}`, `{else}` and `{=}` tags (the latter is a tag for [printing a variable or expression |tags#Printing]) and all filters:
While Sandbox can protect against server-side attacks and Latte already prevents [Cross-site Scripting (XSS)|safety-first] in the user input, templates by design can contain unsafe HTML with client-side JavaScript. Consider this limitation when using third-party templates.

How does the sandbox work? We simply define what we want to allow in the template. Initially, everything is forbidden and we gradually grant permissions. The following code allows the template author to use the `{block}`, `{if}`, `{else}` and `{=}` tags (the latter is a tag for [printing a variable or expression |tags#Printing]) and all filters:

```php
$policy = new Latte\Sandbox\SecurityPolicy;
$policy->allowTags(['block', 'if', 'else', '=']);
$policy->allowFilters($policy::All);

$latte->setPolicy($policy);
$latte->setSandboxMode();
```

We can also allow access to individual global functions, methods, or properties of objects:
Activating the Sandbox
======================

In the example above, the last line is used to enable sandbox mode directly for all templates:

```php
$latte->setSandboxMode();
```

You can remove it and apply the policy using the [`{sandbox}` |tags#Including Templates] tag. This is somewhat analogous to `{include}`, but it enables sandbox mode and, like `{include}`, does not automatically pass the surrounding variables. You can, however, pass them explicitly, for example `{sandbox 'untrusted.latte', a: 1, b: 2}`:

```latte
{sandbox 'untrusted.latte'}
```

Thus, the layout and individual pages can freely use all tags and variables; restrictions will only be applied to the `untrusted.latte` template.

Some violations, like using a forbidden tag or filter, are detected at compile time. Others, like calling disallowed methods of an object, are detected at runtime. The template can also contain any other errors. To prevent an exception from the sandboxed template from disrupting the entire rendering process, you can define your [own exception handler |develop#Exception Handler], which might, for example, just log it.

Configuring the policy
======================

In our sandbox policy, we can allow access to individual tags, filters, global functions, methods, or properties of objects:

```php
$policy->allowTags(['block', 'if', 'else', '=']);
$policy->allowFilters($policy::All);
$policy->allowFunctions(['trim', 'strlen']);
$policy->allowMethods(Nette\Security\User::class, ['isLoggedIn', 'isAllowed']);
$policy->allowProperties(Nette\Database\Row::class, $policy::All);
Expand Down Expand Up @@ -64,26 +91,6 @@ class MyPolicy implements Latte\Policy
If the method is missing, Latte warns you with a deprecation notice.


Activating the Sandbox
======================

The rules apply to the template that we insert with the [`{sandbox}` |tags#Including Templates] tag. This is somewhat analogous to `{include}`: it enables sandbox mode and, like `{include}`, does not automatically pass the surrounding variables. You can, however, pass them explicitly, for example `{sandbox 'untrusted.latte', a: 1, b: 2}`:

```latte
{sandbox 'untrusted.latte'}
```

Thus, the layout and individual pages can freely use all tags and variables; restrictions will only be applied to the `untrusted.latte` template.

Some violations, like using a forbidden tag or filter, are detected at compile time. Others, like calling disallowed methods of an object, are detected at runtime. The template can also contain any other errors. To prevent an exception from the sandboxed template from disrupting the entire rendering process, you can define your [own exception handler |develop#Exception Handler], which might, for example, just log it.

If we wanted to enable sandbox mode directly for all templates, it's easy:

```php
$latte->setSandboxMode();
```


Checking the Generated Code
===========================

Expand Down