|
| 1 | +#### Obvious Typos or Spelling Errors |
| 2 | +- Spelling errors in macro names, assigned variable names, or user-facing text at their declaration sites; do not report at reference sites |
| 3 | +- Typos in `<#assign>`/`<#macro>`/`<#function>` names that will silently resolve to a missing variable at runtime |
| 4 | + |
| 5 | +#### Output Escaping and XSS |
| 6 | +- Interpolations (`${...}`) that reach HTML without escaping: flag when the template lacks `<#ftl output_format="HTML">` (auto-escaping, FreeMarker 2.3.24+) and the value is not passed through `?html`/`?url`/`?js_string` appropriate to its sink (HTML body, attribute, URL, JS, CSS) |
| 7 | +- Explicit `?no_esc` or `<#noautoesc>` on values that carry user-controlled data — treat as a high-risk escape hatch; flag unless the source is clearly trusted or already sanitized |
| 8 | +- Escaping with the wrong context builtin (e.g. `?html` for a value placed inside a URL or inline `<script>`) |
| 9 | +- Do not report missing `?html` when auto-escaping is active for the file's output format and no override disables it |
| 10 | + |
| 11 | +#### Template Injection / RCE (SSTI) |
| 12 | +- User-controlled data concatenated into template source, or templates whose name/body derives from request input (`<#include>`, `<#import>`, `.get_optional_template(userValue)`) — enables server-side template injection |
| 13 | +- Use of the `?new()` builtin to instantiate `TemplateModel` classes, especially `freemarker.template.utility.Execute` or `ObjectConstructor` — arbitrary code execution; flag unless the class is a vetted internal type |
| 14 | +- `?api` / `?eval` on untrusted input, or exposing raw `Class`/`ClassLoader`/`ProcessBuilder`-reachable objects into the data model |
| 15 | +- Templates authored from untrusted input without a restricted `TemplateClassResolver` (e.g. `SAFER_RESOLVER`) — call it out as a hardening gap |
| 16 | + |
| 17 | +#### Null and Missing-Value Handling |
| 18 | +- Interpolations or directive arguments on possibly-absent values without `!` (default) or `??` (existence) — missing values raise `InvalidReferenceException` at render time |
| 19 | +- Overuse of a bare `!` that masks genuinely-required data with a silent empty string; prefer an explicit default (`value!"fallback"`) or an `<#if value??>` guard where absence is meaningful |
| 20 | +- `!` precedence mistakes in expressions (`a.b.c!` guards only the last step); confirm the intended nullable segment |
| 21 | + |
| 22 | +#### Logic-in-Template Smells |
| 23 | +- Business logic, data-access, or non-trivial computation embedded in templates that belongs in the controller/model layer |
| 24 | +- Deeply nested `<#if>`/`<#list>` or duplicated conditional blocks that indicate the view is doing the model's job |
| 25 | +- `<#assign>` used to build state that should have been prepared before rendering |
| 26 | + |
| 27 | +#### Macro and Include Hygiene |
| 28 | +- `<#include>` where `<#import>` (namespaced) is intended, causing global-namespace pollution or accidental variable shadowing |
| 29 | +- Macros/functions defined but never called, or duplicated across templates instead of shared via a common library template |
| 30 | +- Relative template names passed to `<#include>`/`.get_optional_template` without `?absolute_template_name` when resolution context is ambiguous |
| 31 | +- Missing-template failures not handled (`.get_optional_template(...).exists`) where the include is optional |
| 32 | + |
| 33 | +#### Internationalization and Locale-Sensitive Formatting |
| 34 | +- Numbers, dates, times, and currency emitted with locale-default formatting where a fixed machine format is required (e.g. `?string`/`?c` for numbers in URLs, JSON, or IDs) — `?c` (computer format) prevents locale-dependent thousands separators corrupting non-display output |
| 35 | +- Hard-coded user-facing strings that should come from a localized message/resource bundle |
| 36 | +- Date/number output relying on an implicit locale/timezone without confirming the render environment sets them intentionally |
0 commit comments