<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ fuzzing - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ fuzzing - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Thu, 25 Jun 2026 10:02:26 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/fuzzing/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Discover Hidden Subdomains as an Ethical Hacker ]]>
                </title>
                <description>
                    <![CDATA[ Subdomains are an essential part of a website’s infrastructure. They provide additional functions in a web application, such as APIs, admin portals, and staging environments. As an ethical hacker, discovering subdomains is a critical step in learning... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-discover-hidden-subdomains-as-an-ethical-hacker/</link>
                <guid isPermaLink="false">677d84ad446398ca6f670bef</guid>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ gobuster ]]>
                    </category>
                
                    <category>
                        <![CDATA[ domain ]]>
                    </category>
                
                    <category>
                        <![CDATA[ subdomains ]]>
                    </category>
                
                    <category>
                        <![CDATA[ fuzzing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Ethical Hacking ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Tue, 07 Jan 2025 19:46:53 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1735806321604/dec39da9-6dd8-4a73-ba64-5cf894ce34f4.webp" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Subdomains are an essential part of a website’s infrastructure. They provide additional functions in a web application, such as APIs, admin portals, and staging environments.</p>
<p>As an ethical hacker, discovering subdomains is a critical step in learning the attack surface of a target. Subdomains might not be protected well, unlike the main domain. So they can be a great entry point for security auditing or bug bounty programs.</p>
<p>In this article, I’ll walk you through how to find subdomains using multiple methods. We will use <a target="_blank" href="http://tesla.com/">tesla.com</a> as our example in subdomain research.</p>
<blockquote>
<p><em>Note: tesla.com is part of bug bounty programs, so we have permission to scan it for subdomains. If you are doing this in another web application, make sure you have permission.</em></p>
</blockquote>
<h2 id="heading-crtsh"><strong>Crt.sh</strong></h2>
<p>One of the easiest ways to start is by checking Certificate Transparency (CT) logs using <a target="_blank" href="https://crt.sh/">crt.sh</a>. This website records every SSL/TLS certificate issued for a domain, including subdomains.</p>
<p>To search for Tesla’s subdomains, visit <a target="_blank" href="https://crt.sh/">crt.sh</a> and enter <code>%.tesla.com</code> as the query. The <code>%</code> acts as a wildcard to match any subdomains.</p>
<p>Let's look at the results:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735806389562/eabc92c8-6fff-45fb-ba1c-00f582a31c4f.webp" alt="tesla.com subdomain research - results of running tesla.com through crt.sh" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>We can see a lot of interesting subdomains listed in the results. These subdomains may belong to different parts of Tesla’s infrastructure.</p>
<p>For example, <code>shop.tesla.com</code> is likely for their online store, while <code>api.tesla.com</code> could host application programming interfaces.</p>
<p>Using <code>crt.sh</code> is passive, meaning it doesn’t interact with the target, making it both safe and stealthy.</p>
<p>Note that <a target="_blank" href="http://crt.sh">crt.sh</a> will only display subdomains that have valid certificates. If a subdomain uses self-signed certificates or doesn’t use SSL/TLS at all, it may not appear in these logs. Despite this limitation, <a target="_blank" href="http://crt.sh">crt.sh</a> remains a quick and efficient starting point for subdomain enumeration.</p>
<h2 id="heading-sublist3r"><strong>Sublist3r</strong></h2>
<p><a target="_blank" href="https://github.com/aboul3la/Sublist3r">Sublist3r</a> is an open-source tool to automate finding subdomains. It’s helpful in both security assessments and general reconnaissance.</p>
<p>By using multiple search engines (like Google, Bing, Yahoo, and more) Sublist3r finds subdomains that might otherwise remain hidden.</p>
<p>Sublist3r’s command-line interface is simple to use — you give it a domain, and Sublist3r goes to work.</p>
<p>Thanks to its open-source nature, it’s actively maintained and improved by the security community.</p>
<p>Sublist3r is not pre-installed on Kali, so lets go ahead and install it. First, clone the repository and install the requirements:</p>
<pre><code class="lang-plaintext">git clone https://github.com/aboul3la/Sublist3r.git
cd Sublist3r
sudo pip install -r requirements.txt
</code></pre>
<p>Now we are ready to use the sublist3r tool. Here is the syntax to use sublist3r:</p>
<pre><code class="lang-plaintext">python sublist3r.py -d tesla.com
</code></pre>
<p>After a few minutes, Sublist3r will return a list of discovered subdomains. The <code>-d</code> flag tells sublist3r that the domain to use is tesla.com</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735806446961/b2f239bf-5a9b-4da6-a875-d9326e2b0621.webp" alt="sublist3r response" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>You can see that sublist3r has found more than 300 subdomains of <a target="_blank" href="http://tesla.com">tesla.com</a>. Sublist3r is an excellent way to jump-start the recon process, especially if you want to automate the collection of subdomains without installing numerous separate tools.</p>
<p>Note that Sublist3r relies on the APIs of these search engines and other data sources. So it can sometimes miss subdomains that haven’t been crawled or indexed.</p>
<h2 id="heading-google-dorking"><strong>Google Dorking</strong></h2>
<p>Google dorking (sometimes called “Google hacking”) refers to the practice of using special search queries on Google. These operators help to find hidden information, sensitive data, or other resources that would otherwise be hard to locate.</p>
<p>Common operators include <code>site:</code>, <code>inurl:</code>, <code>filetype:</code>, and <code>intitle:</code>, among many others. Let’s start with the <code>site:</code> operator:</p>
<pre><code class="lang-plaintext">site:*.tesla.com
</code></pre>
<p>This query searches for any subdomain of <a target="_blank" href="http://tesla.com"><code>tesla.com</code></a>. Here are some search results.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735806489328/fb4187aa-aa35-45d7-b975-5487de0093e2.webp" alt="tesla.com google dork" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>To dig deeper, try combining <code>site:</code> with other operators. For example, we can use the <code>inurl</code> operator with the keyword ‘admin’ to find URLs containing the word admin.</p>
<pre><code class="lang-plaintext">site:*.tesla.com inurl:admi
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735806522371/02c44cdd-1bc3-4c8c-822a-16f883b6c166.webp" alt="02c44cdd-1bc3-4c8c-822a-16f883b6c166" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>By using these operators (known as Google dorks), you can filter search results to find specific file types, directories, or even private information that may be unintentionally exposed on the internet.</p>
<p>Dorking can produce a lot of data, so you may need to carefully filter your searches to avoid getting flooded with irrelevant information.</p>
<p><a target="_blank" href="https://www.stealthsecurity.sh/p/google-dorking-the-ultimate-guide-to-finding-hidden-information-on-the-web">Here is a full tutorial</a> on Google dorking.</p>
<h2 id="heading-fuzzing-with-gobuster"><strong>Fuzzing with GoBuster</strong></h2>
<p>Now what if the subdomains of a target are not listed anywhere on the internet? We fuzz for it.</p>
<p>Fuzzing is simply brute-forcing potential subdomain names by trying combinations from a wordlist. A wordlist is a list of words that we will use along with the fuzzing tool to see if a subdomain exists.</p>
<p>A subdomain wordlist can contain words like:</p>
<pre><code class="lang-plaintext">ftp
root
admin
portal
api
</code></pre>
<p>Tools like Gobuster and Ffuf can use a wordlist to check whether these subdomains exist. Here is a sample <a target="_blank" href="https://raw.githubusercontent.com/danielmiessler/SecLists/refs/heads/master/Discovery/DNS/subdomains-top1million-110000.txt">subdomain wordlist</a>.</p>
<h3 id="heading-how-gobuster-works"><strong>How Gobuster Works</strong></h3>
<p><a target="_blank" href="https://www.stealthsecurity.sh/p/finding-hidden-directories-subdomains-s3-buckets-using-gobuster">Gobuster</a> is a fast brute-force tool for discovering hidden URLs, files, and directories within websites.</p>
<p>Ffuf is a wonderful web fuzzer, but Gobuster is a faster and more flexible alternative. Gobuster has support for extensions with which we can increase its capabilities.</p>
<p>Gobuster also can scale using multiple threads and perform parallel scans to speed up results.</p>
<p>Gobuster comes pre-installed in Kali Linux. Let’s run the following command to look for subdomains. You can find the word list under /usr/share/wordlists/SecLists in Kali Linux.</p>
<pre><code class="lang-plaintext">gobuster dns -d tesla.com -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt
</code></pre>
<p>The above command checks each word in the wordlist to see if it resolves to a valid subdomain. Here’s a sample output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735806581200/46b3d437-9918-416c-a510-f647e9ac303e.webp" alt="46b3d437-9918-416c-a510-f647e9ac303e" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Gobuster’s results show valid subdomains, including some that might not appear in public databases, like <code>staging.tesla.com</code> or <code>dev.tesla.com</code>.</p>
<p>Fuzzing should be combined with other methods since the results are only as good as the wordlist. For example, prod-version-2.tesla.com can be a subdomain which may not be a part of the wordlist.</p>
<h2 id="heading-other-methods-for-subdomain-discovery"><strong>Other Methods for Subdomain Discovery</strong></h2>
<h3 id="heading-dns-zone-transfers"><strong>DNS Zone Transfers</strong></h3>
<p>While rare, misconfigured DNS servers can allow zone transfers, revealing all subdomains at once. You can test this using <code>dig</code>:</p>
<pre><code class="lang-plaintext">dig axfr @ns1.tesla.com tesla.com
</code></pre>
<p>If the server is properly secured, it won’t allow a zone transfer. But if it’s misconfigured, you might uncover every subdomain Tesla uses.</p>
<h3 id="heading-online-tools"><strong>Online Tools</strong></h3>
<p>Websites like <a target="_blank" href="https://securitytrails.com/">SecurityTrails</a>, <a target="_blank" href="https://shodan.io/">Shodan</a>, and <a target="_blank" href="https://censys.io/">Censys</a> aggregate subdomain data. These tools provide a centralized view of publicly available information.</p>
<h3 id="heading-inspecting-javascript-files"><strong>Inspecting JavaScript Files</strong></h3>
<p>Subdomains often appear in a website’s JavaScript files. By examining Tesla’s website, you might find references to API endpoints or other subdomains.</p>
<h2 id="heading-post-subdomain-discovery">Post-Subdomain Discovery</h2>
<p>Once you have a list of subdomains, we can probe them further. We may discover sign-in portals, development pages, or API endpoints.</p>
<p>Ethical hackers typically use port scanning and service enumeration tools like Nmap and Nikto to find the open ports and running services on each subdomain. Identifying outdated software, insecure protocols, or default credentials is often the next critical step, as these are common weak points in any environment.</p>
<p>Subdomains often show us the broader infrastructure of the website if they are left unprotected.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Subdomain discovery is a critical skill for ethical hackers. It helps us understand the complete picture of a web application. The more we know, the better entry points we have to gain access.</p>
<p>Before using these techniques, always ensure you have proper authorization. Subdomain discovery helps with security audits by uncovering hidden assets and helping organizations protect themselves from potential threats.</p>
<p>For more practical tutorials on cybersecurity, join our <a target="_blank" href="https://www.stealthsecurity.sh/"><strong>weekly newsletter</strong></a>. If you want to practice these subdomain discovery techniques through a hands-on lab, join us at the <a target="_blank" href="https://www.skool.com/hackershub"><strong>Hacker’s Hub</strong></a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Fuzz Test Golang HTTP Services ]]>
                </title>
                <description>
                    <![CDATA[ As a developer, you can’t always envision all of the possible inputs your programs or functions might receive. Even though you can define the major edge cases, you still can’t predict how your program will behave in the case of some weird unexpected ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-fuzz-test-golang-http-services/</link>
                <guid isPermaLink="false">672941e6066de072ede39685</guid>
                
                    <category>
                        <![CDATA[ Go Language ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Testing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ fuzzing ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alex Pliutau ]]>
                </dc:creator>
                <pubDate>Mon, 04 Nov 2024 21:51:34 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1730664559414/b64781c3-341f-4a5d-94fe-38ff78099b42.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As a developer, you can’t always envision all of the possible inputs your programs or functions might receive.</p>
<p>Even though you can define the major edge cases, you still can’t predict how your program will behave in the case of some weird unexpected input. In other words, you can typically only find bugs you <em>expect</em> to find.</p>
<p>That’s where fuzz testing or fuzzing comes to the rescue. And in this tutorial, you’ll learn how to perform fuzz testing in Go.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-fuzz-testing">What is Fuzz Testing</a>?</p>
</li>
<li><p><a class="post-section-overview" href="#heading-fuzz-testing-in-go">Fuzz Testing in Go</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-fuzzing-http-services">Fuzzing HTTP Services</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-resources">Resources</a></p>
</li>
</ul>
<h2 id="heading-what-is-fuzz-testing">What is Fuzz Testing?</h2>
<p>Fuzzing is an automated software testing technique that involves inputting a large amount of valid, nearly-valid, or invalid random data into a computer program and observing its behavior and output. So the goal of fuzzing is to reveal bugs, crashes, and security vulnerabilities in source code you might not find through traditional testing methods.</p>
<p>The <a target="_blank" href="https://youtu.be/w8STTZWdG9Y">Fuzz Testing in Go</a> video which I made a few years ago shows a very simple example of the Go code that may work well unless you provide a certain input:</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Equal</span><span class="hljs-params">(a []<span class="hljs-keyword">byte</span>, b []<span class="hljs-keyword">byte</span>)</span> <span class="hljs-title">bool</span></span> {
  <span class="hljs-keyword">for</span> i := <span class="hljs-keyword">range</span> a {
    <span class="hljs-comment">// can panic with runtime error: index out of range.</span>
    <span class="hljs-keyword">if</span> a[i] != b[i] {
      <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
    }
  }

  <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>
}
</code></pre>
<p>This sample function works perfectly as long as the length of two slices are equal. But it will panic when the first slice is longer than the second (index out of range error). Furthermore, it doesn’t return a correct result when the second slice is the subset of the first one.</p>
<p>The fuzzing technique would easily spot this bug by bombarding this function with various inputs.</p>
<p>It’s a good practice to integrate fuzzing into your team’s software development lifecycle (SDLC) as well. For example, Microsoft uses fuzzing as <a target="_blank" href="https://learn.microsoft.com/en-us/compliance/assurance/assurance-microsoft-security-development-lifecycle">one of the stages in its SDLC</a>, to find potential bugs and vulnerabilities.</p>
<h2 id="heading-fuzz-testing-in-go">Fuzz Testing in Go</h2>
<p>There are many fuzzing tools that have been available for a while – such as <a target="_blank" href="https://github.com/google/oss-fuzz">oss-fuzz</a>, for example – but since Go 1.18, fuzzing was added to Go’s standard library. So it’s now part of the regular testing package since it’s a kind of test. You can also use it together with the other testing primitives which is nice.</p>
<p>The steps to create a fuzz test in Go are the following:</p>
<ol>
<li><p>In a <strong>_test.go</strong> file, create a function that starts with <code>Fuzz</code> which accepts <code>*testing.F</code></p>
</li>
<li><p>Add corpus seeds using <code>f.Add()</code> to allow the fuzzer to generate the data based on it.</p>
</li>
<li><p>Call the fuzz target using <code>f.Fuzz()</code> by passing fuzzing arguments which our target function accepts.</p>
</li>
<li><p>Start the fuzzer using the regular <code>go test</code> command, but with the <code>–fuzz=Fuzz</code> flag</p>
</li>
</ol>
<p>Note that the fuzzing arguments can only be the following types:</p>
<ul>
<li><p>string, byte, []byte</p>
</li>
<li><p>int, int8, int16, int32/rune, int64</p>
</li>
<li><p>uint, uint8, uint16, uint32, uint64</p>
</li>
<li><p>float32, float64</p>
</li>
<li><p>bool</p>
</li>
</ul>
<p>A simple fuzz test for the <strong>Equal</strong> function above may look like this:</p>
<pre><code class="lang-go"><span class="hljs-comment">// Fuzz test</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">FuzzEqual</span><span class="hljs-params">(f *testing.F)</span></span> {
  <span class="hljs-comment">// Seed corpus addition</span>
  f.Add([]<span class="hljs-keyword">byte</span>{<span class="hljs-string">'f'</span>, <span class="hljs-string">'u'</span>, <span class="hljs-string">'z'</span>, <span class="hljs-string">'z'</span>}, []<span class="hljs-keyword">byte</span>{<span class="hljs-string">'t'</span>, <span class="hljs-string">'e'</span>, <span class="hljs-string">'s'</span>, <span class="hljs-string">'t'</span>})

  <span class="hljs-comment">// Fuzz target with fuzzing arguments</span>
  f.Fuzz(<span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(t *testing.T, a []<span class="hljs-keyword">byte</span>, b []<span class="hljs-keyword">byte</span>)</span></span> {
    <span class="hljs-comment">// Call our target function and pass fuzzing arguments</span>
    Equal(a, b)
  })
}
</code></pre>
<p>By default, fuzz tests run forever, so you either need to specify the time limit or wait for fuzz tests to fail. You can specify which tests to run using the <code>--fuzz</code> argument.</p>
<pre><code class="lang-bash">go <span class="hljs-built_in">test</span> --fuzz=Fuzz -fuzztime=10s
</code></pre>
<p>If there are any errors during the execution, the output should look similar to this:</p>
<pre><code class="lang-bash">go <span class="hljs-built_in">test</span> --fuzz=Fuzz -fuzztime=30s
--- FAIL: FuzzEqual (0.02s)
    --- FAIL: FuzzEqual (0.00s)
        testing.go:1591: panic: runtime error: index out of range
    Failing input written to testdata/fuzz/FuzzEqual/84ed65595ad05a58
    To re-run:
    go <span class="hljs-built_in">test</span> -run=FuzzEqual/84ed65595ad05a58
</code></pre>
<p>Notice that the input for which the <code>fuzz</code> test has failed are written into a file in the <code>testdata</code> folder and can be re-played by using that input identifier.</p>
<pre><code class="lang-bash">go <span class="hljs-built_in">test</span> -run=FuzzEqual/84ed65595ad05a58
</code></pre>
<p>The <code>testdata</code> folder can be checked into the repository and be used for regular tests, because fuzz tests can also act as regular tests when executed without the <code>--fuzz</code> flag.</p>
<h2 id="heading-fuzzing-http-services">Fuzzing HTTP Services</h2>
<p>It’s also possible to fuzz test the HTTP services by writing a test for your <code>HandlerFunc</code> and using the <code>httptest</code> package. This can be very useful if you need to test the whole HTTP service, not only the underlying functions.</p>
<p>Let’s now introduce a more real example such as an HTTP Handler that accepts some user input in the request body and then write a fuzz test for it.</p>
<p>Our handler accepts a JSON request with <code>limit</code> and <code>offset</code> fields to paginate some static mocked data. Let's define the types first.</p>
<pre><code class="lang-go"><span class="hljs-keyword">type</span> Request <span class="hljs-keyword">struct</span> {
  Limit  <span class="hljs-keyword">int</span> <span class="hljs-string">`json:"limit"`</span>
  Offset <span class="hljs-keyword">int</span> <span class="hljs-string">`json:"offset"`</span>
}

<span class="hljs-keyword">type</span> Response <span class="hljs-keyword">struct</span> {
  Results    []<span class="hljs-keyword">int</span> <span class="hljs-string">`json:"items"`</span>
  PagesCount <span class="hljs-keyword">int</span>   <span class="hljs-string">`json:"pagesCount"`</span>
}
</code></pre>
<p>Our handler function then parses the JSON, paginates the static slice, and returns a new JSON in response.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">ProcessRequest</span><span class="hljs-params">(w http.ResponseWriter, r *http.Request)</span></span> {
 <span class="hljs-keyword">var</span> req Request

  <span class="hljs-comment">// Decode JSON request</span>
  <span class="hljs-keyword">if</span> err := json.NewDecoder(r.Body).Decode(&amp;req); err != <span class="hljs-literal">nil</span> {
    http.Error(w, err.Error(), http.StatusBadRequest)
    <span class="hljs-keyword">return</span>
  }

 <span class="hljs-comment">// Apply offset and limit to some static data</span>
 all := <span class="hljs-built_in">make</span>([]<span class="hljs-keyword">int</span>, <span class="hljs-number">1000</span>)
 start := req.Offset
 end := req.Offset + req.Limit
 res := Response{
   Results:    all[start:end],
   PagesCount: <span class="hljs-built_in">len</span>(all) / req.Limit,
 }

 <span class="hljs-comment">// Send JSON response</span>
 <span class="hljs-keyword">if</span> err := json.NewEncoder(w).Encode(res); err != <span class="hljs-literal">nil</span> {
   http.Error(w, err.Error(), http.StatusInternalServerError)
   <span class="hljs-keyword">return</span>
 }

 w.WriteHeader(http.StatusOK)
}
</code></pre>
<p>As you may have already noticed, this function doesn’t handle slice operations very well and can easily <code>panic</code>. Also, it can panic if it tries to divide by 0. It's great if we can spot this during the development or using only unit tests, but sometimes not everything is visible to our eye, and our handler may pass the input to other functions and so forth.</p>
<p>Following our <code>FuzzEqual</code> example above, let’s implement a fuzz test for the <code>ProcessRequest</code> handler. The first thing we need to do is to provide the sample inputs for the fuzzer. This is the data that the fuzzer will use and modify into new inputs that are tried. We can craft some sample JSON request and use <code>f.Add()</code> with the <code>[]byte</code> type.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">FuzzProcessRequest</span><span class="hljs-params">(f *testing.F)</span></span> {
  <span class="hljs-comment">// Create sample inputs for the fuzzer</span>
  testRequests := []Request{
    {Limit: <span class="hljs-number">-10</span>, Offset: <span class="hljs-number">-10</span>},
    {Limit: <span class="hljs-number">0</span>, Offset: <span class="hljs-number">0</span>},
    {Limit: <span class="hljs-number">100</span>, Offset: <span class="hljs-number">100</span>},
    {Limit: <span class="hljs-number">200</span>, Offset: <span class="hljs-number">200</span>},
  }

  <span class="hljs-comment">// Add to the seed corpus</span>
  <span class="hljs-keyword">for</span> _, r := <span class="hljs-keyword">range</span> testRequests {
    <span class="hljs-keyword">if</span> data, err := json.Marshal(r); err == <span class="hljs-literal">nil</span> {
      f.Add(data)
    }
  }

  <span class="hljs-comment">// ...</span>
}
</code></pre>
<p>After that we can use the <strong>httptest</strong> package to create a test HTTP server and make requests to it.</p>
<p>Note: Since our fuzzer can generate invalid non-JSON requests, it’s better just to skip them and ignore with <code>t.Skip()</code>. We can also skip <code>BadRequest</code> errors.</p>
<pre><code class="lang-go"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">FuzzProcessRequest</span><span class="hljs-params">(f *testing.F)</span></span> {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-comment">// Create a test server</span>
  srv := httptest.NewServer(http.HandlerFunc(ProcessRequest))
  <span class="hljs-keyword">defer</span> srv.Close()

  <span class="hljs-comment">// Fuzz target with a single []byte argument</span>
  f.Fuzz(<span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(t *testing.T, data []<span class="hljs-keyword">byte</span>)</span></span> {
    <span class="hljs-keyword">var</span> req Request
    <span class="hljs-keyword">if</span> err := json.Unmarshal(data, &amp;req); err != <span class="hljs-literal">nil</span> {
      <span class="hljs-comment">// Skip invalid JSON requests that may be generated during fuzz</span>
      t.Skip(<span class="hljs-string">"invalid json"</span>)
    }

    <span class="hljs-comment">// Pass data to the server</span>
    resp, err := http.DefaultClient.Post(srv.URL, <span class="hljs-string">"application/json"</span>, bytes.NewBuffer(data))
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
      t.Fatalf(<span class="hljs-string">"unable to call server: %v, data: %s"</span>, err, <span class="hljs-keyword">string</span>(data))
    }
    <span class="hljs-keyword">defer</span> resp.Body.Close()

    <span class="hljs-comment">// Skip BadRequest errors</span>
    <span class="hljs-keyword">if</span> resp.StatusCode == http.StatusBadRequest {
      t.Skip(<span class="hljs-string">"invalid json"</span>)
    }

    <span class="hljs-comment">// Check status code</span>
    <span class="hljs-keyword">if</span> resp.StatusCode != http.StatusOK {
      t.Fatalf(<span class="hljs-string">"non-200 status code %d"</span>, resp.StatusCode)
    }
  })
}
</code></pre>
<p>Our fuzz target has a single argument with a type <code>[]byte</code> that contains the full JSON request, but you can change it to have multiple arguments.</p>
<p>Everything is ready now to run our fuzz tests. When fuzzing HTTP servers, you may need to adjust the amount of parallel workers, otherwise the load may overwhelm the test server. You can do that by setting <code>-parallel=1</code> flag.</p>
<pre><code class="lang-bash">go <span class="hljs-built_in">test</span> --fuzz=Fuzz -fuzztime=10s -parallel=1
go <span class="hljs-built_in">test</span> --fuzz=Fuzz -fuzztime=30s
--- FAIL: FuzzProcessRequest (0.02s)
    --- FAIL: FuzzProcessRequest (0.00s)
        runtime error: <span class="hljs-built_in">integer</span> divide by zero
        runtime error: slice bounds out of range
