<?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: Bristie</title>
    <description>The latest articles on DEV Community by Bristie (@n00dlen00b).</description>
    <link>https://dev.to/n00dlen00b</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3839131%2Fdf91e017-2083-4baf-8d6c-1ed32099531a.jpg</url>
      <title>DEV Community: Bristie</title>
      <link>https://dev.to/n00dlen00b</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/n00dlen00b"/>
    <language>en</language>
    <item>
      <title>WaspSting - Penetration Testing &amp; Bug Bounty Tool</title>
      <dc:creator>Bristie</dc:creator>
      <pubDate>Mon, 23 Mar 2026 02:46:06 +0000</pubDate>
      <link>https://dev.to/n00dlen00b/waspsting-osint-automation-tool-47hh</link>
      <guid>https://dev.to/n00dlen00b/waspsting-osint-automation-tool-47hh</guid>
      <description>&lt;h1&gt;
  
  
  I Built a Penetration Testing Tool From Scratch - Here's What I Learned
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;By N00dleN00b | WaspSting v1.5 | Open Source | Apache 2.0&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd4ms6naqrun2r1o6f1d0.png" alt=" " width="777" height="295"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  The Problem Nobody Talks About in Bug Bounty
&lt;/h2&gt;

&lt;p&gt;Everyone talks about finding bugs. Nobody talks about the hours you spend after you find one.&lt;/p&gt;

&lt;p&gt;I'm a cybersecurity student at The University of Tulsa, and like a lot of people in this field, I got hooked on ethical hacking through TryHackMe, HackTheBox, and Burp Suite Labs. The labs are great because it's controlled, structured, and satisfying. You find the vulnerability, you get the flag, you move on. Clean.&lt;/p&gt;

&lt;p&gt;Then I tried my first real bug bounty hunt on Bugcrowd.&lt;/p&gt;

&lt;p&gt;The actual discovery part? Exciting. Everything else? A grind. I was manually keeping track of endpoints in a notepad, copy-pasting evidence into a Word document, writing up findings one by one, trying to remember which OWASP category applied to what, and losing hours to documentation that had nothing to do with actually finding bugs.&lt;/p&gt;

&lt;p&gt;I wanted to get straight to the meat: discovery, exploitation, and verification. Not writing up that yes, the &lt;code&gt;X-Frame-Options&lt;/code&gt; header was missing, for the fifteenth time.&lt;/p&gt;

&lt;p&gt;So I built WaspSting.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is WaspSting?
&lt;/h2&gt;

&lt;p&gt;WaspSting is a Python CLI tool for authorized penetration testing and bug bounty hunting. The core idea is simple: &lt;strong&gt;the documentation should write itself.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You run a scan. WaspSting makes the requests, identifies the issues, maps them to OWASP Top 10:2025, calculates CVSS v3.1 scores, and generates a structured Markdown and JSON report automatically. By the time you're done testing, your report is already 80% written.&lt;/p&gt;

&lt;p&gt;It's built entirely in Python, uses zero paid APIs, and has only two dependencies: &lt;code&gt;rich&lt;/code&gt; for terminal output and &lt;code&gt;requests&lt;/code&gt; for HTTP. Everything else is either standard library or optional external tools.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/N00dleN00b/WaspSting.git
&lt;span class="nb"&gt;cd &lt;/span&gt;WaspSting
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
python3 waspsting.py &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  How It Works: A Technical Deep Dive
&lt;/h2&gt;

&lt;p&gt;WaspSting is built around a modular architecture. Each testing capability lives in its own module under &lt;code&gt;modules/&lt;/code&gt;, and the main &lt;code&gt;waspsting.py&lt;/code&gt; orchestrates them based on the mode you select.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scan Modes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;full     — All modules at once
sast     — Static analysis of a GitHub repo
recon    — Security headers, tech fingerprinting, CVE lookup
auth     — Login lockout testing, JWT attack documentation
bola     — BOLA/IDOR sequential ID walking
api      — Rate limiting, CORS, injection probes
enum     — Subdomain enumeration via crt.sh + DNS brute force
fuzz     — Payload fuzzer across 9 vulnerability categories
nuclei   — Nuclei template runner
bounty   — Scope ingestion → phased test plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Findings Pipeline
&lt;/h3&gt;

&lt;p&gt;Every module returns a standardised findings dict:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;module&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;recon&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;owasp_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A02&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;owasp_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Security Misconfiguration&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;severity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HIGH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;       &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Missing Content-Security-Policy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CSP missing — XSS risk increased&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;evidence&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Header absent from response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fix&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Add Content-Security-Policy header&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cvss_score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="mf"&gt;6.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cvss_vector&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means every finding, regardless of which module produced it, flows through the same reporter, gets scored by the same CVSS engine, and ends up in the same structured report.&lt;/p&gt;

