List indices must be integers or slices in find_and_replace_dependent_values()
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
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:
TypeErroron complex list items (line 87):
Whensub_stepis a list of dictionaries (such as HTTPheaders: [...]innettacker/modules/vuln/log4j_cve_2021_44228.yaml),keyis adict. Line 87 attemptssub_step[key] = ..., raising:TypeError: list indices must be integers or slices, not dictTypeErroron string list items (line 94):
Whensub_stepis a list of strings containing dependent tokens,keyis astr. Line 94 attemptsgenerate_new_step = copy.deepcopy(sub_step[key]), raising:TypeError: list indices must be integers or slices, not strIndexErrordue to truncated regex in the list branch (lines 95–98):
In the dictionary branch (line 74), the regex isdependent_on_temp_event\[\S+\]\['\S+\]\[\S+\](matching the 3-subscript formdependent_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, sore.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_vulnrely 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.pyintentionally 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
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from OWASP/Nettacker
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
Fix remove_old_logs() failing to delete stale scan events when scan_compare_id is NonePossibly taken @euvoor claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
OWASP/Nettacker#1856 · 1 comment ·
Maintainers usually reply within 1 day
-
admin_scan reports the homepage as an admin pagePossibly taken @Alfa-Dev404 claimed this 1 day ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
OWASP/Nettacker#1850 · 1 comment · 1 reaction · 1 assignee ·
Maintainers usually reply within 1 day
Similar issues
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
igormcsouza/tether#278 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 91/100
aws-samples/sample-per-model-bedrock#803 ·
Maintainers usually reply within 1 day
-
documentation p1
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
huggingface/accelerate#4511 ·
Maintainers usually reply within 1 day
-
follow-up
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day