<?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: Joyce Foster</title>
    <description>The latest articles on DEV Community by Joyce Foster (@joycefosterr).</description>
    <link>https://dev.to/joycefosterr</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%2F4071196%2F7529a0a0-2e89-42bc-a4f0-c952aaba0ecf.jpeg</url>
      <title>DEV Community: Joyce Foster</title>
      <link>https://dev.to/joycefosterr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joycefosterr"/>
    <language>en</language>
    <item>
      <title>The Smallest Fix With The Biggest Impact [Skips VS Technology Edition]</title>
      <dc:creator>Joyce Foster</dc:creator>
      <pubDate>Thu, 20 Aug 2026 09:11:15 +0000</pubDate>
      <link>https://dev.to/joycefosterr/the-smallest-fix-with-the-biggest-impactskips-vs-technology-edition-2id6</link>
      <guid>https://dev.to/joycefosterr/the-smallest-fix-with-the-biggest-impactskips-vs-technology-edition-2id6</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/bugsmash"&gt;DEV's Summer Bug Smash: Smash Stories&lt;/a&gt; powered by &lt;a href="https://sentry.io/" rel="noopener noreferrer"&gt;Sentry&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Remember that one Regular Show episode where Skips tried to destroy the park's computer because it caught the &lt;em&gt;Error 220&lt;/em&gt; bug? He took one look at it, picked up a sledgehammer and said the line we’ve all felt as devs: “ &lt;em&gt;There’s something evil in that computer. We gotta smash it&lt;/em&gt;”. In the cartoon, they literally smash the computer and this works to fix the bug. In real life? We don’t get sledgehammers. We get Github PRs.&lt;/p&gt;

&lt;p&gt;Last week, I almost felt like Skips. I found a one-line bug in an open source repo that could’ve broken Instagram webhook security. No hammer, no explosion, just one misindented ‘if’ statement and a missing test. This is the story of how the smallest fix had the biggest impact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-The Challenge&lt;/strong&gt;&lt;br&gt;
So what was my &lt;em&gt;Error 220&lt;/em&gt;? &lt;br&gt;
While contributing to the corsair open-source repo, I found a security breach in the Instagram webhook handler. Something about the verification flow felt off, so I started tracing it line by line. The code called &lt;code&gt;timingSafeEqual&lt;/code&gt; but the result was indecisive. I took an extensive look at it and that's when I saw it- The &lt;code&gt;if&lt;/code&gt; statement meant to guard the check was there, but &lt;code&gt;timingSafeEqual&lt;/code&gt; was indented wrong. It was meant to return the result of &lt;code&gt;timingSafeEqual&lt;/code&gt; to accept or reject the request, but it fell through instead. Although it was running, its return value wasn’t being used to control the flow. &lt;br&gt;
This bug was tiny-one mis-indented line- but it had a great impact. In JS, it is not considered an error and so it’s easy to miss. Webhook security relies on a signature check to prove a request. If timingSafeEqual isn’t actually enforcing it, an attacker could forge a webhook and it would be accepted. The entire protection could fall apart over one tab.&lt;br&gt;
&lt;a href="https://github.com/corsairdev/corsair/pull/759" rel="noopener noreferrer"&gt;View PR #759&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-The Fix&lt;/strong&gt;&lt;br&gt;
In fixing it, I opened &lt;code&gt;PR#759&lt;/code&gt; to correct the indentation so &lt;code&gt;crypto.timingSafeEqual&lt;/code&gt; would be inside the &lt;code&gt;if&lt;/code&gt; block and its boolean result would decide whether to return &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;. Prior to the fix, the function was calling &lt;code&gt;timingSafeEqual&lt;/code&gt; but then ignoring what it returned and continuing to execute anyway. The update makes it return instantly based on that result. If a signature doesn’t match, the request is rejected. In the same vein, it is accepted where it matches.&lt;/p&gt;

&lt;p&gt;This change, small but significant, reconnects the verification to the return value.  Consequently, the library actually enforces “only accepts requests signed by Instagram” instead of just running the check. This two-line difference restores the whole security guarantee and &lt;code&gt;PR #759&lt;/code&gt; has since been merged into the corsair repo, closing the gap for good. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-The Technical Breakdown&lt;/strong&gt;&lt;br&gt;
Here, Instagram signs every webhook with a secret key, and sends that signature in the request header. It is then the corsair's job to take the incoming payload, recreate the signature on our side, and compare it to the one Instagram sent. At this stage, &lt;code&gt;crypto.timingSafeEqual&lt;/code&gt; comes in. It is a &lt;code&gt;Node.js&lt;/code&gt; function made particularly for comparing secrets because it requires the same amount of time, whether they match or not. This prevents timing attacks.&lt;/p&gt;

&lt;p&gt;In the process of generating the comparison, the bug broke the last step, and due to the indentation, the results never actually returned. So, the function would always continue, whether the signatures matched or not. After &lt;code&gt;PR#759&lt;/code&gt;, I made the return value matter. If &lt;code&gt;timingSafeEqual&lt;/code&gt; says false, it rejects. If it says true, it accepts. Now the check actually gates the request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-The Lesson&lt;/strong&gt;&lt;br&gt;
What I am proud of: Recalling the Regular Show episode where the computer threw &lt;em&gt;Error 220&lt;/em&gt; and Skips immediately wanted to smash it. With this bug, it would’ve been just as easy to see the bad indentation, ignore it and let the webhook pass through anyway. I am proud that, like Skips, I decided to “smash” the bug by finding and fixing the indentation. This small choice positively restored the security.&lt;/p&gt;

&lt;p&gt;What I learnt: I learnt that running a security check isn’t the same as enforcing it. My code was checking the signature but not using the result. Technology is only effective when you act on what it tells you. &lt;code&gt;crypto.timingSafeEqual&lt;/code&gt; only mattered once I made its return value decide whether to accept or reject.&lt;/p&gt;

&lt;p&gt;Challenges I came across: The challenge was that it failed silently. Just like &lt;em&gt;Error 220&lt;/em&gt; didn’t crash the computer in Regular Show, the bug didn’t show any errors. The request still went through whether the signature was valid or not. I had to slow down, read the flow and make one precise fix. This made me pay attention to the tiniest of details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;-Before and After Comparison&lt;/strong&gt;&lt;br&gt;
Before: The webhook validation ran &lt;code&gt;timingSafeEqual&lt;/code&gt; but ignored the result, so all requests got through whether the signature matched or not.&lt;/p&gt;

&lt;p&gt;After: &lt;code&gt;PR#759&lt;/code&gt; makes the return value gate the request, so only valid Instagram webhooks are processed.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Error 220&lt;/em&gt; taught the Park crew that some problems just need to be smashed. &lt;code&gt;PR #759&lt;/code&gt; taught me that some problems just need to be seen. Not every fix has to be loud to matter. Sometimes the biggest impact comes from the smallest, most precise correction, one misindented line, caught and fixed, restoring an entire security guarantee. That's the smash bug story I'll remember.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>bugsmash</category>
      <category>security</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
