Backend Development 10 min read

Resolving Data Contamination in Multithreaded Security Testing by Redesigning Class Attributes in Python

This article explains how using a shared class attribute to store open ports in a Python security‑testing framework can cause data contamination across threads, demonstrates the problem with example code, and presents three solutions—reinitializing the attribute, using contextvars, and employing threading.local—to ensure thread‑local isolation and accurate port scanning.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Resolving Data Contamination in Multithreaded Security Testing by Redesigning Class Attributes in Python

During online security testing, Nmap is often used for port scanning, and a class attribute all_open_ports is employed to record open ports. When multiple threads run tests simultaneously, this shared attribute can become a source of data contamination, leading to inaccurate results.

The issue is illustrated with a parent class Parent that defines all_open_ports as a class‑level set and a child class Child that inherits it. A multithreaded test creates two Child instances, each scanning a different port, and the output shows that the set is shared across threads, causing unexpected behavior.

class Parent: all_open_ports = set() def __init__(self, args): self.all_open_ports.update(args.get("open_ports", [])) def check_port(self, port): if port not in self.all_open_ports: self.all_open_ports.add(port) print(f"{port} in all_open_ports, {self.all_open_ports}")

The root cause is that all_open_ports is a class attribute, making it shared by all subclasses and instances. Each time a Child object is created, the ports passed in are added to the same set, so different test runs interfere with each other.

Three remediation strategies are presented:

Reinitializing all_open_ports in __init__ : By assigning self.all_open_ports = set() inside the constructor, each instance gets its own set, eliminating cross‑thread contamination but also losing the intended sharing of already‑scanned ports.

Using contextvars.ContextVar : A ContextVar provides a context‑local variable that can be safely accessed in asynchronous or multithreaded code. The article shows how to wrap the set in a ContextVar and update it per thread.

Employing threading.local() : Thread‑local storage gives each thread its own independent copy of the variable. The example defines a ParentLocal class that stores all_open_ports in a threading.local() object, ensuring isolation between threads while preserving per‑thread state.

Each solution is demonstrated with code snippets and the corresponding execution results, highlighting how the shared‑state problem is resolved.

In conclusion, while reinitializing the attribute is the simplest fix, using contextvars or threading.local offers a more robust way to maintain thread‑local data without sacrificing the efficiency gains of shared port information.

PythonThread SafetyMultithreadingthreadlocalClass AttributesContextVar
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.