Skip to content

OD307 t-raw-unsafe

t-raw is deprecated and renders unescaped HTML; use t-out with Markup.

Category Severity Series Needs the index
Security Warning, Error from saas~19.1 15.0 and later no

What it reports

A t-raw attribute in a QWeb template or a view's arch, in a data file of the module. Templates under static/ are not read.

Why it matters

t-raw writes its value into the page as HTML, whatever the value is. When that value holds text a user typed, such as a name, a reference or a comment, the user can inject markup and script into every page or report that renders it. Odoo 15.0 replaced it with t-out, which escapes plain strings and writes a Markup value as it is. Html fields already return Markup, so they render the same way through t-out; other trusted HTML has to be wrapped in Markup in Python, which makes the decision to trust it visible where it is made.

Odoo 15.0 to 19.0 still render t-raw and log a deprecation warning. From saas~19.1 the server no longer knows the directive: it logs it as unknown and renders the element without that content, so a template ported unchanged silently loses it. The rule is an error there.

A t-raw on a value that is already safe is not a vulnerability, but it still needs the rewrite.

Example

report/delivery_note_templates.xml
<template id="report_delivery_note_document">
    <div class="page">
        <h2 t-out="doc.name"/>
        <div t-out="doc.note"/>
        <p t-raw="doc.client_order_ref"/>
    </div>
</template>

client_order_ref is plain text that anyone who edits the order can fill, and t-raw renders any markup in it.

report/delivery_note_templates.xml
<template id="report_delivery_note_document">
    <div class="page">
        <h2 t-out="doc.name"/>
        <div t-out="doc.note"/>
        <p t-out="doc.client_order_ref"/>
    </div>
</template>

Suppressing

<!-- odooscan: ignore[OD307] -->

See suppressing a finding.