<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Taksh Patadia </title>
    <description>The latest articles on DEV Community by Taksh Patadia  (@taksh_patadia_1009).</description>
    <link>https://dev.to/taksh_patadia_1009</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4104913%2F19b2a197-9948-46d4-981a-2114ed92deb6.jpg</url>
      <title>DEV Community: Taksh Patadia </title>
      <link>https://dev.to/taksh_patadia_1009</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/taksh_patadia_1009"/>
    <language>en</language>
    <item>
      <title>I Built a Network Security Diagnostic Tool With Python’s Standard Library Only</title>
      <dc:creator>Taksh Patadia </dc:creator>
      <pubDate>Tue, 01 Sep 2026 18:26:01 +0000</pubDate>
      <link>https://dev.to/taksh_patadia_1009/i-built-a-network-security-diagnostic-tool-with-pythons-standard-library-only-3668</link>
      <guid>https://dev.to/taksh_patadia_1009/i-built-a-network-security-diagnostic-tool-with-pythons-standard-library-only-3668</guid>
      <description>&lt;p&gt;I Built a Network Security Diagnostic Tool With Python’s Standard Library Only&lt;/p&gt;

&lt;p&gt;For 72 hours, I had a strange constraint:&lt;/p&gt;

&lt;p&gt;Build something useful. Don’t install a single third-party runtime dependency.&lt;/p&gt;

&lt;p&gt;That sounds simple until you try to build something that deals with networking.&lt;/p&gt;

&lt;p&gt;For the Zero Dependency 72-hour hackathon, I built TRACE — a passive network and security diagnostic tool that takes a domain and analyzes what happens when it tries to communicate with that target.&lt;/p&gt;

&lt;p&gt;The goal wasn’t to build another port scanner.&lt;/p&gt;

&lt;p&gt;I wanted TRACE to answer a more useful question:&lt;/p&gt;

&lt;p&gt;“Where does the connection actually succeed or fail, and what can I observe about the target’s security configuration?”&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;What TRACE does&lt;/p&gt;

&lt;p&gt;A TRACE scan follows roughly this path:&lt;/p&gt;

&lt;p&gt;Target&lt;br&gt;
  ↓&lt;br&gt;
DNS&lt;br&gt;
  ↓&lt;br&gt;
TCP&lt;br&gt;
  ↓&lt;br&gt;
HTTP / HTTPS&lt;br&gt;
  ↓&lt;br&gt;
Redirects&lt;br&gt;
  ↓&lt;br&gt;
TLS&lt;br&gt;
  ↓&lt;br&gt;
Certificate&lt;br&gt;
  ↓&lt;br&gt;
Security Headers&lt;br&gt;
  ↓&lt;br&gt;
Findings&lt;br&gt;
  ↓&lt;br&gt;
Risk Summary&lt;/p&gt;

&lt;p&gt;Given a target such as:&lt;/p&gt;

&lt;p&gt;google.com&lt;/p&gt;

&lt;p&gt;TRACE can resolve its address, check TCP connectivity on ports 80 and 443, inspect HTTP and HTTPS responses, follow redirect chains, inspect TLS information, examine the certificate, check security-related HTTP headers, classify observations by severity, and produce a final security summary.&lt;/p&gt;

&lt;p&gt;The important word here is passive.&lt;/p&gt;

&lt;p&gt;TRACE isn’t claiming that it can prove a website is vulnerable. It reports what it can observe from the network and HTTP/TLS behavior.&lt;/p&gt;

&lt;p&gt;That’s why the final report explicitly describes its confidence as:&lt;/p&gt;

&lt;p&gt;PASSIVE / OBSERVATIONAL&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;The obvious question: why not just install packages?&lt;/p&gt;

&lt;p&gt;That’s exactly what I would normally do.&lt;/p&gt;

