Skip to content

Commit eb3221d

Browse files
fix(asm): fix segfault in IAST for f-string formatting of non-text values [backport 2.1] (#7246)
Backport 4d61286 from #7242 to 2.1. IAST: There was a missing step in the construction of f-strings replacements for IAST patching, where non-string values should be formatted. This was causing a segfault in those cases, and this PR should fix them. As you can see in the PEP 498, in the code equivalence section, a format call is performed: https://peps.python.org/pep-0498/#code-equivalence Also add unit tests as regression tests. ## Checklist - [x] Change(s) are motivated and described in the PR description. - [x] Testing strategy is described if automated tests are not included in the PR. - [x] Risk is outlined (performance impact, potential for breakage, maintainability, etc). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] [Library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) are followed. If no release note is required, add label `changelog/no-changelog`. - [x] Documentation is included (in-code, generated user docs, [public corp docs](https://github.com/DataDog/documentation/)). - [x] Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [x] Title is accurate. - [x] No unnecessary changes are introduced. - [x] Description motivates each change. - [x] Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes unless absolutely necessary. - [x] Testing strategy adequately addresses listed risk(s). - [x] Change is maintainable (easy to change, telemetry, documentation). - [x] Release note makes sense to a user of the library. - [x] Reviewer has explicitly acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment. - [x] Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting) - [x] If this PR touches code that signs or publishes builds or packages, or handles credentials of any kind, I've requested a review from `@DataDog/security-design-and-guidance`. - [x] This PR doesn't touch any of that. Co-authored-by: Federico Mon <[email protected]>
1 parent f019c8b commit eb3221d

File tree

4 files changed

+41
-1
lines changed

4 files changed

+41
-1
lines changed

ddtrace/appsec/_iast/_taint_tracking/aspects.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ def format_value_aspect(
374374
else:
375375
new_text = element
376376
if not isinstance(new_text, TEXT_TYPES):
377-
return new_text
377+
return format(new_text)
378378

379379
try:
380380
if format_spec:
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
fixes:
3+
- |
4+
ASM: This fix resolves an issue where an f-string expression would not be formatted properly causing a segfault if IAST is enabled.

tests/appsec/iast/aspects/test_str_py3.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,17 @@ def test_string_fstring_twice_different_objects_tainted_twice(self): # type: ()
100100
result = mod_py3.do_repr_fstring_with_format_twice(obj) # pylint: disable=no-member
101101
assert result == "foo a foo a "
102102
assert as_formatted_evidence(result) == ":+-foo-+: a :+-foo-+: a "
103+
104+
@pytest.mark.parametrize(
105+
"function",
106+
[
107+
mod_py3.do_repr_fstring_with_expression1,
108+
mod_py3.do_repr_fstring_with_expression2,
109+
mod_py3.do_repr_fstring_with_expression3,
110+
mod_py3.do_repr_fstring_with_expression4,
111+
mod_py3.do_repr_fstring_with_expression5,
112+
],
113+
)
114+
def test_string_fstring_non_string(self, function): # type: () -> None
115+
result = function() # pylint: disable=no-member
116+
assert result == "Hello world, True!"

tests/appsec/iast/fixtures/aspects/str_methods_py3.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,28 @@ def do_repr_fstring_with_format_twice(a): # type: (Any) -> str
3333
return f"{a!r:10} {a!r:11}"
3434

3535

36+
def do_repr_fstring_with_expression1(): # type: (Any) -> str
37+
return f"Hello world, {False or True}!"
38+
39+
40+
def do_repr_fstring_with_expression2(): # type: (Any) -> str
41+
return f"Hello world, {'True' * 1}!"
42+
43+
44+
def do_repr_fstring_with_expression3(): # type: (Any) -> str
45+
return f"Hello world, {'true'.capitalize()}!"
46+
47+
48+
def do_repr_fstring_with_expression4(): # type: (Any) -> str
49+
import math
50+
51+
return f"Hello world, {math.sin(5.5) <= 0}!"
52+
53+
54+
def do_repr_fstring_with_expression5(): # type: (Any) -> str
55+
return f"Hello world, {str([False, False, True, False][400 % 199]).lower().capitalize()}!"
56+
57+
3658
class Resolver404(Exception):
3759
pass
3860

0 commit comments

Comments
 (0)