&lt;h3&gt;
  
  
  CVSS v3.1 Scoring: Pure Python, No Library
&lt;/h3&gt;

&lt;p&gt;One of the features I'm most proud of is the CVSS calculator. Rather than pulling in an external library, I implemented the full CVSS v3.1 base score formula from scratch in &lt;code&gt;modules/cvss.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The spec defines a specific formula with metric weights for Attack Vector, Attack Complexity, Privileges Required, User Interaction, Scope, and the CIA triad (Confidentiality, Integrity, Availability). The tricky part is the "round up" rule CVSS uses ceiling rounding to one decimal place, not standard rounding.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CVSSVector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;iss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;U&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;impact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;6.42&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;iss&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;impact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;7.52&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iss&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.029&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;3.25&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;iss&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.02&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;exploitability&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;8.22&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;av&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ac&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pr&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ui&lt;/span&gt;

    &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;impact&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;exploitability&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;U&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; \
          &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.08&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;impact&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;exploitability&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;  &lt;span class="c1"&gt;# CVSS ceiling rounding
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every finding is auto-mapped to a vector based on its OWASP category and title. A SQL injection maps to &lt;code&gt;AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H&lt;/code&gt; (network reachable, no privileges, scope changed, full CIA impact) — a 10.0 CRITICAL. A missing header maps to something lower. You can also override any finding's vector interactively with &lt;code&gt;--cvss-override&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Fuzzer — And Why False Positives Were a Problem
&lt;/h3&gt;

&lt;p&gt;The fuzzer (&lt;code&gt;modules/fuzzer.py&lt;/code&gt;) sends payloads across the following 9 categories: SQLi, XSS, SSTI, path traversal, SSRF, command injection, NoSQL, prompt injection, and open redirect.&lt;/p&gt;

&lt;p&gt;Early on I had a serious false-positive problem. When testing against OWASP Juice Shop (a React SPA), every single XSS and SSTI payload was flagging as a hit. The tool was reporting 60+ HIGH findings that were all fake.&lt;/p&gt;

&lt;p&gt;The root cause: I was checking if the payload appeared anywhere in the response body, but React SPAs return the same &lt;code&gt;index.html&lt;/code&gt; shell for every request regardless of query parameters. The payload appeared in the URL, which appeared in the response, which triggered the match.&lt;/p&gt;

&lt;p&gt;The fix was a two-part SPA guard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_is_spa_shell&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;indicators&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;app-root&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;div id=&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;root&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data-beasties-container&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response_text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ind&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;indicators&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# If baseline is SPA and response is same size/status — skip it
&lt;/span&gt;&lt;span class="n"&gt;same_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;baseline_status&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;size_diff&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;baseline_is_spa&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;same_response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;continue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And tighter detection signatures (SSTI) only triggers if &lt;code&gt;49&lt;/code&gt; appears as a standalone token (the evaluated result of &lt;code&gt;{{7*7}}&lt;/code&gt;), not just anywhere in the response. XSS only triggers if the tag appears &lt;em&gt;unencoded&lt;/em&gt; in the body.&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom OWASP Pattern Rules
&lt;/h3&gt;

&lt;p&gt;v1.5 adds a YAML-based rules engine that lets you write your own detection patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-key-exposure&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS Access Key Exposed&lt;/span&gt;
  &lt;span class="na"&gt;owasp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;A02&lt;/span&gt;
  &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CRITICAL&lt;/span&gt;
  &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;response_body&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AKIA[0-9A-Z]{16}"&lt;/span&gt;
    &lt;span class="na"&gt;source_code&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;   &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(AKIA|ASIA|AROA)[0-9A-Z]{16}"&lt;/span&gt;
  &lt;span class="na"&gt;fix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Rotate the key immediately and audit CloudTrail.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rules can match against HTTP response bodies, source code files (SAST mode), header presence/absence, header values, and status codes. Drop your YAML files in &lt;code&gt;rules/&lt;/code&gt; and they're picked up automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bugcrowd API Integration
&lt;/h3&gt;

&lt;p&gt;Instead of manually copying scope from a Bugcrowd program page, WaspSting can pull it directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;BUGCROWD_API_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_token_here
python3 waspsting.py &lt;span class="nt"&gt;--bugcrowd-program&lt;/span&gt; acme-corp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It fetches the target groups, filters to web-relevant targets, converts wildcards (&lt;code&gt;*.example.com&lt;/code&gt;) to their apex domain with a clear warning, and saves a WaspSting-compatible scope JSON ready to pass to &lt;code&gt;--mode bounty&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Finding Real Bugs — DVWA Walkthrough
&lt;/h2&gt;

