diff --git a/ddtrace/appsec/_iast/_ast/visitor.py b/ddtrace/appsec/_iast/_ast/visitor.py index c726b7570b..3c071edb42 100644 --- a/ddtrace/appsec/_iast/_ast/visitor.py +++ b/ddtrace/appsec/_iast/_ast/visitor.py @@ -3,7 +3,6 @@ from _ast import ImportFrom import ast import copy -import os import sys from typing import Any # noqa:F401 from typing import List # noqa:F401 @@ -66,9 +65,6 @@ def __init__( "format_map": "ddtrace_aspects.format_map_aspect", "zfill": "ddtrace_aspects.zfill_aspect", "ljust": "ddtrace_aspects.ljust_aspect", - "split": "ddtrace_aspects.split_aspect", - "rsplit": "ddtrace_aspects.rsplit_aspect", - "splitlines": "ddtrace_aspects.splitlines_aspect", }, # Replacement function for indexes and ranges "slices": { @@ -77,14 +73,10 @@ def __init__( }, # Replacement functions for modules "module_functions": { - "os.path": { - "basename": "ddtrace_aspects._aspect_ospathbasename", - "dirname": "ddtrace_aspects._aspect_ospathdirname", - "join": "ddtrace_aspects._aspect_ospathjoin", - "normcase": "ddtrace_aspects._aspect_ospathnormcase", - "split": "ddtrace_aspects._aspect_ospathsplit", - "splitext": "ddtrace_aspects._aspect_ospathsplitext", - } + # "BytesIO": "ddtrace_aspects.stringio_aspect", + # "StringIO": "ddtrace_aspects.stringio_aspect", + # "format": "ddtrace_aspects.format_aspect", + # "format_map": "ddtrace_aspects.format_map_aspect", }, "operators": { ast.Add: "ddtrace_aspects.add_aspect", @@ -133,13 +125,6 @@ def __init__( }, }, } - - if sys.version_info >= (3, 12): - self._aspects_spec["module_functions"]["os.path"]["splitroot"] = "ddtrace_aspects._aspect_ospathsplitroot" - - if sys.version_info >= (3, 12) or os.name == "nt": - self._aspects_spec["module_functions"]["os.path"]["splitdrive"] = "ddtrace_aspects._aspect_ospathsplitdrive" - self._sinkpoints_spec = { "definitions_module": "ddtrace.appsec._iast.taint_sinks", "alias_module": "ddtrace_taint_sinks", @@ -507,46 +492,30 @@ def visit_Call(self, call_node): # type: (ast.Call) -> Any if self._is_string_format_with_literals(call_node): return call_node - # This resolve moduleparent.modulechild.name - # TODO: use the better Hdiv method with a decorator - func_value = getattr(func_member, "value", None) - func_value_value = getattr(func_value, "value", None) if func_value else None - func_value_value_id = getattr(func_value_value, "id", None) if func_value_value else None - func_value_attr = getattr(func_value, "attr", None) if func_value else None - func_attr = getattr(func_member, "attr", None) - aspect = None - if func_value_value_id or func_attr: - if func_value_value_id and func_value_attr: - # e.g. "os.path" or "one.two.three.whatever" (all dotted previous tokens with be in the id) - key = func_value_value_id + "." + func_value_attr - elif func_value_attr: - # e.g os - key = func_attr - else: - key = None - - if key: - module_dict = self._aspect_modules.get(key, None) - aspect = module_dict.get(func_attr, None) if module_dict else None - if aspect: - # Create a new Name node for the replacement and set it as node.func - call_node.func = self._attr_node(call_node, aspect) - self.ast_modified = call_modified = True + aspect = self._aspect_methods.get(method_name) - if not aspect: - # Not a module symbol, check if it's a known method - aspect = self._aspect_methods.get(method_name) + if aspect: + # Move the Attribute.value to 'args' + new_arg = func_member.value + call_node.args.insert(0, new_arg) + # Send 1 as flag_added_args value + call_node.args.insert(0, self._int_constant(call_node, 1)) + + # Insert None as first parameter instead of a.b.c.method + # to avoid unexpected side effects such as a.b.read(4).method + call_node.args.insert(0, self._none_constant(call_node)) + # Create a new Name node for the replacement and set it as node.func + call_node.func = self._attr_node(call_node, aspect) + self.ast_modified = call_modified = True + + elif hasattr(func_member.value, "id") or hasattr(func_member.value, "attr"): + aspect = self._aspect_modules.get(method_name, None) if aspect: - # Move the Attribute.value to 'args' - new_arg = func_member.value - call_node.args.insert(0, new_arg) - # Send 1 as flag_added_args value - call_node.args.insert(0, self._int_constant(call_node, 1)) - - # Insert None as first parameter instead of a.b.c.method - # to avoid unexpected side effects such as a.b.read(4).method - call_node.args.insert(0, self._none_constant(call_node)) + # Send 0 as flag_added_args value + call_node.args.insert(0, self._int_constant(call_node, 0)) + # Move the Function to 'args' + call_node.args.insert(0, call_node.func) # Create a new Name node for the replacement and set it as node.func call_node.func = self._attr_node(call_node, aspect) diff --git a/ddtrace/appsec/_iast/_taint_tracking/Aspects/AspectSplit.cpp b/ddtrace/appsec/_iast/_taint_tracking/Aspects/AspectSplit.cpp deleted file mode 100644 index 5269270438..0000000000 --- a/ddtrace/appsec/_iast/_taint_tracking/Aspects/AspectSplit.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "AspectSplit.h" -#include "Initializer/Initializer.h" - -template -py::list -api_split_text(const StrType& text, const optional& separator, const optional maxsplit) -{ - TaintRangeMapType* tx_map = initializer->get_tainting_map(); - if (not tx_map) { - throw py::value_error(MSG_ERROR_TAINT_MAP); - } - - auto split = text.attr("split"); - auto split_result = split(separator, maxsplit); - auto ranges = api_get_ranges(text); - if (not ranges.empty()) { - set_ranges_on_splitted(text, ranges, split_result, tx_map, false); - } - - return split_result; -} - -template -py::list -api_rsplit_text(const StrType& text, const optional& separator, const optional maxsplit) -{ - TaintRangeMapType* tx_map = initializer->get_tainting_map(); - if (not tx_map) { - throw py::value_error(MSG_ERROR_TAINT_MAP); - } - - auto rsplit = text.attr("rsplit"); - auto split_result = rsplit(separator, maxsplit); - auto ranges = api_get_ranges(text); - if (not ranges.empty()) { - set_ranges_on_splitted(text, ranges, split_result, tx_map, false); - } - return split_result; -} - -template -py::list -api_splitlines_text(const StrType& text, bool keepends) -{ - TaintRangeMapType* tx_map = initializer->get_tainting_map(); - if (not tx_map) { - throw py::value_error(MSG_ERROR_TAINT_MAP); - } - - auto splitlines = text.attr("splitlines"); - auto split_result = splitlines(keepends); - auto ranges = api_get_ranges(text); - if (not ranges.empty()) { - set_ranges_on_splitted(text, ranges, split_result, tx_map, keepends); - } - return split_result; -} - -void -pyexport_aspect_split(py::module& m) -{ - m.def("_aspect_split", &api_split_text, "text"_a, "separator"_a = py::none(), "maxsplit"_a = -1); - m.def("_aspect_split", &api_split_text, "text"_a, "separator"_a = py::none(), "maxsplit"_a = -1); - m.def("_aspect_split", &api_split_text, "text"_a, "separator"_a = py::none(), "maxsplit"_a = -1); - m.def("_aspect_rsplit", &api_rsplit_text, "text"_a, "separator"_a = py::none(), "maxsplit"_a = -1); - m.def("_aspect_rsplit", &api_rsplit_text, "text"_a, "separator"_a = py::none(), "maxsplit"_a = -1); - m.def("_aspect_rsplit", &api_rsplit_text, "text"_a, "separator"_a = py::none(), "maxsplit"_a = -1); - // cppcheck-suppress assignBoolToPointer - m.def("_aspect_splitlines", &api_splitlines_text, "text"_a, "keepends"_a = false); - // cppcheck-suppress assignBoolToPointer - m.def("_aspect_splitlines", &api_splitlines_text, "text"_a, "keepends"_a = false); - // cppcheck-suppress assignBoolToPointer - m.def("_aspect_splitlines", &api_splitlines_text, "text"_a, "keepends"_a = false); -} \ No newline at end of file diff --git a/ddtrace/appsec/_iast/_taint_tracking/Aspects/AspectSplit.h b/ddtrace/appsec/_iast/_taint_tracking/Aspects/AspectSplit.h deleted file mode 100644 index 5fb708e7c2..0000000000 --- a/ddtrace/appsec/_iast/_taint_tracking/Aspects/AspectSplit.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "Helpers.h" - -template -py::list -api_split_text(const StrType& text, const optional& separator, const optional maxsplit); - -template -py::list -api_rsplit_text(const StrType& text, const optional& separator, const optional maxsplit); - -template -py::list -api_splitlines_text(const StrType& text, bool keepends); - -void -pyexport_aspect_split(py::module& m); \ No newline at end of file diff --git a/ddtrace/appsec/_iast/_taint_tracking/Aspects/AspectsOsPath.cpp b/ddtrace/appsec/_iast/_taint_tracking/Aspects/AspectsOsPath.cpp deleted file mode 100644 index 86055cf035..0000000000 --- a/ddtrace/appsec/_iast/_taint_tracking/Aspects/AspectsOsPath.cpp +++ /dev/null @@ -1,277 +0,0 @@ -#include "AspectsOsPath.h" -#include - -#include "Helpers.h" - -static bool -starts_with_separator(const py::handle& arg, const std::string& separator) -{ - std::string carg = py::cast(arg); - return carg.substr(0, 1) == separator; -} - -template -StrType -api_ospathjoin_aspect(StrType& first_part, const py::args& args) -{ - auto ospath = py::module_::import("os.path"); - auto join = ospath.attr("join"); - auto joined = join(first_part, *args); - - auto tx_map = initializer->get_tainting_map(); - if (not tx_map or tx_map->empty()) { - return joined; - } - - std::string separator = ospath.attr("sep").cast(); - auto sepsize = separator.size(); - - // Find the initial iteration point. This will be the first argument that has the separator ("/foo") - // as a first character or first_part (the first element) if no such argument is found. - auto initial_arg_pos = -1; - bool root_is_after_first = false; - for (auto& arg : args) { - if (not is_text(arg.ptr())) { - return joined; - } - - if (starts_with_separator(arg, separator)) { - root_is_after_first = true; - initial_arg_pos++; - break; - } - initial_arg_pos++; - } - - TaintRangeRefs result_ranges; - result_ranges.reserve(args.size()); - - std::vector all_ranges; - unsigned long current_offset = 0; - auto first_part_len = py::len(first_part); - - if (not root_is_after_first) { - // Get the ranges of first_part and set them to the result, skipping the first character position - // if it's a separator - bool ranges_error; - TaintRangeRefs ranges; - std::tie(ranges, ranges_error) = get_ranges(first_part.ptr(), tx_map); - if (not ranges_error and not ranges.empty()) { - for (auto& range : ranges) { - result_ranges.emplace_back(shift_taint_range(range, current_offset, first_part_len)); - } - } - - if (not first_part.is(py::str(separator))) { - current_offset = py::len(first_part); - } - - current_offset += sepsize; - initial_arg_pos = 0; - } - - unsigned long unsigned_initial_arg_pos = max(0, initial_arg_pos); - - // Now go trough the arguments and do the same - for (unsigned long i = 0; i < args.size(); i++) { - if (i >= unsigned_initial_arg_pos) { - // Set the ranges from the corresponding argument - bool ranges_error; - TaintRangeRefs ranges; - std::tie(ranges, ranges_error) = get_ranges(args[i].ptr(), tx_map); - if (not ranges_error and not ranges.empty()) { - auto len_args_i = py::len(args[i]); - for (auto& range : ranges) { - result_ranges.emplace_back(shift_taint_range(range, current_offset, len_args_i)); - } - } - current_offset += py::len(args[i]); - current_offset += sepsize; - } - } - - if (not result_ranges.empty()) { - PyObject* new_result = new_pyobject_id(joined.ptr()); - set_ranges(new_result, result_ranges, tx_map); - return py::reinterpret_steal(new_result); - } - - return joined; -} - -template -StrType -api_ospathbasename_aspect(const StrType& path) -{ - auto tx_map = initializer->get_tainting_map(); - if (not tx_map) { - throw py::value_error(MSG_ERROR_TAINT_MAP); - } - - auto ospath = py::module_::import("os.path"); - auto basename = ospath.attr("basename"); - auto basename_result = basename(path); - if (py::len(basename_result) == 0) { - return basename_result; - } - - bool ranges_error; - TaintRangeRefs ranges; - std::tie(ranges, ranges_error) = get_ranges(path.ptr(), tx_map); - if (ranges_error or ranges.empty()) { - return basename_result; - } - - // Create a fake list to call set_ranges_on_splitted on it (we are - // only interested on the last path, which is the basename result) - auto prev_path_len = py::len(path) - py::len(basename_result); - std::string filler(prev_path_len, 'X'); - py::str filler_str(filler); - py::list apply_list; - apply_list.append(filler_str); - apply_list.append(basename_result); - - set_ranges_on_splitted(path, ranges, apply_list, tx_map, false); - return apply_list[1]; -} - -template -StrType -api_ospathdirname_aspect(const StrType& path) -{ - auto tx_map = initializer->get_tainting_map(); - if (not tx_map) { - throw py::value_error(MSG_ERROR_TAINT_MAP); - } - - auto ospath = py::module_::import("os.path"); - auto dirname = ospath.attr("dirname"); - auto dirname_result = dirname(path); - if (py::len(dirname_result) == 0) { - return dirname_result; - } - - bool ranges_error; - TaintRangeRefs ranges; - std::tie(ranges, ranges_error) = get_ranges(path.ptr(), tx_map); - if (ranges_error or ranges.empty()) { - return dirname_result; - } - - // Create a fake list to call set_ranges_on_splitted on it (we are - // only interested on the first path, which is the dirname result) - auto prev_path_len = py::len(path) - py::len(dirname_result); - std::string filler(prev_path_len, 'X'); - py::str filler_str(filler); - py::list apply_list; - apply_list.append(dirname_result); - apply_list.append(filler_str); - - set_ranges_on_splitted(path, ranges, apply_list, tx_map, false); - return apply_list[0]; -} - -template -static py::tuple -_forward_to_set_ranges_on_splitted(const char* function_name, const StrType& path, bool includeseparator = false) -{ - auto tx_map = initializer->get_tainting_map(); - if (not tx_map) { - throw py::value_error(MSG_ERROR_TAINT_MAP); - } - auto ospath = py::module_::import("os.path"); - auto function = ospath.attr(function_name); - auto function_result = function(path); - if (py::len(function_result) == 0) { - return function_result; - } - - bool ranges_error; - TaintRangeRefs ranges; - std::tie(ranges, ranges_error) = get_ranges(path.ptr(), tx_map); - if (ranges_error or ranges.empty()) { - return function_result; - } - - set_ranges_on_splitted(path, ranges, function_result, tx_map, includeseparator); - return function_result; -} - -template -py::tuple -api_ospathsplit_aspect(const StrType& path) -{ - return _forward_to_set_ranges_on_splitted("split", path); -} - -template -py::tuple -api_ospathsplitext_aspect(const StrType& path) -{ - return _forward_to_set_ranges_on_splitted("splitext", path, true); -} - -template -py::tuple -api_ospathsplitdrive_aspect(const StrType& path) -{ - return _forward_to_set_ranges_on_splitted("splitdrive", path, true); -} - -template -py::tuple -api_ospathsplitroot_aspect(const StrType& path) -{ - return _forward_to_set_ranges_on_splitted("splitroot", path, true); -} - -template -StrType -api_ospathnormcase_aspect(const StrType& path) -{ - auto tx_map = initializer->get_tainting_map(); - if (not tx_map) { - throw py::value_error(MSG_ERROR_TAINT_MAP); - } - - auto ospath = py::module_::import("os.path"); - auto normcase = ospath.attr("normcase"); - auto normcased = normcase(path); - - bool ranges_error; - TaintRangeRefs ranges; - std::tie(ranges, ranges_error) = get_ranges(path.ptr(), tx_map); - if (ranges_error or ranges.empty()) { - return normcased; - } - - TaintRangeRefs result_ranges = ranges; - PyObject* new_result = new_pyobject_id(normcased.ptr()); - if (new_result) { - set_ranges(new_result, result_ranges, tx_map); - return py::reinterpret_steal(new_result); - } - - return normcased; -} - -void -pyexport_ospath_aspects(py::module& m) -{ - m.def("_aspect_ospathjoin", &api_ospathjoin_aspect, "first_part"_a); - m.def("_aspect_ospathjoin", &api_ospathjoin_aspect, "first_part"_a); - m.def("_aspect_ospathnormcase", &api_ospathnormcase_aspect, "path"_a); - m.def("_aspect_ospathnormcase", &api_ospathnormcase_aspect, "path"_a); - m.def("_aspect_ospathbasename", &api_ospathbasename_aspect, "path"_a); - m.def("_aspect_ospathbasename", &api_ospathbasename_aspect, "path"_a); - m.def("_aspect_ospathdirname", &api_ospathdirname_aspect, "path"_a); - m.def("_aspect_ospathdirname", &api_ospathdirname_aspect, "path"_a); - m.def("_aspect_ospathsplit", &api_ospathsplit_aspect, "path"_a); - m.def("_aspect_ospathsplit", &api_ospathsplit_aspect, "path"_a); - m.def("_aspect_ospathsplitext", &api_ospathsplitext_aspect, "path"_a); - m.def("_aspect_ospathsplitext", &api_ospathsplitext_aspect, "path"_a); - m.def("_aspect_ospathsplitdrive", &api_ospathsplitdrive_aspect, "path"_a); - m.def("_aspect_ospathsplitdrive", &api_ospathsplitdrive_aspect, "path"_a); - m.def("_aspect_ospathsplitroot", &api_ospathsplitroot_aspect, "path"_a); - m.def("_aspect_ospathsplitroot", &api_ospathsplitroot_aspect, "path"_a); -} diff --git a/ddtrace/appsec/_iast/_taint_tracking/Aspects/AspectsOsPath.h b/ddtrace/appsec/_iast/_taint_tracking/Aspects/AspectsOsPath.h deleted file mode 100644 index 48e1baf354..0000000000 --- a/ddtrace/appsec/_iast/_taint_tracking/Aspects/AspectsOsPath.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once -#include "Initializer/Initializer.h" -#include "TaintTracking/TaintRange.h" -#include "TaintTracking/TaintedObject.h" - -namespace py = pybind11; - -template -StrType -api_ospathjoin_aspect(StrType& first_part, const py::args& args); - -template -StrType -api_ospathbasename_aspect(const StrType& path); - -template -StrType -api_ospathdirname_aspect(const StrType& path); - -template -py::tuple -api_ospathsplit_aspect(const StrType& path); - -template -py::tuple -api_ospathsplitext_aspect(const StrType& path); - -template -py::tuple -api_ospathsplitdrive_aspect(const StrType& path); - -template -py::tuple -api_ospathsplitroot_aspect(const StrType& path); - -template -StrType -api_ospathnormcase_aspect(const StrType& path); - -void -pyexport_ospath_aspects(py::module& m); diff --git a/ddtrace/appsec/_iast/_taint_tracking/Aspects/_aspects_exports.h b/ddtrace/appsec/_iast/_taint_tracking/Aspects/_aspects_exports.h index 1331af54a9..fd45b423cb 100644 --- a/ddtrace/appsec/_iast/_taint_tracking/Aspects/_aspects_exports.h +++ b/ddtrace/appsec/_iast/_taint_tracking/Aspects/_aspects_exports.h @@ -1,7 +1,5 @@ #pragma once #include "AspectFormat.h" -#include "AspectSplit.h" -#include "AspectsOsPath.h" #include "Helpers.h" #include @@ -12,9 +10,4 @@ pyexport_m_aspect_helpers(py::module& m) pyexport_aspect_helpers(m_aspect_helpers); py::module m_aspect_format = m.def_submodule("aspect_format", "Aspect Format"); pyexport_format_aspect(m_aspect_format); - - py::module m_aspects_ospath = m.def_submodule("aspects_ospath", "Aspect os.path.join"); - pyexport_ospath_aspects(m_aspects_ospath); - py::module m_aspect_split = m.def_submodule("aspect_split", "Aspect split"); - pyexport_aspect_split(m_aspect_split); } diff --git a/ddtrace/appsec/_iast/_taint_tracking/TaintTracking/TaintRange.cpp b/ddtrace/appsec/_iast/_taint_tracking/TaintTracking/TaintRange.cpp index 4883a84213..49e3e4a78f 100644 --- a/ddtrace/appsec/_iast/_taint_tracking/TaintTracking/TaintRange.cpp +++ b/ddtrace/appsec/_iast/_taint_tracking/TaintTracking/TaintRange.cpp @@ -38,7 +38,7 @@ TaintRange::get_hash() const }; TaintRangePtr -shift_taint_range(const TaintRangePtr& source_taint_range, RANGE_START offset, RANGE_LENGTH new_length = -1) +api_shift_taint_range(const TaintRangePtr& source_taint_range, RANGE_START offset, RANGE_LENGTH new_length = -1) { if (new_length == -1) { new_length = source_taint_range->length; @@ -56,7 +56,7 @@ shift_taint_ranges(const TaintRangeRefs& source_taint_ranges, RANGE_START offset new_ranges.reserve(source_taint_ranges.size()); for (const auto& trange : source_taint_ranges) { - new_ranges.emplace_back(shift_taint_range(trange, offset, new_length)); + new_ranges.emplace_back(api_shift_taint_range(trange, offset, new_length)); } return new_ranges; } @@ -243,7 +243,7 @@ get_range_by_hash(size_t range_hash, optional& taint_ranges) } TaintRangeRefs -api_get_ranges(const py::object& string_input) +api_get_ranges(py::object& string_input) { bool ranges_error; TaintRangeRefs ranges; diff --git a/ddtrace/appsec/_iast/_taint_tracking/TaintTracking/TaintRange.h b/ddtrace/appsec/_iast/_taint_tracking/TaintTracking/TaintRange.h index d076dc5984..72152200d5 100644 --- a/ddtrace/appsec/_iast/_taint_tracking/TaintTracking/TaintRange.h +++ b/ddtrace/appsec/_iast/_taint_tracking/TaintTracking/TaintRange.h @@ -73,13 +73,7 @@ using TaintRangePtr = shared_ptr; using TaintRangeRefs = vector; TaintRangePtr -shift_taint_range(const TaintRangePtr& source_taint_range, RANGE_START offset, RANGE_LENGTH new_length); - -inline TaintRangePtr -api_shift_taint_range(const TaintRangePtr& source_taint_range, RANGE_START offset, RANGE_LENGTH new_length) -{ - return shift_taint_range(source_taint_range, offset, new_length); -} +api_shift_taint_range(const TaintRangePtr& source_taint_range, RANGE_START offset, RANGE_LENGTH new_length); TaintRangeRefs shift_taint_ranges(const TaintRangeRefs& source_taint_ranges, RANGE_START offset, RANGE_LENGTH new_length); @@ -97,7 +91,7 @@ py::object api_set_ranges(py::object& str, const TaintRangeRefs& ranges); TaintRangeRefs -api_get_ranges(const py::object& string_input); +api_get_ranges(py::object& string_input); void api_copy_ranges_from_strings(py::object& str_1, py::object& str_2); diff --git a/ddtrace/appsec/_iast/_taint_tracking/__init__.py b/ddtrace/appsec/_iast/_taint_tracking/__init__.py index b155e7c08a..ba1217a9ab 100644 --- a/ddtrace/appsec/_iast/_taint_tracking/__init__.py +++ b/ddtrace/appsec/_iast/_taint_tracking/__init__.py @@ -24,17 +24,6 @@ from ._native.aspect_helpers import common_replace from ._native.aspect_helpers import parse_params from ._native.aspect_helpers import set_ranges_on_splitted - from ._native.aspect_split import _aspect_rsplit - from ._native.aspect_split import _aspect_split - from ._native.aspect_split import _aspect_splitlines - from ._native.aspects_ospath import _aspect_ospathbasename - from ._native.aspects_ospath import _aspect_ospathdirname - from ._native.aspects_ospath import _aspect_ospathjoin - from ._native.aspects_ospath import _aspect_ospathnormcase - from ._native.aspects_ospath import _aspect_ospathsplit - from ._native.aspects_ospath import _aspect_ospathsplitdrive - from ._native.aspects_ospath import _aspect_ospathsplitext - from ._native.aspects_ospath import _aspect_ospathsplitroot from ._native.initializer import active_map_addreses_size from ._native.initializer import create_context from ._native.initializer import debug_taint_map @@ -91,17 +80,6 @@ "str_to_origin", "origin_to_str", "common_replace", - "_aspect_ospathjoin", - "_aspect_split", - "_aspect_rsplit", - "_aspect_splitlines", - "_aspect_ospathbasename", - "_aspect_ospathdirname", - "_aspect_ospathnormcase", - "_aspect_ospathsplit", - "_aspect_ospathsplitext", - "_aspect_ospathsplitdrive", - "_aspect_ospathsplitroot", "_format_aspect", "as_formatted_evidence", "parse_params", diff --git a/ddtrace/appsec/_iast/_taint_tracking/aspects.py b/ddtrace/appsec/_iast/_taint_tracking/aspects.py index cae1e07d45..66c392ef3b 100644 --- a/ddtrace/appsec/_iast/_taint_tracking/aspects.py +++ b/ddtrace/appsec/_iast/_taint_tracking/aspects.py @@ -16,17 +16,6 @@ from .._taint_tracking import TagMappingMode from .._taint_tracking import TaintRange -from .._taint_tracking import _aspect_ospathbasename -from .._taint_tracking import _aspect_ospathdirname -from .._taint_tracking import _aspect_ospathjoin -from .._taint_tracking import _aspect_ospathnormcase -from .._taint_tracking import _aspect_ospathsplit -from .._taint_tracking import _aspect_ospathsplitdrive -from .._taint_tracking import _aspect_ospathsplitext -from .._taint_tracking import _aspect_ospathsplitroot -from .._taint_tracking import _aspect_rsplit -from .._taint_tracking import _aspect_split -from .._taint_tracking import _aspect_splitlines from .._taint_tracking import _convert_escaped_text_to_tainted_text from .._taint_tracking import _format_aspect from .._taint_tracking import are_all_text_all_ranges @@ -55,26 +44,7 @@ _join_aspect = aspects.join_aspect _slice_aspect = aspects.slice_aspect -__all__ = [ - "add_aspect", - "str_aspect", - "bytearray_extend_aspect", - "decode_aspect", - "encode_aspect", - "_aspect_ospathjoin", - "_aspect_split", - "_aspect_rsplit", - "_aspect_splitlines", - "_aspect_ospathbasename", - "_aspect_ospathdirname", - "_aspect_ospathnormcase", - "_aspect_ospathsplit", - "_aspect_ospathsplitext", - "_aspect_ospathsplitdrive", - "_aspect_ospathsplitroot", -] - -# TODO: Factorize the "flags_added_args" copypasta into a decorator +__all__ = ["add_aspect", "str_aspect", "bytearray_extend_aspect", "decode_aspect", "encode_aspect"] def add_aspect(op1, op2): @@ -87,45 +57,6 @@ def add_aspect(op1, op2): return op1 + op2 -def split_aspect(orig_function: Optional[Callable], flag_added_args: int, *args: Any, **kwargs: Any) -> str: - if orig_function: - if orig_function != builtin_str: - if flag_added_args > 0: - args = args[flag_added_args:] - return orig_function(*args, **kwargs) - try: - return _aspect_split(*args, **kwargs) - except Exception as e: - iast_taint_log_error("IAST propagation error. split_aspect. {}".format(e)) - return args[0].split(*args[1:], **kwargs) - - -def rsplit_aspect(orig_function: Optional[Callable], flag_added_args: int, *args: Any, **kwargs: Any) -> str: - if orig_function: - if orig_function != builtin_str: - if flag_added_args > 0: - args = args[flag_added_args:] - return orig_function(*args, **kwargs) - try: - return _aspect_rsplit(*args, **kwargs) - except Exception as e: - iast_taint_log_error("IAST propagation error. rsplit_aspect. {}".format(e)) - return args[0].rsplit(*args[1:], **kwargs) - - -def splitlines_aspect(orig_function: Optional[Callable], flag_added_args: int, *args: Any, **kwargs: Any) -> str: - if orig_function: - if orig_function != builtin_str: - if flag_added_args > 0: - args = args[flag_added_args:] - return orig_function(*args, **kwargs) - try: - return _aspect_splitlines(*args, **kwargs) - except Exception as e: - iast_taint_log_error("IAST propagation error. splitlines_aspect. {}".format(e)) - return args[0].splitlines(*args[1:], **kwargs) - - def str_aspect(orig_function: Optional[Callable], flag_added_args: int, *args: Any, **kwargs: Any) -> str: if orig_function: if orig_function != builtin_str: @@ -285,14 +216,12 @@ def modulo_aspect(candidate_text: Text, candidate_tuple: Any) -> Any: tag_mapping_function=TagMappingMode.Mapper, ) % tuple( - ( - as_formatted_evidence( - parameter, - tag_mapping_function=TagMappingMode.Mapper, - ) - if isinstance(parameter, IAST.TEXT_TYPES) - else parameter + as_formatted_evidence( + parameter, + tag_mapping_function=TagMappingMode.Mapper, ) + if isinstance(parameter, IAST.TEXT_TYPES) + else parameter for parameter in parameter_list ), ranges_orig=ranges_orig, @@ -453,11 +382,9 @@ def format_map_aspect( candidate_text, candidate_text_ranges, tag_mapping_function=TagMappingMode.Mapper ).format_map( { - key: ( - as_formatted_evidence(value, tag_mapping_function=TagMappingMode.Mapper) - if isinstance(value, IAST.TEXT_TYPES) - else value - ) + key: as_formatted_evidence(value, tag_mapping_function=TagMappingMode.Mapper) + if isinstance(value, IAST.TEXT_TYPES) + else value for key, value in mapping.items() } ), diff --git a/ddtrace/appsec/_iast/taint_sinks/ast_taint.py b/ddtrace/appsec/_iast/taint_sinks/ast_taint.py index 57d22f6379..af8f59b15a 100644 --- a/ddtrace/appsec/_iast/taint_sinks/ast_taint.py +++ b/ddtrace/appsec/_iast/taint_sinks/ast_taint.py @@ -14,7 +14,6 @@ from typing import Callable # noqa:F401 -# TODO: we also need a native version of this function! def ast_function( func, # type: Callable flag_added_args, # type: Any diff --git a/tests/appsec/iast/aspects/test_aspect_helpers.py b/tests/appsec/iast/aspects/test_aspect_helpers.py index 7e8a5a4123..43efa3d8ef 100644 --- a/tests/appsec/iast/aspects/test_aspect_helpers.py +++ b/tests/appsec/iast/aspects/test_aspect_helpers.py @@ -72,8 +72,8 @@ def test_common_replace_tainted_bytearray(): assert get_ranges(s2) == [_RANGE1, _RANGE2] -def _build_sample_range(start, length, name): # type: (int, int) -> TaintRange - return TaintRange(start, length, Source(name, "sample_value", OriginType.PARAMETER)) +def _build_sample_range(start, end, name): # type: (int, int) -> TaintRange + return TaintRange(start, end, Source(name, "sample_value", OriginType.PARAMETER)) def test_as_formatted_evidence(): # type: () -> None diff --git a/tests/appsec/iast/aspects/test_ospath_aspects.py b/tests/appsec/iast/aspects/test_ospath_aspects.py deleted file mode 100644 index 87d60ad6a4..0000000000 --- a/tests/appsec/iast/aspects/test_ospath_aspects.py +++ /dev/null @@ -1,714 +0,0 @@ -import os -import sys - -import pytest - -from ddtrace.appsec._iast._taint_tracking import OriginType -from ddtrace.appsec._iast._taint_tracking import Source -from ddtrace.appsec._iast._taint_tracking import TaintRange -from ddtrace.appsec._iast._taint_tracking import _aspect_ospathbasename -from ddtrace.appsec._iast._taint_tracking import _aspect_ospathdirname -from ddtrace.appsec._iast._taint_tracking import _aspect_ospathjoin -from ddtrace.appsec._iast._taint_tracking import _aspect_ospathnormcase -from ddtrace.appsec._iast._taint_tracking import _aspect_ospathsplit -from ddtrace.appsec._iast._taint_tracking import _aspect_ospathsplitext - - -if sys.version_info >= (3, 12) or os.name == "nt": - from ddtrace.appsec._iast._taint_tracking import _aspect_ospathsplitdrive -if sys.version_info >= (3, 12): - from ddtrace.appsec._iast._taint_tracking import _aspect_ospathsplitroot -from ddtrace.appsec._iast._taint_tracking import get_tainted_ranges -from ddtrace.appsec._iast._taint_tracking import taint_pyobject - - -def test_ospathjoin_first_arg_nottainted_noslash(): - tainted_foo = taint_pyobject( - pyobject="foo", - source_name="test_ospath", - source_value="foo", - source_origin=OriginType.PARAMETER, - ) - - tainted_bar = taint_pyobject( - pyobject="bar", - source_name="test_ospath", - source_value="bar", - source_origin=OriginType.PARAMETER, - ) - res = _aspect_ospathjoin("root", tainted_foo, "nottainted", tainted_bar, "alsonottainted") - assert res == "root/foo/nottainted/bar/alsonottainted" - assert get_tainted_ranges(res) == [ - TaintRange(5, 3, Source("test_ospath", "foo", OriginType.PARAMETER)), - TaintRange(20, 3, Source("test_ospath", "bar", OriginType.PARAMETER)), - ] - - -def test_ospathjoin_later_arg_tainted_with_slash_then_ignore_previous(): - ignored_tainted_foo = taint_pyobject( - pyobject="foo", - source_name="test_ospath", - source_value="foo", - source_origin=OriginType.PARAMETER, - ) - - tainted_slashbar = taint_pyobject( - pyobject="/bar", - source_name="test_ospath", - source_value="/bar", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathjoin("ignored", ignored_tainted_foo, "ignored_nottainted", tainted_slashbar, "alsonottainted") - assert res == "/bar/alsonottainted" - assert get_tainted_ranges(res) == [ - TaintRange(0, 4, Source("test_ospath", "/bar", OriginType.PARAMETER)), - ] - - -def test_ospathjoin_first_arg_tainted_no_slash(): - tainted_foo = taint_pyobject( - pyobject="foo", - source_name="test_ospath", - source_value="foo", - source_origin=OriginType.PARAMETER, - ) - - tainted_bar = taint_pyobject( - pyobject="bar", - source_name="test_ospath", - source_value="bar", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathjoin(tainted_foo, "nottainted", tainted_bar, "alsonottainted") - assert res == "foo/nottainted/bar/alsonottainted" - assert get_tainted_ranges(res) == [ - TaintRange(0, 3, Source("test_ospath", "foo", OriginType.PARAMETER)), - TaintRange(15, 3, Source("test_ospath", "bar", OriginType.PARAMETER)), - ] - - -def test_ospathjoin_first_arg_tainted_with_slash(): - tainted_slashfoo = taint_pyobject( - pyobject="/foo", - source_name="test_ospath", - source_value="/foo", - source_origin=OriginType.PARAMETER, - ) - - tainted_bar = taint_pyobject( - pyobject="bar", - source_name="test_ospath", - source_value="bar", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathjoin(tainted_slashfoo, "nottainted", tainted_bar, "alsonottainted") - assert res == "/foo/nottainted/bar/alsonottainted" - assert get_tainted_ranges(res) == [ - TaintRange(0, 4, Source("test_ospath", "/foo", OriginType.PARAMETER)), - TaintRange(16, 3, Source("test_ospath", "bar", OriginType.PARAMETER)), - ] - - -def test_ospathjoin_single_arg_nottainted(): - res = _aspect_ospathjoin("nottainted") - assert res == "nottainted" - assert not get_tainted_ranges(res) - - res = _aspect_ospathjoin("/nottainted") - assert res == "/nottainted" - assert not get_tainted_ranges(res) - - -def test_ospathjoin_single_arg_tainted(): - tainted_foo = taint_pyobject( - pyobject="foo", - source_name="test_ospath", - source_value="foo", - source_origin=OriginType.PARAMETER, - ) - res = _aspect_ospathjoin(tainted_foo) - assert res == "foo" - assert get_tainted_ranges(res) == [TaintRange(0, 3, Source("test_ospath", "/foo", OriginType.PARAMETER))] - - tainted_slashfoo = taint_pyobject( - pyobject="/foo", - source_name="test_ospath", - source_value="/foo", - source_origin=OriginType.PARAMETER, - ) - res = _aspect_ospathjoin(tainted_slashfoo) - assert res == "/foo" - assert get_tainted_ranges(res) == [TaintRange(0, 4, Source("test_ospath", "/foo", OriginType.PARAMETER))] - - -def test_ospathjoin_last_slash_nottainted(): - tainted_foo = taint_pyobject( - pyobject="foo", - source_name="test_ospath", - source_value="foo", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathjoin("root", tainted_foo, "/nottainted") - assert res == "/nottainted" - assert not get_tainted_ranges(res) - - -def test_ospathjoin_last_slash_tainted(): - tainted_foo = taint_pyobject( - pyobject="foo", - source_name="test_ospath", - source_value="foo", - source_origin=OriginType.PARAMETER, - ) - - tainted_slashbar = taint_pyobject( - pyobject="/bar", - source_name="test_ospath", - source_value="/bar", - source_origin=OriginType.PARAMETER, - ) - res = _aspect_ospathjoin("root", tainted_foo, "nottainted", tainted_slashbar) - assert res == "/bar" - assert get_tainted_ranges(res) == [TaintRange(0, 4, Source("test_ospath", "/bar", OriginType.PARAMETER))] - - -def test_ospathjoin_wrong_arg(): - with pytest.raises(TypeError): - _ = _aspect_ospathjoin("root", 42, "foobar") - - -def test_ospathjoin_bytes_nottainted(): - res = _aspect_ospathjoin(b"nottainted", b"alsonottainted") - assert res == b"nottainted/alsonottainted" - - -def test_ospathjoin_bytes_tainted(): - tainted_foo = taint_pyobject( - pyobject=b"foo", - source_name="test_ospath", - source_value=b"foo", - source_origin=OriginType.PARAMETER, - ) - res = _aspect_ospathjoin(tainted_foo, b"nottainted") - assert res == b"foo/nottainted" - assert get_tainted_ranges(res) == [TaintRange(0, 3, Source("test_ospath", b"foo", OriginType.PARAMETER))] - - tainted_slashfoo = taint_pyobject( - pyobject=b"/foo", - source_name="test_ospath", - source_value=b"/foo", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathjoin(tainted_slashfoo, b"nottainted") - assert res == b"/foo/nottainted" - assert get_tainted_ranges(res) == [TaintRange(0, 4, Source("test_ospath", b"/foo", OriginType.PARAMETER))] - - res = _aspect_ospathjoin(b"nottainted_ignore", b"alsoignored", tainted_slashfoo) - assert res == b"/foo" - assert get_tainted_ranges(res) == [TaintRange(0, 4, Source("test_ospath", b"/foo", OriginType.PARAMETER))] - - -def test_ospathjoin_empty(): - res = _aspect_ospathjoin("") - assert res == "" - - -def test_ospathjoin_noparams(): - with pytest.raises(TypeError): - _ = _aspect_ospathjoin() - - -def test_ospathbasename_tainted_normal(): - tainted_foobarbaz = taint_pyobject( - pyobject="/foo/bar/baz", - source_name="test_ospath", - source_value="/foo/bar/baz", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathbasename(tainted_foobarbaz) - assert res == "baz" - assert get_tainted_ranges(res) == [TaintRange(0, 3, Source("test_ospath", "/foo/bar/baz", OriginType.PARAMETER))] - - -def test_ospathbasename_tainted_empty(): - tainted_empty = taint_pyobject( - pyobject="", - source_name="test_ospath", - source_value="", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathbasename(tainted_empty) - assert res == "" - assert not get_tainted_ranges(res) - - -def test_ospathbasename_nottainted(): - res = _aspect_ospathbasename("/foo/bar/baz") - assert res == "baz" - assert not get_tainted_ranges(res) - - -def test_ospathbasename_wrong_arg(): - with pytest.raises(TypeError): - _ = _aspect_ospathbasename(42) - - -def test_ospathbasename_bytes_tainted(): - tainted_foobarbaz = taint_pyobject( - pyobject=b"/foo/bar/baz", - source_name="test_ospath", - source_value=b"/foo/bar/baz", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathbasename(tainted_foobarbaz) - assert res == b"baz" - assert get_tainted_ranges(res) == [TaintRange(0, 3, Source("test_ospath", b"/foo/bar/baz", OriginType.PARAMETER))] - - -def test_ospathbasename_bytes_nottainted(): - res = _aspect_ospathbasename(b"/foo/bar/baz") - assert res == b"baz" - assert not get_tainted_ranges(res) - - -def test_ospathbasename_single_slash_tainted(): - tainted_slash = taint_pyobject( - pyobject="/", - source_name="test_ospath", - source_value="/", - source_origin=OriginType.PARAMETER, - ) - res = _aspect_ospathbasename(tainted_slash) - assert res == "" - assert not get_tainted_ranges(res) - - -def test_ospathbasename_nottainted_empty(): - res = _aspect_ospathbasename("") - assert res == "" - assert not get_tainted_ranges(res) - - -def test_ospathnormcase_tainted_normal(): - tainted_foobarbaz = taint_pyobject( - pyobject="/foo/bar/baz", - source_name="test_ospath", - source_value="/foo/bar/baz", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathnormcase(tainted_foobarbaz) - assert res == "/foo/bar/baz" - assert get_tainted_ranges(res) == [TaintRange(0, 12, Source("test_ospath", "/foo/bar/baz", OriginType.PARAMETER))] - - -def test_ospathnormcase_tainted_empty(): - tainted_empty = taint_pyobject( - pyobject="", - source_name="test_ospath", - source_value="", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathnormcase(tainted_empty) - assert res == "" - assert not get_tainted_ranges(res) - - -def test_ospathnormcase_nottainted(): - res = _aspect_ospathnormcase("/foo/bar/baz") - assert res == "/foo/bar/baz" - assert not get_tainted_ranges(res) - - -def test_ospathnormcase_wrong_arg(): - with pytest.raises(TypeError): - _ = _aspect_ospathnormcase(42) - - -def test_ospathnormcase_bytes_tainted(): - tainted_foobarbaz = taint_pyobject( - pyobject=b"/foo/bar/baz", - source_name="test_ospath", - source_value=b"/foo/bar/baz", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathnormcase(tainted_foobarbaz) - assert res == b"/foo/bar/baz" - assert get_tainted_ranges(res) == [TaintRange(0, 12, Source("test_ospath", b"/foo/bar/baz", OriginType.PARAMETER))] - - -def test_ospathnormcase_bytes_nottainted(): - res = _aspect_ospathnormcase(b"/foo/bar/baz") - assert res == b"/foo/bar/baz" - assert not get_tainted_ranges(res) - - -def test_ospathnormcase_single_slash_tainted(): - tainted_slash = taint_pyobject( - pyobject="/", - source_name="test_ospath", - source_value="/", - source_origin=OriginType.PARAMETER, - ) - res = _aspect_ospathnormcase(tainted_slash) - assert res == "/" - assert get_tainted_ranges(res) == [TaintRange(0, 1, Source("test_ospath", "/", OriginType.PARAMETER))] - - -def test_ospathnormcase_nottainted_empty(): - res = _aspect_ospathnormcase("") - assert res == "" - assert not get_tainted_ranges(res) - - -def test_ospathdirname_tainted_normal(): - tainted_foobarbaz = taint_pyobject( - pyobject="/foo/bar/baz", - source_name="test_ospath", - source_value="/foo/bar/baz", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathdirname(tainted_foobarbaz) - assert res == "/foo/bar" - assert get_tainted_ranges(res) == [TaintRange(0, 8, Source("test_ospath", "/foo/bar/baz", OriginType.PARAMETER))] - - -def test_ospathdirname_tainted_empty(): - tainted_empty = taint_pyobject( - pyobject="", - source_name="test_ospath", - source_value="", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathdirname(tainted_empty) - assert res == "" - assert not get_tainted_ranges(res) - - -def test_ospathdirname_nottainted(): - res = _aspect_ospathdirname("/foo/bar/baz") - assert res == "/foo/bar" - assert not get_tainted_ranges(res) - - -def test_ospathdirname_wrong_arg(): - with pytest.raises(TypeError): - _ = _aspect_ospathdirname(42) - - -def test_ospathdirname_bytes_tainted(): - tainted_foobarbaz = taint_pyobject( - pyobject=b"/foo/bar/baz", - source_name="test_ospath", - source_value=b"/foo/bar/baz", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathdirname(tainted_foobarbaz) - assert res == b"/foo/bar" - assert get_tainted_ranges(res) == [TaintRange(0, 8, Source("test_ospath", b"/foo/bar/baz", OriginType.PARAMETER))] - - -def test_ospathdirname_bytes_nottainted(): - res = _aspect_ospathdirname(b"/foo/bar/baz") - assert res == b"/foo/bar" - assert not get_tainted_ranges(res) - - -def test_ospathdirname_single_slash_tainted(): - tainted_slash = taint_pyobject( - pyobject="/", - source_name="test_ospath", - source_value="/", - source_origin=OriginType.PARAMETER, - ) - res = _aspect_ospathdirname(tainted_slash) - assert res == "/" - assert get_tainted_ranges(res) == [TaintRange(0, 1, Source("test_ospath", "/", OriginType.PARAMETER))] - - -def test_ospathdirname_nottainted_empty(): - res = _aspect_ospathdirname("") - assert res == "" - assert not get_tainted_ranges(res) - - -def test_ospathsplit_tainted_normal(): - tainted_foobarbaz = taint_pyobject( - pyobject="/foo/bar/baz", - source_name="test_ospath", - source_value="/foo/bar/baz", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathsplit(tainted_foobarbaz) - assert res == ("/foo/bar", "baz") - assert get_tainted_ranges(res[0]) == [TaintRange(0, 8, Source("test_ospath", "/foo/bar/baz", OriginType.PARAMETER))] - assert get_tainted_ranges(res[1]) == [TaintRange(0, 3, Source("test_ospath", "/foo/bar/baz", OriginType.PARAMETER))] - - -def test_ospathsplit_tainted_empty(): - tainted_empty = taint_pyobject( - pyobject="", - source_name="test_ospath", - source_value="", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathsplit(tainted_empty) - assert res == ("", "") - assert not get_tainted_ranges(res[0]) - assert not get_tainted_ranges(res[1]) - - -def test_ospathsplit_nottainted(): - res = _aspect_ospathsplit("/foo/bar/baz") - assert res == ("/foo/bar", "baz") - assert not get_tainted_ranges(res[0]) - assert not get_tainted_ranges(res[1]) - - -def test_ospathsplit_wrong_arg(): - with pytest.raises(TypeError): - _ = _aspect_ospathsplit(42) - - -def test_ospathsplit_bytes_tainted(): - tainted_foobarbaz = taint_pyobject( - pyobject=b"/foo/bar/baz", - source_name="test_ospath", - source_value=b"/foo/bar/baz", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathsplit(tainted_foobarbaz) - assert res == (b"/foo/bar", b"baz") - assert get_tainted_ranges(res[0]) == [ - TaintRange(0, 8, Source("test_ospath", b"/foo/bar/baz", OriginType.PARAMETER)) - ] - assert get_tainted_ranges(res[1]) == [ - TaintRange(0, 3, Source("test_ospath", b"/foo/bar/baz", OriginType.PARAMETER)) - ] - - -def test_ospathsplit_bytes_nottainted(): - res = _aspect_ospathsplit(b"/foo/bar/baz") - assert res == (b"/foo/bar", b"baz") - assert not get_tainted_ranges(res[0]) - assert not get_tainted_ranges(res[1]) - - -def test_ospathsplit_single_slash_tainted(): - tainted_slash = taint_pyobject( - pyobject="/", - source_name="test_ospath", - source_value="/", - source_origin=OriginType.PARAMETER, - ) - res = _aspect_ospathsplit(tainted_slash) - assert res == ("/", "") - assert get_tainted_ranges(res[0]) == [TaintRange(0, 1, Source("test_ospath", "/", OriginType.PARAMETER))] - assert not get_tainted_ranges(res[1]) - - -def test_ospathsplit_nottainted_empty(): - res = _aspect_ospathsplit("") - assert res == ("", "") - assert not get_tainted_ranges(res[0]) - assert not get_tainted_ranges(res[1]) - - -def test_ospathsplitext_tainted_normal(): - tainted_foobarbaz = taint_pyobject( - pyobject="/foo/bar/baz.jpg", - source_name="test_ospath", - source_value="/foo/bar/baz.jpg", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathsplitext(tainted_foobarbaz) - assert res == ("/foo/bar/baz", ".jpg") - assert get_tainted_ranges(res[0]) == [ - TaintRange(0, 12, Source("test_ospath", "/foo/bar/baz.jpg", OriginType.PARAMETER)) - ] - assert get_tainted_ranges(res[1]) == [ - TaintRange(0, 4, Source("test_ospath", "/foo/bar/baz.jpg", OriginType.PARAMETER)) - ] - - -@pytest.mark.skipif(sys.version_info < (3, 12), reason="Requires Python 3.12") -def test_ospathsplitroot_tainted_normal(): - tainted_foobarbaz = taint_pyobject( - pyobject="/foo/bar/baz", - source_name="test_ospath", - source_value="/foo/bar/baz", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathsplitroot(tainted_foobarbaz) - assert res == ("", "/", "foo/bar/baz") - assert not get_tainted_ranges(res[0]) - assert get_tainted_ranges(res[1]) == [TaintRange(0, 1, Source("test_ospath", "/foo/bar/baz", OriginType.PARAMETER))] - assert get_tainted_ranges(res[2]) == [ - TaintRange(0, 11, Source("test_ospath", "/foo/bar/baz", OriginType.PARAMETER)) - ] - - -@pytest.mark.skipif(sys.version_info < (3, 12), reason="Requires Python 3.12") -def test_ospathsplitroot_tainted_doble_initial_slash(): - tainted_foobarbaz = taint_pyobject( - pyobject="//foo/bar/baz", - source_name="test_ospath", - source_value="//foo/bar/baz", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathsplitroot(tainted_foobarbaz) - assert res == ("", "//", "foo/bar/baz") - assert not get_tainted_ranges(res[0]) - assert get_tainted_ranges(res[1]) == [ - TaintRange(0, 2, Source("test_ospath", "//foo/bar/baz", OriginType.PARAMETER)) - ] - assert get_tainted_ranges(res[2]) == [ - TaintRange(0, 11, Source("test_ospath", "//foo/bar/baz", OriginType.PARAMETER)) - ] - - -@pytest.mark.skipif(sys.version_info < (3, 12), reason="Requires Python 3.12") -def test_ospathsplitroot_tainted_triple_initial_slash(): - tainted_foobarbaz = taint_pyobject( - pyobject="///foo/bar/baz", - source_name="test_ospath", - source_value="///foo/bar/baz", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathsplitroot(tainted_foobarbaz) - assert res == ("", "/", "//foo/bar/baz") - assert not get_tainted_ranges(res[0]) - assert get_tainted_ranges(res[1]) == [ - TaintRange(0, 1, Source("test_ospath", "///foo/bar/baz", OriginType.PARAMETER)) - ] - assert get_tainted_ranges(res[2]) == [ - TaintRange(0, 13, Source("test_ospath", "///foo/bar/baz", OriginType.PARAMETER)) - ] - - -@pytest.mark.skipif(sys.version_info < (3, 12), reason="Requires Python 3.12") -def test_ospathsplitroot_tainted_empty(): - tainted_empty = taint_pyobject( - pyobject="", - source_name="test_ospath", - source_value="", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathsplitroot(tainted_empty) - assert res == ("", "", "") - for i in res: - assert not get_tainted_ranges(i) - - -@pytest.mark.skipif(sys.version_info < (3, 12), reason="Requires Python 3.12") -def test_ospathsplitroot_nottainted(): - res = _aspect_ospathsplitroot("/foo/bar/baz") - assert res == ("", "/", "foo/bar/baz") - for i in res: - assert not get_tainted_ranges(i) - - -@pytest.mark.skipif(sys.version_info < (3, 12), reason="Requires Python 3.12") -def test_ospathsplitroot_wrong_arg(): - with pytest.raises(TypeError): - _ = _aspect_ospathsplitroot(42) - - -@pytest.mark.skipif(sys.version_info < (3, 12), reason="Requires Python 3.12") -def test_ospathsplitroot_bytes_tainted(): - tainted_foobarbaz = taint_pyobject( - pyobject=b"/foo/bar/baz", - source_name="test_ospath", - source_value=b"/foo/bar/baz", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathsplitroot(tainted_foobarbaz) - assert res == (b"", b"/", b"foo/bar/baz") - assert not get_tainted_ranges(res[0]) - assert get_tainted_ranges(res[1]) == [ - TaintRange(0, 1, Source("test_ospath", b"/foo/bar/baz", OriginType.PARAMETER)) - ] - assert get_tainted_ranges(res[2]) == [ - TaintRange(0, 11, Source("test_ospath", b"/foo/bar/baz", OriginType.PARAMETER)) - ] - - -@pytest.mark.skipif(sys.version_info < (3, 12), reason="Requires Python 3.12") -def test_ospathsplitroot_bytes_nottainted(): - res = _aspect_ospathsplitroot(b"/foo/bar/baz") - assert res == (b"", b"/", b"foo/bar/baz") - for i in res: - assert not get_tainted_ranges(i) - - -@pytest.mark.skipif(sys.version_info < (3, 12), reason="Requires Python 3.12") -def tets_ospathsplitroot_single_slash_tainted(): - tainted_slash = taint_pyobject( - pyobject="/", - source_name="test_ospath", - source_value="/", - source_origin=OriginType.PARAMETER, - ) - res = _aspect_ospathsplitroot(tainted_slash) - assert res == ("", "/", "") - assert not get_tainted_ranges(res[0]) - assert get_tainted_ranges(res[1]) == [TaintRange(0, 1, Source("test_ospath", "/", OriginType.PARAMETER))] - assert not get_tainted_ranges(res[2]) - - -@pytest.mark.skipif(sys.version_info < (3, 12) and os.name != "nt", reason="Requires Python 3.12 or Windows") -def test_ospathsplitdrive_tainted_normal(): - tainted_foobarbaz = taint_pyobject( - pyobject="/foo/bar/baz", - source_name="test_ospath", - source_value="/foo/bar/baz", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathsplitdrive(tainted_foobarbaz) - assert res == ("", "/foo/bar/baz") - assert not get_tainted_ranges(res[0]) - assert get_tainted_ranges(res[1]) == [ - TaintRange(0, 12, Source("test_ospath", "/foo/bar/baz", OriginType.PARAMETER)) - ] - - -@pytest.mark.skipif(sys.version_info < (3, 12) and os.name != "nt", reason="Requires Python 3.12 or Windows") -def test_ospathsplitdrive_tainted_empty(): - tainted_empty = taint_pyobject( - pyobject="", - source_name="test_ospath", - source_value="", - source_origin=OriginType.PARAMETER, - ) - - res = _aspect_ospathsplitdrive(tainted_empty) - assert res == ("", "") - for i in res: - assert not get_tainted_ranges(i) - - -# TODO: add tests for ospathsplitdrive with different drive letters that must run -# under Windows since they're noop under posix diff --git a/tests/appsec/iast/aspects/test_ospath_aspects_fixtures.py b/tests/appsec/iast/aspects/test_ospath_aspects_fixtures.py deleted file mode 100644 index 8a10c996b2..0000000000 --- a/tests/appsec/iast/aspects/test_ospath_aspects_fixtures.py +++ /dev/null @@ -1,113 +0,0 @@ -import os -import sys - -import pytest - -from ddtrace.appsec._iast._taint_tracking import OriginType -from ddtrace.appsec._iast._taint_tracking import Source -from ddtrace.appsec._iast._taint_tracking import TaintRange -from ddtrace.appsec._iast._taint_tracking import get_tainted_ranges -from ddtrace.appsec._iast._taint_tracking import taint_pyobject -from tests.appsec.iast.aspects.conftest import _iast_patched_module - - -mod = _iast_patched_module("tests.appsec.iast.fixtures.aspects.module_functions") - - -def test_ospathjoin_tainted(): - string_input = taint_pyobject( - pyobject="foo", source_name="first_element", source_value="foo", source_origin=OriginType.PARAMETER - ) - result = mod.do_os_path_join(string_input, "bar") - assert result == "foo/bar" - assert get_tainted_ranges(result) == [TaintRange(0, 3, Source("first_element", "foo", OriginType.PARAMETER))] - - -def test_ospathnormcase_tainted(): - string_input = taint_pyobject( - pyobject="/foo/bar", source_name="first_element", source_value="/foo/bar", source_origin=OriginType.PARAMETER - ) - result = mod.do_os_path_normcase(string_input) - assert result == "/foo/bar" - assert get_tainted_ranges(result) == [TaintRange(0, 8, Source("first_element", "/foo/bar", OriginType.PARAMETER))] - - -def test_ospathbasename_tainted(): - string_input = taint_pyobject( - pyobject="/foo/bar", source_name="first_element", source_value="/foo/bar", source_origin=OriginType.PARAMETER - ) - result = mod.do_os_path_basename(string_input) - assert result == "bar" - assert get_tainted_ranges(result) == [TaintRange(0, 3, Source("first_element", "/foo/bar", OriginType.PARAMETER))] - - -def test_ospathdirname_tainted(): - string_input = taint_pyobject( - pyobject="/foo/bar", source_name="first_element", source_value="/foo/bar", source_origin=OriginType.PARAMETER - ) - result = mod.do_os_path_dirname(string_input) - assert result == "/foo" - assert get_tainted_ranges(result) == [TaintRange(0, 4, Source("first_element", "/foo/bar", OriginType.PARAMETER))] - - -def test_ospathsplit_tainted(): - string_input = taint_pyobject( - pyobject="/foo/bar", source_name="first_element", source_value="/foo/bar", source_origin=OriginType.PARAMETER - ) - result = mod.do_os_path_split(string_input) - assert result == ("/foo", "bar") - assert get_tainted_ranges(result[0]) == [ - TaintRange(0, 4, Source("first_element", "/foo/bar", OriginType.PARAMETER)) - ] - assert get_tainted_ranges(result[1]) == [ - TaintRange(0, 3, Source("first_element", "/foo/bar", OriginType.PARAMETER)) - ] - - -def test_ospathsplitext_tainted(): - string_input = taint_pyobject( - pyobject="/foo/bar.txt", - source_name="first_element", - source_value="/foo/bar.txt", - source_origin=OriginType.PARAMETER, - ) - result = mod.do_os_path_splitext(string_input) - assert result == ("/foo/bar", ".txt") - assert get_tainted_ranges(result[0]) == [ - TaintRange(0, 8, Source("first_element", "/foo/bar.txt", OriginType.PARAMETER)) - ] - assert get_tainted_ranges(result[1]) == [ - TaintRange(0, 4, Source("first_element", "/foo/bar.txt", OriginType.PARAMETER)) - ] - - -@pytest.mark.skipif(sys.version_info < (3, 12), reason="requires python3.12 or higher") -def test_ospathsplitroot_tainted(): - string_input = taint_pyobject( - pyobject="/foo/bar", source_name="first_element", source_value="/foo/bar", source_origin=OriginType.PARAMETER - ) - result = mod.do_os_path_splitroot(string_input) - assert result == ("", "/", "foo/bar") - assert not get_tainted_ranges(result[0]) - assert get_tainted_ranges(result[1]) == [ - TaintRange(0, 1, Source("first_element", "/foo/bar", OriginType.PARAMETER)) - ] - assert get_tainted_ranges(result[2]) == [ - TaintRange(0, 7, Source("first_element", "/foo/bar", OriginType.PARAMETER)) - ] - - -@pytest.mark.skipif(sys.version_info < (3, 12) and os.name != "nt", reason="Required Python 3.12 or Windows") -def test_ospathsplitdrive_tainted(): - string_input = taint_pyobject( - pyobject="/foo/bar", source_name="first_element", source_value="/foo/bar", source_origin=OriginType.PARAMETER - ) - result = mod.do_os_path_splitdrive(string_input) - assert result == ("", "/foo/bar") - assert not get_tainted_ranges(result[0]) - assert get_tainted_ranges(result[1]) == [ - TaintRange(0, 8, Source("first_element", "/foo/bar", OriginType.PARAMETER)) - ] - - -# TODO: add tests for os.path.splitdrive and os.path.normcase under Windows diff --git a/tests/appsec/iast/aspects/test_split_aspect.py b/tests/appsec/iast/aspects/test_split_aspect.py deleted file mode 100644 index f7c9ec197e..0000000000 --- a/tests/appsec/iast/aspects/test_split_aspect.py +++ /dev/null @@ -1,145 +0,0 @@ -from ddtrace.appsec._iast._taint_tracking import TaintRange -from ddtrace.appsec._iast._taint_tracking import _aspect_rsplit -from ddtrace.appsec._iast._taint_tracking import _aspect_split -from ddtrace.appsec._iast._taint_tracking import _aspect_splitlines -from ddtrace.appsec._iast._taint_tracking._native.taint_tracking import OriginType -from ddtrace.appsec._iast._taint_tracking._native.taint_tracking import Source -from ddtrace.appsec._iast._taint_tracking._native.taint_tracking import get_ranges -from ddtrace.appsec._iast._taint_tracking._native.taint_tracking import set_ranges -from tests.appsec.iast.aspects.test_aspect_helpers import _build_sample_range - - -# These tests are simple ones testing the calls and replacements since most of the -# actual testing is in test_aspect_helpers' test for set_ranges_on_splitted which these -# functions call internally. -def test_aspect_split_simple(): - s = "abc def" - range1 = _build_sample_range(0, 3, "abc") - range2 = _build_sample_range(3, 4, " def") - set_ranges(s, (range1, range2)) - ranges = get_ranges(s) - assert ranges - res = _aspect_split(s) - assert res == ["abc", "def"] - assert get_ranges(res[0]) == [range1] - assert get_ranges(res[1]) == [TaintRange(0, 3, Source(" def", "sample_value", OriginType.PARAMETER))] - - -def test_aspect_rsplit_simple(): - s = "abc def" - range1 = _build_sample_range(0, 3, "abc") - range2 = _build_sample_range(3, 4, " def") - set_ranges(s, (range1, range2)) - ranges = get_ranges(s) - assert ranges - res = _aspect_rsplit(s) - assert res == ["abc", "def"] - assert get_ranges(res[0]) == [range1] - assert get_ranges(res[1]) == [TaintRange(0, 3, Source(" def", "sample_value", OriginType.PARAMETER))] - - -def test_aspect_split_with_separator(): - s = "abc:def" - range1 = _build_sample_range(0, 3, "abc") - range2 = _build_sample_range(3, 4, ":def") - set_ranges(s, (range1, range2)) - ranges = get_ranges(s) - assert ranges - res = _aspect_split(s, ":") - assert res == ["abc", "def"] - assert get_ranges(res[0]) == [range1] - assert get_ranges(res[1]) == [TaintRange(0, 3, Source(":def", "sample_value", OriginType.PARAMETER))] - - -def test_aspect_rsplit_with_separator(): - s = "abc:def" - range1 = _build_sample_range(0, 3, "abc") - range2 = _build_sample_range(3, 4, ":def") - set_ranges(s, (range1, range2)) - ranges = get_ranges(s) - assert ranges - res = _aspect_rsplit(s, ":") - assert res == ["abc", "def"] - assert get_ranges(res[0]) == [range1] - assert get_ranges(res[1]) == [TaintRange(0, 3, Source(":def", "sample_value", OriginType.PARAMETER))] - - -def test_aspect_split_with_maxsplit(): - s = "abc def ghi" - range1 = _build_sample_range(0, 3, "abc") - range2 = _build_sample_range(3, 4, " def") - range3 = _build_sample_range(7, 4, " ghi") - set_ranges(s, (range1, range2, range3)) - ranges = get_ranges(s) - assert ranges - res = _aspect_split(s, maxsplit=1) - assert res == ["abc", "def ghi"] - assert get_ranges(res[0]) == [range1] - assert get_ranges(res[1]) == [ - TaintRange(0, 3, Source(" def", "sample_value", OriginType.PARAMETER)), - TaintRange(3, 4, Source(" ghi", "sample_value", OriginType.PARAMETER)), - ] - - res = _aspect_split(s, maxsplit=2) - assert res == ["abc", "def", "ghi"] - assert get_ranges(res[0]) == [range1] - assert get_ranges(res[1]) == [TaintRange(0, 3, Source(" def", "sample_value", OriginType.PARAMETER))] - assert get_ranges(res[2]) == [TaintRange(0, 3, Source(" ghi", "sample_value", OriginType.PARAMETER))] - - res = _aspect_split(s, maxsplit=0) - assert res == ["abc def ghi"] - assert get_ranges(res[0]) == [range1, range2, range3] - - -def test_aspect_rsplit_with_maxsplit(): - s = "abc def ghi" - range1 = _build_sample_range(0, 3, "abc") - range2 = _build_sample_range(3, 4, " def") - range3 = _build_sample_range(7, 4, " ghi") - set_ranges(s, (range1, range2, range3)) - ranges = get_ranges(s) - assert ranges - res = _aspect_rsplit(s, maxsplit=1) - assert res == ["abc def", "ghi"] - assert get_ranges(res[0]) == [ - range1, - TaintRange(3, 4, Source(" def", "sample_value", OriginType.PARAMETER)), - ] - assert get_ranges(res[1]) == [TaintRange(0, 3, Source(" ghi", "sample_value", OriginType.PARAMETER))] - res = _aspect_rsplit(s, maxsplit=2) - assert res == ["abc", "def", "ghi"] - assert get_ranges(res[0]) == [range1] - assert get_ranges(res[1]) == [TaintRange(0, 3, Source(" def", "sample_value", OriginType.PARAMETER))] - assert get_ranges(res[2]) == [TaintRange(0, 3, Source(" ghi", "sample_value", OriginType.PARAMETER))] - - res = _aspect_rsplit(s, maxsplit=0) - assert res == ["abc def ghi"] - assert get_ranges(res[0]) == [range1, range2, range3] - - -def test_aspect_splitlines_simple(): - s = "abc\ndef" - range1 = _build_sample_range(0, 3, "abc") - range2 = _build_sample_range(3, 4, " def") - set_ranges(s, (range1, range2)) - ranges = get_ranges(s) - assert ranges - res = _aspect_splitlines(s) - assert res == ["abc", "def"] - assert get_ranges(res[0]) == [range1] - assert get_ranges(res[1]) == [TaintRange(0, 3, Source(" def", "sample_value", OriginType.PARAMETER))] - - -def test_aspect_splitlines_keepend_true(): - s = "abc\ndef\nhij\n" - range1 = _build_sample_range(0, 4, "abc\n") - range2 = _build_sample_range(4, 4, "def\n") - range3 = _build_sample_range(8, 4, "hij\n") - set_ranges(s, (range1, range2, range3)) - ranges = get_ranges(s) - assert ranges - res = _aspect_splitlines(s, True) - assert res == ["abc\n", "def\n", "hij\n"] - assert get_ranges(res[0]) == [range1] - assert get_ranges(res[1]) == [TaintRange(0, 4, Source("def\n", "sample_value", OriginType.PARAMETER))] - assert get_ranges(res[2]) == [TaintRange(0, 4, Source("hij\n", "sample_value", OriginType.PARAMETER))] diff --git a/tests/appsec/iast/aspects/test_str_aspect.py b/tests/appsec/iast/aspects/test_str_aspect.py index 5666fb97ba..5140bb1fe4 100644 --- a/tests/appsec/iast/aspects/test_str_aspect.py +++ b/tests/appsec/iast/aspects/test_str_aspect.py @@ -4,10 +4,7 @@ from ddtrace.appsec._iast import oce from ddtrace.appsec._iast._taint_tracking import OriginType -from ddtrace.appsec._iast._taint_tracking import Source -from ddtrace.appsec._iast._taint_tracking import TaintRange from ddtrace.appsec._iast._taint_tracking import as_formatted_evidence -from ddtrace.appsec._iast._taint_tracking import get_tainted_ranges from ddtrace.appsec._iast._taint_tracking import is_pyobject_tainted from ddtrace.appsec._iast._taint_tracking import taint_pyobject import ddtrace.appsec._iast._taint_tracking.aspects as ddtrace_aspects @@ -374,145 +371,6 @@ def test_repr_aspect_tainting(obj, expected_result, formatted_result): _iast_error_metric.assert_not_called() -def test_split_tainted_noargs(): - result = mod.do_split_no_args("abc def ghi") - assert result == ["abc", "def", "ghi"] - for substr in result: - assert not get_tainted_ranges(substr) - - s_tainted = taint_pyobject( - pyobject="abc def ghi", - source_name="test_split_tainted", - source_value="abc def ghi", - source_origin=OriginType.PARAMETER, - ) - assert get_tainted_ranges(s_tainted) - - result2 = mod.do_split_no_args(s_tainted) - assert result2 == ["abc", "def", "ghi"] - for substr in result2: - assert get_tainted_ranges(substr) == [ - TaintRange(0, 3, Source("test_split_tainted", "abc", OriginType.PARAMETER)), - ] - - -@pytest.mark.parametrize( - "s, call, _args, should_be_tainted, result_list, result_tainted_list", - [ - ("abc def", mod.do_split_no_args, [], True, ["abc", "def"], [(0, 3), (0, 3)]), - (b"abc def", mod.do_split_no_args, [], True, [b"abc", b"def"], [(0, 3), (0, 3)]), - ( - bytearray(b"abc def"), - mod.do_split_no_args, - [], - True, - [bytearray(b"abc"), bytearray(b"def")], - [(0, 3), (0, 3)], - ), - ("abc def", mod.do_rsplit_no_args, [], True, ["abc", "def"], [(0, 3), (0, 3)]), - (b"abc def", mod.do_rsplit_no_args, [], True, [b"abc", b"def"], [(0, 3), (0, 3)]), - ( - bytearray(b"abc def"), - mod.do_rsplit_no_args, - [], - True, - [bytearray(b"abc"), bytearray(b"def")], - [(0, 3), (0, 3)], - ), - ("abc def", mod.do_split_no_args, [], False, ["abc", "def"], []), - ("abc def", mod.do_rsplit_no_args, [], False, ["abc", "def"], []), - (b"abc def", mod.do_rsplit_no_args, [], False, [b"abc", b"def"], []), - ("abc def hij", mod.do_split_no_args, [], True, ["abc", "def", "hij"], [(0, 3), (0, 3), (0, 3)]), - (b"abc def hij", mod.do_split_no_args, [], True, [b"abc", b"def", b"hij"], [(0, 3), (0, 3), (0, 3)]), - ("abc def hij", mod.do_rsplit_no_args, [], True, ["abc", "def", "hij"], [(0, 3), (0, 3), (0, 3)]), - (b"abc def hij", mod.do_rsplit_no_args, [], True, [b"abc", b"def", b"hij"], [(0, 3), (0, 3), (0, 3)]), - ("abc def hij", mod.do_split_no_args, [], False, ["abc", "def", "hij"], []), - (b"abc def hij", mod.do_split_no_args, [], False, [b"abc", b"def", b"hij"], []), - ("abc def hij", mod.do_rsplit_no_args, [], False, ["abc", "def", "hij"], []), - (b"abc def hij", mod.do_rsplit_no_args, [], False, [b"abc", b"def", b"hij"], []), - ( - bytearray(b"abc def hij"), - mod.do_rsplit_no_args, - [], - False, - [bytearray(b"abc"), bytearray(b"def"), bytearray(b"hij")], - [], - ), - ("abc def hij", mod.do_split_maxsplit, [1], True, ["abc", "def hij"], [(0, 3), (0, 7)]), - ("abc def hij", mod.do_rsplit_maxsplit, [1], True, ["abc def", "hij"], [(0, 7), (0, 3)]), - ("abc def hij", mod.do_split_maxsplit, [1], False, ["abc", "def hij"], []), - ("abc def hij", mod.do_rsplit_maxsplit, [1], False, ["abc def", "hij"], []), - ("abc def hij", mod.do_split_maxsplit, [2], True, ["abc", "def", "hij"], [(0, 3), (0, 3), (0, 3)]), - ("abc def hij", mod.do_rsplit_maxsplit, [2], True, ["abc", "def", "hij"], [(0, 3), (0, 3), (0, 3)]), - ("abc def hij", mod.do_split_maxsplit, [2], False, ["abc", "def", "hij"], []), - ("abc def hij", mod.do_rsplit_maxsplit, [2], False, ["abc", "def", "hij"], []), - ("abc|def|hij", mod.do_split_separator, ["|"], True, ["abc", "def", "hij"], [(0, 3), (0, 3), (0, 3)]), - ("abc|def|hij", mod.do_rsplit_separator, ["|"], True, ["abc", "def", "hij"], [(0, 3), (0, 3), (0, 3)]), - ("abc|def|hij", mod.do_split_separator, ["|"], False, ["abc", "def", "hij"], []), - ("abc|def|hij", mod.do_rsplit_separator, ["|"], False, ["abc", "def", "hij"], []), - ("abc|def hij", mod.do_split_separator, ["|"], True, ["abc", "def hij"], [(0, 3), (0, 7)]), - ("abc|def hij", mod.do_rsplit_separator, ["|"], True, ["abc", "def hij"], [(0, 3), (0, 7)]), - ("abc|def hij", mod.do_split_separator, ["|"], False, ["abc", "def hij"], []), - ("abc|def hij", mod.do_rsplit_separator, ["|"], False, ["abc", "def hij"], []), - ("abc|def|hij", mod.do_split_separator_and_maxsplit, ["|", 1], True, ["abc", "def|hij"], [(0, 3), (0, 7)]), - ("abc|def|hij", mod.do_rsplit_separator_and_maxsplit, ["|", 1], True, ["abc|def", "hij"], [(0, 7), (0, 3)]), - ("abc|def|hij", mod.do_split_separator_and_maxsplit, ["|", 1], False, ["abc", "def|hij"], []), - ("abc|def|hij", mod.do_rsplit_separator_and_maxsplit, ["|", 1], False, ["abc|def", "hij"], []), - ("abc\ndef\nhij", mod.do_splitlines_no_arg, [], True, ["abc", "def", "hij"], [(0, 3), (0, 3), (0, 3)]), - (b"abc\ndef\nhij", mod.do_splitlines_no_arg, [], True, [b"abc", b"def", b"hij"], [(0, 3), (0, 3), (0, 3)]), - ( - bytearray(b"abc\ndef\nhij"), - mod.do_splitlines_no_arg, - [], - True, - [bytearray(b"abc"), bytearray(b"def"), bytearray(b"hij")], - [(0, 3), (0, 3), (0, 3)], - ), - ( - "abc\ndef\nhij\n", - mod.do_splitlines_keepends, - [True], - True, - ["abc\n", "def\n", "hij\n"], - [(0, 4), (0, 4), (0, 4)], - ), - ( - b"abc\ndef\nhij\n", - mod.do_splitlines_keepends, - [True], - True, - [b"abc\n", b"def\n", b"hij\n"], - [(0, 4), (0, 4), (0, 4)], - ), - ( - bytearray(b"abc\ndef\nhij\n"), - mod.do_splitlines_keepends, - [True], - True, - [bytearray(b"abc\n"), bytearray(b"def\n"), bytearray(b"hij\n")], - [(0, 4), (0, 4), (0, 4)], - ), - ], -) -def test_split_aspect_tainting(s, call, _args, should_be_tainted, result_list, result_tainted_list): - _test_name = "test_split_aspect_tainting" - if should_be_tainted: - obj = taint_pyobject( - s, source_name="test_split_aspect_tainting", source_value=s, source_origin=OriginType.PARAMETER - ) - else: - obj = s - - result = call(obj, *_args) - assert result == result_list - for idx, result_range in enumerate(result_tainted_list): - result_item = result[idx] - assert is_pyobject_tainted(result_item) == should_be_tainted - if should_be_tainted: - _range = get_tainted_ranges(result_item)[0] - assert _range == TaintRange(result_range[0], result_range[1], Source(_test_name, obj, OriginType.PARAMETER)) - - class TestOperatorsReplacement(BaseReplacement): def test_aspect_ljust_str_tainted(self): # type: () -> None diff --git a/tests/appsec/iast/fixtures/aspects/module_functions.py b/tests/appsec/iast/fixtures/aspects/module_functions.py deleted file mode 100644 index a50bd059d2..0000000000 --- a/tests/appsec/iast/fixtures/aspects/module_functions.py +++ /dev/null @@ -1,33 +0,0 @@ -import os.path - - -def do_os_path_join(a, b): - return os.path.join(a, b) - - -def do_os_path_normcase(a): - return os.path.normcase(a) - - -def do_os_path_basename(a): - return os.path.basename(a) - - -def do_os_path_dirname(a): - return os.path.dirname(a) - - -def do_os_path_splitdrive(a): - return os.path.splitdrive(a) - - -def do_os_path_splitroot(a): - return os.path.splitroot(a) - - -def do_os_path_split(a): - return os.path.split(a) - - -def do_os_path_splitext(a): - return os.path.splitext(a) diff --git a/tests/appsec/iast/fixtures/aspects/str_methods.py b/tests/appsec/iast/fixtures/aspects/str_methods.py index dd748b732c..eff192d710 100644 --- a/tests/appsec/iast/fixtures/aspects/str_methods.py +++ b/tests/appsec/iast/fixtures/aspects/str_methods.py @@ -473,13 +473,11 @@ def django_check(all_issues, display_num_errors=False): if visible_issue_count: footer += "\n" footer += "System check identified %s (%s silenced)." % ( - ( - "no issues" - if visible_issue_count == 0 - else "1 issue" - if visible_issue_count == 1 - else "%s issues" % visible_issue_count - ), + "no issues" + if visible_issue_count == 0 + else "1 issue" + if visible_issue_count == 1 + else "%s issues" % visible_issue_count, len(all_issues) - visible_issue_count, ) @@ -515,13 +513,11 @@ def django_check_simple_formatted_ifs(f): def django_check_simple_formatted_multiple_ifs(f): visible_issue_count = 1 f += "System check identified %s (%s silenced)." % ( - ( - "no issues" - if visible_issue_count == 0 - else "1 issue" - if visible_issue_count == 1 - else "%s issues" % visible_issue_count - ), + "no issues" + if visible_issue_count == 0 + else "1 issue" + if visible_issue_count == 1 + else "%s issues" % visible_issue_count, 5 - visible_issue_count, ) return f @@ -1004,38 +1000,15 @@ def do_rsplit_no_args(s): # type: (str) -> List[str] return s.rsplit() -def do_split_maxsplit(s, maxsplit=-1): # type: (str, int) -> List[str] - return s.split(maxsplit=maxsplit) - - -def do_rsplit_maxsplit(s, maxsplit=-1): # type: (str, int) -> List[str] - return s.rsplit(maxsplit=maxsplit) +def do_split(s, sep, maxsplit=-1): # type: (str, str, int) -> List[str] + return s.split(sep, maxsplit) -def do_split_separator(s, separator): # type: (str, str) -> List[str] - return s.split(separator) - - -def do_rsplit_separator(s, separator): # type: (str, str) -> List[str] - return s.rsplit(separator) - - -def do_split_separator_and_maxsplit(s, separator, maxsplit): # type: (str, str, int) -> List[str] - return s.split(separator, maxsplit) - - -def do_rsplit_separator_and_maxsplit(s, separator, maxsplit): # type: (str, str, int) -> List[str] - return s.rsplit(separator, maxsplit) - - -def do_splitlines_no_arg(s): # type: (str) -> List[str] +# foosep is just needed so it has the signature expected by _test_somesplit_impl +def do_splitlines(s, foosep): # type: (str, str) -> List[str] return s.splitlines() -def do_splitlines_keepends(s, keepends): # type: (str, bool) -> List[str] - return s.splitlines(keepends=keepends) - - def do_partition(s, sep): # type: (str, str) -> Tuple[str, str, str] return s.partition(sep)