| 101 | # ============================================================ |
| 102 | |
| 103 | class TestFormat864: |
| 104 | def test_tainted_receiver_fires(self): |
| 105 | """template = request.GET.get('t'); template.format(user=user)""" |
| 106 | code = """ |
| 107 | template = request.GET.get('template') |
| 108 | result = template.format(user=user_obj) |
| 109 | """ |
| 110 | assert fires(code, "FORMAT864"), "FORMAT864 must fire: tainted string used as .format() template" |
| 111 | |
| 112 | def test_tainted_via_subscript_fires(self): |
| 113 | code = """ |
| 114 | tmpl = request.GET['template'] |
| 115 | output = tmpl.format(name='Alice') |
| 116 | """ |
| 117 | assert fires(code, "FORMAT864"), "FORMAT864 must fire with subscript source" |
| 118 | |
| 119 | def test_constant_template_safe(self): |
| 120 | code = """ |
| 121 | result = 'Hello {name}!'.format(name=user.name) |
| 122 | """ |
| 123 | assert not fires(code, "FORMAT864"), "FORMAT864 must NOT fire for constant template" |
| 124 | |
| 125 | def test_tainted_arg_safe(self): |
| 126 | # FORMAT864 only fires when the TEMPLATE (receiver) is tainted. |
| 127 | # A safe hardcoded template with tainted ARGUMENTS is not SSTI. |
| 128 | # FP case: msg = '{} is a symlink'; raise FileExistsError(msg.format(cfile)) |
| 129 | code = """ |
| 130 | msg = '{} is not a valid path' |
| 131 | raise ValueError(msg.format(request.GET.get('path'))) |
| 132 | """ |
| 133 | assert not fires(code, "FORMAT864"), "FORMAT864 must NOT fire when only the arg is tainted" |
| 134 | |
| 135 | |
| 136 | # ============================================================ |
nothing calls this directly
no outgoing calls
no test coverage detected