&lt;p&gt;For a networking project, the obvious choices might include packages such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;requests or httpx for HTTP&lt;/li&gt;
&lt;li&gt;dnspython for DNS&lt;/li&gt;
&lt;li&gt;cryptography for deeper certificate and cryptographic handling&lt;/li&gt;
&lt;li&gt;click or typer for CLI interfaces&lt;/li&gt;
&lt;li&gt;pytest for testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the hackathon’s constraint was the point:&lt;/p&gt;

&lt;p&gt;No third-party runtime dependencies.&lt;/p&gt;

&lt;p&gt;Python had to do the work.&lt;/p&gt;

&lt;p&gt;And that changed how I approached the entire project.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;What I used instead&lt;/p&gt;

&lt;p&gt;The Python standard library turned out to contain much more networking functionality than I initially expected.&lt;/p&gt;

&lt;p&gt;The basic substitutions looked like this:&lt;/p&gt;

&lt;p&gt;What I needed   What I might normally install   What TRACE used&lt;br&gt;
DNS resolution  dnspython   socket&lt;br&gt;
TCP connections higher-level networking libraries   socket&lt;br&gt;
HTTP communication  requests / httpx    http.client&lt;br&gt;
HTTPS/TLS   requests / other TLS wrappers   ssl&lt;br&gt;
URL parsing third-party helpers urllib.parse&lt;br&gt;
CLI handling    click / typer   argparse&lt;br&gt;
Timing  external utilities  standard-library timing functions&lt;br&gt;
JSON handling   external serializers    json&lt;br&gt;
Testing pytest  unittest&lt;/p&gt;

&lt;p&gt;The important lesson was that zero dependency does not mean zero abstraction.&lt;/p&gt;

&lt;p&gt;The abstractions are still there.&lt;/p&gt;

&lt;p&gt;They’re just lower-level.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;DNS was the easy part&lt;/p&gt;

&lt;p&gt;One of the first things TRACE needs to know is:&lt;/p&gt;

&lt;p&gt;“Where is this domain?”&lt;/p&gt;

&lt;p&gt;Python’s socket module can handle basic DNS resolution without installing anything.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;p&gt;google.com&lt;br&gt;
    ↓&lt;br&gt;
socket&lt;br&gt;
    ↓&lt;br&gt;
142.x.x.x&lt;/p&gt;

&lt;p&gt;That gave TRACE the first piece of evidence.&lt;/p&gt;

&lt;p&gt;If DNS fails, there isn’t much point continuing with TCP, TLS, or HTTP.&lt;/p&gt;

&lt;p&gt;So TRACE stops and reports that it cannot continue.&lt;/p&gt;

&lt;p&gt;That also became one of our first useful failure cases to test.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;TCP made the abstraction disappear&lt;/p&gt;

&lt;p&gt;The next question is:&lt;/p&gt;

&lt;p&gt;“Can I actually reach the target?”&lt;/p&gt;

&lt;p&gt;TRACE checks TCP connectivity on ports 80 and 443.&lt;/p&gt;

&lt;p&gt;A normal high-level library can make networking feel like:&lt;/p&gt;

&lt;p&gt;response = requests.get(url)&lt;/p&gt;

&lt;p&gt;But when you’re working closer to the socket layer, you have to think about the actual connection:&lt;/p&gt;

&lt;p&gt;DNS&lt;br&gt;
 ↓&lt;br&gt;
IP address&lt;br&gt;
 ↓&lt;br&gt;
TCP connection&lt;br&gt;
 ↓&lt;br&gt;
port&lt;br&gt;
 ↓&lt;br&gt;
success / failure&lt;/p&gt;

&lt;p&gt;That was one of the more useful parts of the challenge because it forced me to understand what the higher-level libraries normally hide.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;HTTP was where things got more interesting&lt;/p&gt;

&lt;p&gt;TRACE doesn’t just want to know whether an HTTP request succeeds.&lt;/p&gt;

&lt;p&gt;It wants to observe the response.&lt;/p&gt;

&lt;p&gt;For example, Google produced a redirect:&lt;/p&gt;

&lt;p&gt;HTTP 301&lt;br&gt;
    ↓&lt;br&gt;
redirect&lt;br&gt;
    ↓&lt;br&gt;