</code></pre>
<p>And as expected, we will see the above errors uncovered.</p>
<p>We can also see the fuzz inputs in the <code>testdata</code> folder to see which JSON contributed to this failure. Here is a sample content of the file:</p>
<pre><code class="lang-bash">go <span class="hljs-built_in">test</span> fuzz v1
[]byte(<span class="hljs-string">"{"</span><span class="hljs-built_in">limit</span><span class="hljs-string">":0,"</span>offset<span class="hljs-string">":0}"</span>)
</code></pre>
<p>To fix that issue, we can introduce input validation and default settings:</p>
<pre><code class="lang-go"><span class="hljs-keyword">if</span> req.Limit &lt;= <span class="hljs-number">0</span> {
  req.Limit = <span class="hljs-number">1</span>
}
<span class="hljs-keyword">if</span> req.Offset &lt; <span class="hljs-number">0</span> {
  req.Offset = <span class="hljs-number">0</span>
}
<span class="hljs-keyword">if</span> req.Offset &gt; <span class="hljs-built_in">len</span>(all) {
  start = <span class="hljs-built_in">len</span>(all) - <span class="hljs-number">1</span>
}
<span class="hljs-keyword">if</span> end &gt; <span class="hljs-built_in">len</span>(all) {
  end = <span class="hljs-built_in">len</span>(all)
}
</code></pre>
<p>With this change, the fuzz tests will run for 10 seconds and exit without an error.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Writing fuzz tests for your HTTP services or any other methods is a great way to detect hard-to-find bugs. Fuzzers can detect hard-to-spot bugs that happen for only some weird unexpected input.</p>
<p>It’s amazing to see that fuzzing is a part of Go’s built-in testing library, making it easy to combine with regular tests. Note: prior to Go 1.18, developers used <a target="_blank" href="https://github.com/dvyukov/go-fuzz">go-fuzz</a>, which is a great tool for fuzzing as well.</p>
<h3 id="heading-resources"><strong>Resources</strong></h3>
<ul>
<li><p><a target="_blank" href="https://github.com/plutov/packagemain/tree/master/fuzz-testing-http-services">Source Code</a></p>
</li>
<li><p><a target="_blank" href="https://youtu.be/w8STTZWdG9Y">Fuzz Testing in Go</a></p>
</li>
<li><p><a target="_blank" href="https://go.dev/doc/security/fuzz/">Go Fuzzing</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