&lt;p&gt;Let's put it into practice against DVWA (Damn Vulnerable Web Application), a deliberately vulnerable app you can run locally for safe, legal testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run DVWA in Docker&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 vulnerables/web-dvwa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;http://localhost:8080&lt;/code&gt;, log in with &lt;code&gt;admin/password&lt;/code&gt;, click &lt;strong&gt;Setup/Reset DB&lt;/strong&gt;, then set security level to &lt;strong&gt;Low&lt;/strong&gt; in the DVWA Security tab.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — Recon
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 waspsting.py &lt;span class="nt"&gt;--target&lt;/span&gt; http://localhost:8080 &lt;span class="nt"&gt;--mode&lt;/span&gt; recon &lt;span class="nt"&gt;--rules&lt;/span&gt; &lt;span class="nt"&gt;--confirm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What you'll see:&lt;/strong&gt; Missing security headers (HSTS, CSP, X-Frame-Options), no HTTPS, CVSS scores auto-populated for each finding.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibzpz7xhzekcjn0izwj8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibzpz7xhzekcjn0izwj8.png" alt=" " width="775" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpcjjq63jbyxhi0qfrrqe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpcjjq63jbyxhi0qfrrqe.png" alt=" " width="773" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9lgvut5vjr1ozlbkoqac.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9lgvut5vjr1ozlbkoqac.png" alt=" " width="777" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffluwjl3w184x0fgid62c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffluwjl3w184x0fgid62c.png" alt=" " width="782" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9zp0nlvjvhu4tzi9r58.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9zp0nlvjvhu4tzi9r58.png" alt=" " width="773" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8x0ltpkyi55o3j8ca57h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8x0ltpkyi55o3j8ca57h.png" alt=" " width="773" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 — Auth Audit
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 waspsting.py &lt;span class="nt"&gt;--target&lt;/span&gt; http://localhost:8080 &lt;span class="nt"&gt;--mode&lt;/span&gt; auth &lt;span class="nt"&gt;--confirm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What you'll see:&lt;/strong&gt; WaspSting finds the login endpoint, tests lockout policy (DVWA has none on Low security), documents JWT attack vectors for manual testing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzocgkykfr6jqyzq8y3w9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzocgkykfr6jqyzq8y3w9.png" alt=" " width="767" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zr1z10nbd1yzsb0gqme.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zr1z10nbd1yzsb0gqme.png" alt=" " width="772" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0ykgphwawh3r5p195p8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0ykgphwawh3r5p195p8.png" alt=" " width="772" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 — Fuzzer
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 waspsting.py &lt;span class="nt"&gt;--target&lt;/span&gt; http://localhost:8080 &lt;span class="nt"&gt;--mode&lt;/span&gt; fuzz &lt;span class="nt"&gt;--confirm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What you'll see:&lt;/strong&gt; On DVWA at Low security, the fuzzer should trigger on SQL injection endpoints because DVWA actually returns database errors and real signatures, not SPA noise.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6tfh9gbsfyssjir6xccw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6tfh9gbsfyssjir6xccw.png" alt=" " width="776" height="215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1wdxzjxjczjic4860oa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1wdxzjxjczjic4860oa.png" alt=" " width="771" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwvqvffksuqq4trfrnmry.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwvqvffksuqq4trfrnmry.png" alt=" " width="777" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhlgsb3lrgytu2nwalco4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhlgsb3lrgytu2nwalco4.png" alt=" " width="772" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 — Full Scan with HTML Report
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 waspsting.py &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--target&lt;/span&gt; http://localhost:8080 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--mode&lt;/span&gt; full &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--html&lt;/span&gt; &lt;span class="nt"&gt;--rules&lt;/span&gt; &lt;span class="nt"&gt;--cvss-override&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--confirm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What you'll see:&lt;/strong&gt; Every module runs sequentially, findings accumulate, CVSS table prints at the end, HTML report saved to &lt;code&gt;output/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Open the HTML report in your browser and that's your executive report with risk gauge, severity charts, and filterable findings table.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnqv3zivuy3amsznqw9eu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnqv3zivuy3amsznqw9eu.png" alt=" " width="773" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnb3e23oy7k4ghwl0bfcb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnb3e23oy7k4ghwl0bfcb.png" alt=" " width="777" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmoeklu9jxf9l7ctt0is7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmoeklu9jxf9l7ctt0is7.png" alt=" " width="775" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjzs69aejvsk35fdwg0wi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjzs69aejvsk35fdwg0wi.png" alt=" " width="775" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folp9asaqo648tholehkg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folp9asaqo648tholehkg.png" alt=" " width="771" height="270"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Learned as Building a Security Tool
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Building tools forces you to understand the underlying concepts deeply
&lt;/h3&gt;

