@@ -2480,23 +2480,60 @@ The basic TAL commands are:
24802480**tal:replace="expression"**
24812481 Replace this tag with the result of the expression. For example::
24822482
2483- <span tal:replace="request/user/realname " />
2483+ <span tal:replace="request/user/id " />
24842484
24852485 The example would replace the <span> tag and its contents with the
2486- user's realname. If the user's realname was "Bruce", then the
2487- resultant output would be "Bruce".
2486+ user's id. If the user's id was "3" the resulting output would be
2487+ "3".
2488+
2489+ You need to be a little careful with ``tal:replace``. Unlike
2490+ ``tal:content``, it doesn't always escape the output. For example
2491+ if you used::
2492+
2493+ <tal:x tal:replace="request/user/realname" />
2494+
2495+ it would replace the contents with the value of the user's
2496+ realname. The realname is something the user can control. The user
2497+ could include something like::
2498+
2499+ Bruce<script>alert("hello there");</script>
2500+
2501+ This would result in an alert box popping up when the page was
2502+ loaded. Attackers could use this `XSS exploit`_ for malicious
2503+ purposes.
2504+
2505+ Generally you would use tal:replace when calling a utility function
2506+ using a :ref:`Python expression <python expression>` that generates
2507+ trusted HTML.
2508+
2509+ If you are inserting untrusted content, it is better to use
2510+ ``tal:content`` with tags that disappear as described below.
2511+
2512+ .. _`XSS exploit`: https://owasp.org/www-community/attacks/xss/
24882513
24892514**tal:content="expression"**
2490- Replace the contents of this tag with the result of the expression.
2491- For example::
2515+ Replace the contents of this tag (but not the tag itself) with the
2516+ result of the expression. For example::
24922517
2493- <span tal:content="request/user/realname">user's name appears here
2494- </span>
2518+ <span tal:content="request/user/realname">user's name appears here
2519+ </span>
24952520
24962521 This example would replace the contents of the ``<span>`` tag with the
24972522 user's realname. If the user's realname was "Bruce" then the
24982523 output will be ``<span>Bruce</span>``.
24992524
2525+ ``tal:content`` replaces special HTML claracters like ``<`` with an
2526+ HTML entitity ``<``. This makes it safer to use when inserting
2527+ untrusted data. To have ``tal:content`` insert unescaped HTML, you
2528+ need to use the `structure modifier`_.
2529+
2530+ If the tag is an unknown ``tal:`` tag, TAL removes the tag. So
2531+ evaulating:
2532+
2533+ <tal:x tal:replace="request/user/realname" />
2534+
2535+ results in ``Bruce``.
2536+
25002537**tal:attributes="attribute expression; attribute expression; ..."**
25012538 Set attributes on this tag to the results of expressions. For
25022539 example::
@@ -2574,6 +2611,8 @@ attribute values may be one of the following forms:
25742611 expression in the interpolation decorator ``${ ... }`` is a
25752612 path expression as above.
25762613
2614+ .. _`python expression`:
2615+
25772616**Python Expressions** - e.g. ``python: 1+1``
25782617 These expressions give the full power of Python. All the "root level"
25792618 variables are available, so ``python:item.status.checklist()`` is
@@ -2582,6 +2621,8 @@ attribute values may be one of the following forms:
25822621
25832622Modifiers:
25842623
2624+ .. _`structure modifier`:
2625+
25852626**structure** - e.g. ``structure python:msg.content.plain(hyperlink=1)``
25862627 The result of expressions are *escaped* to be safe for HTML
25872628 display (all "<", ">" and "&" are replaced with entities
0 commit comments