List indices must be integers or slices in find_and_replace_dependent_values()

Open Beginner friendly
#1,829 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@vishalmore90 is already working on this.

Since Nov 2, 2026.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python
Domain
backend, security

Research direction

Start with find_and_replace_dependent_values() in nettacker/core/lib/base.py and the existing tests in tests/core/lib/test_base.py; the issue also requests coverage in tests/unit/test_base.py. Reproduce the failure with the Log4j module or add focused cases for lists of dictionaries and strings containing dependent tokens. Done when list items are traversed with valid indices, substitutions work, and the tests pass.

Written by the indexing model from the issue text.

Description

Description

In nettacker/core/lib/base.py, the find_and_replace_dependent_values() method resolves values from temporary events (such as generated tokens or session IDs) and substitutes them into subsequent module steps.

When handling dictionary inputs (if isinstance(sub_step, dict):), the function iterates over dictionary keys. However, in the branch handling list inputs (if isinstance(sub_step, list):, lines 83–106), it iterates over the list elements using for key in copy.deepcopy(sub_step):. Because sub_step is a list, key represents an item of the list (e.g., a dict or a str), not an integer index:

83:         if isinstance(sub_step, list):
84:             value_index = 0
85:             for key in copy.deepcopy(sub_step):
86:                 if type(sub_step[value_index]) not in [str, float, int, bytes]:
87:                     sub_step[key] = self.find_and_replace_dependent_values(
88:                         copy.deepcopy(sub_step[value_index]), dependent_on_temp_event
89:                     )
90:                 else:
91:                     if isinstance(sub_step[value_index], str):
92:                         if "dependent_on_temp_event" in sub_step[value_index]:
93:                             globals().update(locals())
94:                             generate_new_step = copy.deepcopy(sub_step[key])
95:                             key_name = re.findall(
96:                                 re.compile("dependent_on_temp_event\\['\\S+\\]\\[\\S+\\]"),
97:                                 generate_new_step,
98:                             )[0]
99:                             try:
100:                                 key_value = eval(key_name)
101:                             except Exception:
102:                                 key_value = "error"
103:                             sub_step[value_index] = sub_step[value_index].replace(
104:                                 key_name, key_value
105:                             )
106:                 value_index += 1

This implementation contains three distinct flaws:

  1. TypeError on complex list items (line 87):
    When sub_step is a list of dictionaries (such as HTTP headers: [...] in nettacker/modules/vuln/log4j_cve_2021_44228.yaml), key is a dict. Line 87 attempts sub_step[key] = ..., raising:
    TypeError: list indices must be integers or slices, not dict
    
  2. TypeError on string list items (line 94):
    When sub_step is a list of strings containing dependent tokens, key is a str. Line 94 attempts generate_new_step = copy.deepcopy(sub_step[key]), raising:
    TypeError: list indices must be integers or slices, not str
    
  3. IndexError due to truncated regex in the list branch (lines 95–98):
    In the dictionary branch (line 74), the regex is dependent_on_temp_event\[\S+\]\['\S+\]\[\S+\] (matching the 3-subscript form dependent_on_temp_event[<index>]['<field>'][<match>]). In the list branch (line 96), the regex is missing the first index accessor (dependent_on_temp_event\['\S+\]\[\S+\]). It never matches valid 3-subscript expressions, so re.findall(...) returns [], causing line 98 [0] to raise:
    IndexError: list index out of range
    

Code Pointers / Steps to Reproduce

Affected File:
  • nettacker/core/lib/base.py (lines 83–106)
Reproduction Steps:

Run a scan using the built-in Log4j vulnerability module against any host:

python nettacker.py -i 127.0.0.1 -m log4j_cve_2021_44228_vuln

Once step 1 completes and generates the token (log4shell_token), step 2 attempts to substitute dependent_on_temp_event[0]['content'][0] into the HTTP headers list. The worker thread fails immediately with TypeError: list indices must be integers or slices, not dict.

Minimal Python Demonstration:
from unittest.mock import MagicMock
import sys

# Mock database imports to test logic in isolation
sys.modules["sqlalchemy"] = MagicMock()
sys.modules["sqlalchemy.orm"] = MagicMock()
sys.modules["nettacker.database.db"] = MagicMock()

from nettacker.core.lib.base import BaseEngine
from nettacker.core.template import TemplateLoader

# Load Step 2 of the shipped Log4j vulnerability module
inputs = {"target": "127.0.0.1", "user_agent": "test"}
module = TemplateLoader("log4j_cve_2021_44228_vuln", inputs).load()
step2 = module["payloads"][0]["steps"][1]

# Simulated temp event result from step 1
temp_event = [{"content": ["huntress_token_12345"]}]

engine = BaseEngine()
# Raises TypeError: list indices must be integers or slices, not dict
engine.find_and_replace_dependent_values(step2, temp_event)

Traceback:

Traceback (most recent call last):
  File "repro.py", line 22, in <module>
    engine.find_and_replace_dependent_values(step2, temp_event)
  File "nettacker/core/lib/base.py", line 64, in find_and_replace_dependent_values
    sub_step[key] = self.find_and_replace_dependent_values(
        copy.deepcopy(sub_step[key]), dependent_on_temp_event
    )
  File "nettacker/core/lib/base.py", line 87, in find_and_replace_dependent_values
    sub_step[key] = self.find_and_replace_dependent_values(
TypeError: list indices must be integers or slices, not dict

Impact

  • Vulnerability Scanning Broken: High-impact vulnerability modules such as log4j_cve_2021_44228_vuln rely on multi-step execution where a token generated in step 1 is injected into an HTTP headers list across steps 2–8. Because of this error, every subsequent step fails, rendering Nettacker unable to execute Log4Shell scans or detect the vulnerability.
  • Silent Scan Failures: Worker threads encounter unhandled exceptions during dependent value resolution, preventing requests from being sent and causing dependent scan steps to terminate prematurely.
  • Untested Code Path: Because testing this method with realistic list structures immediately crashed, unit test coverage in tests/core/lib/test_base.py intentionally omitted these lines (lines 87 and 93–103).

Proposed Solution

In nettacker/core/lib/base.py (lines 83–106), use enumerate() to index the list with integer positions (value_index) rather than dictionary-style keys, and align the regex with the 3-subscript pattern used in the dictionary branch:

        elif isinstance(sub_step, list):
            for value_index, item in enumerate(copy.deepcopy(sub_step)):
                if not isinstance(item, (str, float, int, bytes)):
                    sub_step[value_index] = self.find_and_replace_dependent_values(
                        item, dependent_on_temp_event
                    )
                elif isinstance(item, str) and "dependent_on_temp_event" in item:
                    globals().update(locals())
                    matches = re.findall(
                        re.compile("dependent_on_temp_event\\[\\S+\\]\\['\\S+\\]\\[\\S+\\]"),
                        item,
                    )
                    for key_name in matches:
                        try:
                            key_value = eval(key_name)
                        except Exception:
                            key_value = "error"
                        sub_step[value_index] = sub_step[value_index].replace(
                            key_name, str(key_value)
                        )

Additionally, add a unit test in tests/unit/test_base.py verifying that find_and_replace_dependent_values() properly traverses and replaces tokens within lists of dictionaries and lists of strings.


OS: Linux / Windows / macOS

OS Version: All supported versions

Python Version: 3.10, 3.11, 3.12

Dominant language
Python
Stars
5.7k
Forks
1.2k
Avg merge
5d 1h
Merged PRs (30d)
10

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from OWASP/Nettacker

All issues in OWASP/Nettacker

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.