HTTP 200&lt;/p&gt;

&lt;p&gt;TRACE records the redirect chain instead of simply following it and throwing away the intermediate information.&lt;/p&gt;

&lt;p&gt;That matters because the path itself can contain useful information.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;One edge case taught me an important lesson&lt;/p&gt;

&lt;p&gt;During testing, TRACE reported this for Google’s HTTP behavior:&lt;/p&gt;

&lt;p&gt;HTTP → HTTPS Upgrade: NOT OBSERVED&lt;/p&gt;

&lt;p&gt;At first glance, that sounds like:&lt;/p&gt;

&lt;p&gt;“Google doesn’t use HTTPS.”&lt;/p&gt;

&lt;p&gt;But TRACE had independently established that:&lt;/p&gt;

&lt;p&gt;Port 443 → OPEN&lt;br&gt;
TLS → TLSv1.3&lt;br&gt;
Certificate → HEALTHY&lt;/p&gt;

&lt;p&gt;So that conclusion would obviously be wrong.&lt;/p&gt;

&lt;p&gt;The actual observation was narrower:&lt;/p&gt;

&lt;p&gt;An HTTPS destination was not observed in the particular HTTP redirect chain TRACE followed.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;I changed the way I thought about security observations because of this.&lt;/p&gt;

&lt;p&gt;A diagnostic tool has to be careful not to turn:&lt;/p&gt;

&lt;p&gt;“I didn’t observe X”&lt;/p&gt;

&lt;p&gt;into:&lt;/p&gt;

&lt;p&gt;“X does not exist.”&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;TLS was where the standard library became surprisingly useful&lt;/p&gt;

&lt;p&gt;TRACE uses Python’s ssl functionality to inspect the TLS connection.&lt;/p&gt;

&lt;p&gt;For a working HTTPS target, TRACE can observe things such as:&lt;/p&gt;

&lt;p&gt;TLS Version : TLSv1.3&lt;br&gt;
Cipher      : TLS_AES_256_GCM_SHA384&lt;br&gt;
Certificate : *.google.com&lt;br&gt;
Issuer      : Google Trust Services&lt;/p&gt;

&lt;p&gt;It also calculates certificate validity information and reports whether the certificate appears healthy based on its validity period.&lt;/p&gt;

&lt;p&gt;Again, the goal isn’t to recreate a complete certificate-analysis ecosystem.&lt;/p&gt;

&lt;p&gt;It’s to extract useful information from a real TLS connection using functionality Python already provides.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Then came the security headers&lt;/p&gt;

&lt;p&gt;TRACE checks several response headers, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HSTS&lt;/li&gt;
&lt;li&gt;X-Content-Type-Options&lt;/li&gt;
&lt;li&gt;Content-Security-Policy&lt;/li&gt;
&lt;li&gt;Referrer-Policy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tool turns each observation into a finding with:&lt;/p&gt;

&lt;p&gt;Name&lt;br&gt;
Severity&lt;br&gt;
Status&lt;br&gt;
Evidence&lt;br&gt;
Impact&lt;br&gt;
Recommendation&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Finding:&lt;br&gt;
HSTS&lt;br&gt;
Severity:&lt;br&gt;
LOW&lt;br&gt;
Status:&lt;br&gt;
NOT DETECTED&lt;br&gt;
Evidence:&lt;br&gt;
Strict-Transport-Security header absent&lt;br&gt;
Impact:&lt;br&gt;
The response does not provide an HSTS policy to browsers&lt;br&gt;
Recommendation:&lt;br&gt;
Consider enabling HSTS after validating HTTPS configuration&lt;/p&gt;

&lt;p&gt;This is deliberately conservative.&lt;/p&gt;

&lt;p&gt;A missing header isn’t automatically treated as a confirmed vulnerability.&lt;/p&gt;

&lt;p&gt;It’s an observation that may represent a security improvement opportunity.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;The part that took more thought: turning observations into a conclusion&lt;/p&gt;

&lt;p&gt;Collecting data is only half the problem.&lt;/p&gt;