&lt;p&gt;You can't write a CVSS calculator without understanding how Attack Vector, Scope, and the CIA triad interact. You can't write a fuzzer without understanding why SPAs behave differently from server-rendered apps. The act of building forced me to go deeper than any lab ever did.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. False positives are a real problem and most write-ups skip it
&lt;/h3&gt;

&lt;p&gt;Every security tool deals with false positives. The difference between a useful tool and a noisy one is how carefully you tune detection. I spent more time on the SPA guard than on the entire fuzzer payload list.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Good architecture matters more than features
&lt;/h3&gt;

&lt;p&gt;The decision to standardize all findings into the same dict format early on meant that CVSS scoring, deduplication, notifications, and reporting all just worked when I added them and no refactoring needed. The modular design meant I could add Nuclei integration without touching any existing module.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Documentation is part of the product
&lt;/h3&gt;

&lt;p&gt;The README, the example rules file, the clear error messages are as important as the code. A tool with great features and terrible docs gets ignored. A tool with decent features and great docs gets used and contributed to.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Real-world testing is humbling
&lt;/h3&gt;

&lt;p&gt;The moment I ran WaspSting against Juice Shop and saw 60 false-positive XSS findings, I understood something that no CTF ever taught me: the difference between "payload sent" and "vulnerability confirmed" is everything. That lesson shapes how I think about every finding now.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Use WaspSting for Bug Bounty
&lt;/h2&gt;

&lt;p&gt;Here's the workflow I'd recommend for a typical Bugcrowd engagement:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Import scope&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;BUGCROWD_API_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_token
python3 waspsting.py &lt;span class="nt"&gt;--bugcrowd-program&lt;/span&gt; target-program
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Run the bounty planner&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 waspsting.py &lt;span class="nt"&gt;--mode&lt;/span&gt; bounty &lt;span class="nt"&gt;--scope&lt;/span&gt; output/scope_target_SESSION.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you a phased test plan prioritised by payout potential.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Recon each in-scope target&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 waspsting.py &lt;span class="nt"&gt;--target&lt;/span&gt; https://app.target.com &lt;span class="nt"&gt;--mode&lt;/span&gt; recon &lt;span class="nt"&gt;--cve&lt;/span&gt; &lt;span class="nt"&gt;--rules&lt;/span&gt; &lt;span class="nt"&gt;--confirm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Subdomain enumeration&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 waspsting.py &lt;span class="nt"&gt;--target&lt;/span&gt; https://target.com &lt;span class="nt"&gt;--mode&lt;/span&gt; enum &lt;span class="nt"&gt;--screenshot&lt;/span&gt; &lt;span class="nt"&gt;--confirm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Full scan on interesting subdomains&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 waspsting.py &lt;span class="nt"&gt;--target&lt;/span&gt; https://app.target.com &lt;span class="nt"&gt;--mode&lt;/span&gt; full &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--html&lt;/span&gt; &lt;span class="nt"&gt;--rules&lt;/span&gt; &lt;span class="nt"&gt;--burp&lt;/span&gt; &lt;span class="nt"&gt;--dedup&lt;/span&gt; &lt;span class="nt"&gt;--confirm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6. Manual follow-up&lt;/strong&gt;&lt;br&gt;
Use the generated Burp config to load scope and payloads into Burp Suite Community for manual testing of anything the automated scan flagged.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Clear session when done&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 clear_session.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Saves your reports, wipes the output directory, and you're ready for the next program.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The roadmap still has some exciting items:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HackerOne API integration (same as Bugcrowd but H1's OAuth flow)&lt;/li&gt;
&lt;li&gt;CVSS v4.0 support (the spec dropped in 2023, still catching up)&lt;/li&gt;
&lt;li&gt;Custom OWASP pattern sharing — a community rules repository&lt;/li&gt;
&lt;li&gt;CI/CD integration docs for teams running WaspSting in pipelines&lt;/li&gt;
&lt;li&gt;General optimization, fine-tuning for accuracy, and I'm sure there's more things I haven't even considered yet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you find a bug, want to contribute a module, or just want to say the tool helped you find something on a real program, open an issue or a PR. I'm learning as I go and every contribution teaches me something.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/N00dleN00b/WaspSting.git
&lt;span class="nb"&gt;cd &lt;/span&gt;WaspSting
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
python3 waspsting.py &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Licensed Apache 2.0. Free to use, fork, and build on.&lt;/p&gt;

&lt;p&gt;If WaspSting helped you find a bug — star the repo. It means a lot as a student building in public.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;N00dleN00b is a cybersecurity student at TU passionate about ethical hacking, bug bounty research, and building open-source security tooling.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;GitHub: &lt;a href="https://github.com/N00dleN00b/WaspSting" rel="noopener noreferrer"&gt;github.com/N00dleN00b/WaspSting&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>bugbounty</category>
      <category>security</category>
      <category>python</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
