{"record":{"id":"92385900f3e3195d","repo":"nodejs/node","slug":"template","errorCode":null,"errorMessage":"{template}","messagePattern":"\\{template\\}","errorType":"exception","errorClass":"TemplateNotFound","httpStatus":null,"severity":"error","filePath":"tools/inspector_protocol/jinja2/loaders.py","lineNumber":31,"sourceCode":"import weakref\nfrom types import ModuleType\nfrom os import path\nfrom hashlib import sha1\nfrom jinja2.exceptions import TemplateNotFound\nfrom jinja2.utils import open_if_exists, internalcode\nfrom jinja2._compat import string_types, iteritems\n\n\ndef split_template_path(template):\n    \"\"\"Split a path into segments and perform a sanity check.  If it detects\n    '..' in the path it will raise a `TemplateNotFound` error.\n    \"\"\"\n    pieces = []\n    for piece in template.split('/'):\n        if path.sep in piece \\\n           or (path.altsep and path.altsep in piece) or \\\n           piece == path.pardir:\n            raise TemplateNotFound(template)\n        elif piece and piece != '.':\n            pieces.append(piece)\n    return pieces\n\n\nclass BaseLoader(object):\n    \"\"\"Baseclass for all loaders.  Subclass this and override `get_source` to\n    implement a custom loading mechanism.  The environment provides a\n    `get_template` method that calls the loader's `load` method to get the\n    :class:`Template` object.\n\n    A very basic example for a loader that looks up templates on the file\n    system could look like this::\n\n        from jinja2 import BaseLoader, TemplateNotFound\n        from os.path import join, exists, getmtime\n\n        class MyLoader(BaseLoader):","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/inspector_protocol/jinja2/loaders.py#L13-L49","documentation":"split_template_path segments a template name on '/' and rejects any segment containing an OS path separator or equal to the parent-directory marker ('..'). This is a security guard against directory traversal: it raises TemplateNotFound(template) before the loader ever touches the filesystem.","triggerScenarios":"Calling get_template('../secret'), get_template('foo/../../etc/passwd'), or passing a name with a backslash segment on a system where altsep applies — any name that could escape the loader's root.","commonSituations":"Building template names from user input without sanitization; cross-platform path strings using '\\\\' on POSIX; attempting to share templates outside the configured template root.","solutions":["Use only forward-slash-relative names within the configured template root; never include '..' in a template name.","Sanitize/normalize user-supplied names before passing them to get_template (reject '..' and path separators).","If you need templates outside the root, add the directory to the loader's searchpath explicitly."],"exampleFix":"# before\nenv.get_template('../shared/header.html')\n\n# after\nloader = FileSystemLoader(['/app/templates', '/app/shared'])\nenv.get_template('header.html')","handlingStrategy":"validation","validationCode":"import os\n\ndef safe_template_name(name: str) -> str:\n    if not name or name != name.strip():\n        raise ValueError('template name must be non-empty and trimmed')\n    for piece in name.split('/'):\n        if piece in ('', '.', '..') or os.sep in piece or (os.altsep and os.altsep in piece):\n            raise ValueError('unsafe template name: %r' % name)\n    return name","typeGuard":"import os\n\ndef is_safe_template_name(name: str) -> bool:\n    if not isinstance(name, str) or not name:\n        return False\n    for piece in name.split('/'):\n        if piece in ('', '.', '..') or os.sep in piece or (os.altsep and os.altsep in piece):\n            return False\n    return True","tryCatchPattern":"from jinja2 import TemplateNotFound\ntry:\n    tmpl = env.get_template(name)\nexcept TemplateNotFound:\n    raise ValueError('template not found or name rejected: %r' % name)","preventionTips":["Never accept raw user input as a template name; validate against '..' and path separators.","Use forward slashes only; never OS-specific separators in template names.","Expose shared templates by adding their directory to searchpath, not by traversing up."],"tags":["jinja2","loader","security","path-traversal"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}