&lt;p&gt;TRACE needed to answer:&lt;/p&gt;

&lt;p&gt;“So what?”&lt;/p&gt;

&lt;p&gt;That’s why it has a finding model with:&lt;/p&gt;

&lt;p&gt;Observation&lt;br&gt;
    ↓&lt;br&gt;
Severity&lt;br&gt;
    ↓&lt;br&gt;
Evidence&lt;br&gt;
    ↓&lt;br&gt;
Impact&lt;br&gt;
    ↓&lt;br&gt;
Recommendation&lt;/p&gt;

&lt;p&gt;Then those findings are aggregated into an overall risk summary.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Risk Level       : LOW&lt;br&gt;
High Findings    : 0&lt;br&gt;
Medium Findings  : 0&lt;br&gt;
Low Findings     : 1&lt;br&gt;
Informational    : 3&lt;/p&gt;

&lt;p&gt;And the tool explains the primary observation rather than simply printing:&lt;/p&gt;

&lt;p&gt;Risk: LOW&lt;/p&gt;

&lt;p&gt;That makes the output much more useful to someone who isn’t interested in reading raw HTTP headers.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;The standard library wasn’t a magic button&lt;/p&gt;

&lt;p&gt;One of the biggest misconceptions I had going into this was that “zero dependency” meant the project would simply be smaller.&lt;/p&gt;

&lt;p&gt;It isn’t.&lt;/p&gt;

&lt;p&gt;A dependency often hides complexity.&lt;/p&gt;

&lt;p&gt;When you remove the dependency, the complexity doesn’t disappear.&lt;/p&gt;

&lt;p&gt;You inherit it.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;p&gt;requests.get(...)&lt;/p&gt;

&lt;p&gt;you start thinking about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sockets&lt;/li&gt;
&lt;li&gt;connections&lt;/li&gt;
&lt;li&gt;TLS contexts&lt;/li&gt;
&lt;li&gt;redirects&lt;/li&gt;
&lt;li&gt;response parsing&lt;/li&gt;
&lt;li&gt;timeouts&lt;/li&gt;
&lt;li&gt;certificates&lt;/li&gt;
&lt;li&gt;error handling&lt;/li&gt;
&lt;li&gt;URL normalization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The package didn’t make those concepts disappear.&lt;/p&gt;

&lt;p&gt;It just made me less aware of them.&lt;/p&gt;

&lt;p&gt;The hackathon forced those layers back into view.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;What I learned about AI-assisted development&lt;/p&gt;

&lt;p&gt;I also used AI coding assistance during development.&lt;/p&gt;

&lt;p&gt;But this hackathon made one thing very clear:&lt;/p&gt;

&lt;p&gt;Generating code is not the same as understanding the code.&lt;/p&gt;

&lt;p&gt;An AI can produce a function using socket or ssl very quickly.&lt;/p&gt;

&lt;p&gt;That doesn’t mean the resulting implementation is correct.&lt;/p&gt;

&lt;p&gt;The actual work was:&lt;/p&gt;

&lt;p&gt;Generate&lt;br&gt;
   ↓&lt;br&gt;
Run&lt;br&gt;
   ↓&lt;br&gt;
Observe&lt;br&gt;
   ↓&lt;br&gt;
Question&lt;br&gt;
   ↓&lt;br&gt;
Debug&lt;br&gt;
   ↓&lt;br&gt;
Understand&lt;br&gt;
   ↓&lt;br&gt;
Test again&lt;/p&gt;

&lt;p&gt;The project had to work under the zero-dependency constraint, and I needed to be able to explain why the implementation worked.&lt;/p&gt;

&lt;p&gt;That made AI much more useful as a development partner than as a replacement for understanding.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Why I didn’t build everything&lt;/p&gt;

&lt;p&gt;There is always another feature you can add.&lt;/p&gt;

&lt;p&gt;More ports.&lt;/p&gt;

&lt;p&gt;More TLS checks.&lt;/p&gt;

&lt;p&gt;More headers.&lt;/p&gt;

&lt;p&gt;A dashboard.&lt;/p&gt;

&lt;p&gt;A database.&lt;/p&gt;

&lt;p&gt;An AI explanation engine.&lt;/p&gt;

&lt;p&gt;But a 72-hour hackathon is also a lesson in scope.&lt;/p&gt;

&lt;p&gt;A smaller tool that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;works reliably,&lt;/li&gt;
&lt;li&gt;handles failures,&lt;/li&gt;
&lt;li&gt;explains its findings,&lt;/li&gt;
&lt;li&gt;has tests,&lt;/li&gt;
&lt;li&gt;has clear documentation,&lt;/li&gt;
&lt;li&gt;and genuinely respects the dependency constraint&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;is more valuable than a huge project that barely works.&lt;/p&gt;

&lt;p&gt;So TRACE stayed focused on its core purpose:&lt;/p&gt;

&lt;p&gt;Passive network and HTTP/TLS diagnostics with security-oriented observations.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;What zero dependencies actually changed&lt;/p&gt;

&lt;p&gt;The most interesting result of the challenge wasn’t that I managed to avoid pip install.&lt;/p&gt;

&lt;p&gt;It was that I started looking at the standard library differently.&lt;/p&gt;

&lt;p&gt;Before this project, a lot of functionality felt like something you simply imported.&lt;/p&gt;

&lt;p&gt;After building TRACE, I started asking:&lt;/p&gt;

&lt;p&gt;“What is the package actually doing underneath?”&lt;/p&gt;

&lt;p&gt;Sometimes the answer is surprisingly close to:&lt;/p&gt;

&lt;p&gt;socket&lt;br&gt;
ssl&lt;br&gt;
http.client&lt;br&gt;
urllib&lt;br&gt;
json&lt;br&gt;
argparse&lt;/p&gt;

&lt;p&gt;The dependency wasn’t magic.&lt;/p&gt;

&lt;p&gt;It was an abstraction.&lt;/p&gt;

&lt;p&gt;And sometimes the standard library already had enough building blocks to create the abstraction I actually needed.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;What I’d improve next&lt;/p&gt;

&lt;p&gt;TRACE is intentionally not a replacement for professional security scanners.&lt;/p&gt;

&lt;p&gt;There are several directions I’d explore with more time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;more robust IPv6 handling&lt;/li&gt;
&lt;li&gt;richer network timing information&lt;/li&gt;
&lt;li&gt;broader TLS analysis&lt;/li&gt;
&lt;li&gt;more sophisticated redirect analysis&lt;/li&gt;
&lt;li&gt;larger automated test coverage&lt;/li&gt;
&lt;li&gt;machine-readable JSON reports&lt;/li&gt;
&lt;li&gt;more configurable CLI options&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But those are extensions.&lt;/p&gt;

&lt;p&gt;The core experiment was successful:&lt;/p&gt;

&lt;p&gt;Could I build a useful network/security diagnostic tool using Python’s standard library only?&lt;/p&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;p&gt;And the interesting part wasn’t avoiding packages.&lt;/p&gt;

&lt;p&gt;It was discovering how much engineering those packages were doing for me.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;Final takeaway&lt;/p&gt;

&lt;p&gt;Zero dependency doesn’t mean zero complexity.&lt;/p&gt;

&lt;p&gt;It means you’re choosing where that complexity lives.&lt;/p&gt;

&lt;p&gt;With TRACE, I chose to put more of it in my own code and rely on Python’s standard library as the foundation.&lt;/p&gt;

&lt;p&gt;That forced me to understand networking at a level I probably wouldn’t have reached by simply installing another package.&lt;/p&gt;

&lt;p&gt;And that’s probably the biggest thing I’ll take away from the hackathon:&lt;/p&gt;

&lt;p&gt;Before installing a dependency, understand what you’re actually asking it to do.&lt;/p&gt;

</description>
      <category>python</category>
      <category>cybersecurity</category>
      <category>networking</category>
      <category>hackathon</category>
    </item>
  </channel>
</rss>
