Urgent.News

What's breaking now, across thousands of outlets.

Tech

I built a QR code phishing scanner for our free API — and ended up writing a PNG decoder from scratch to make it work.

** ** The problem QR code phishing ("quishing") is one of the fastest-growing phishing vectors right now — Microsoft's 2026 report puts the year-over-year growth at 146% in Q1 alone, and QR codes now account for roughly 12% of all phishing attacks, up from under 1% in 2021. The attack specifically slips past text-based email filters, since the malicious URL is hidden inside an image. I wanted to…

QR code phishing, or "quishing," has been rapidly growing in popularity, with Microsoft reporting a 146% increase in the past quarter alone. This type of attack is particularly dangerous because it bypasses text-based email filters, hiding malicious URLs inside images. To combat this threat, I developed a QR code scanner that decodes QR codes from images and checks the resulting URL against a database of known malware and phishing sites.

This functionality was integrated into Presend's free API, allowing users to scan QR codes and verify their safety in a single call.

The challenge lay in creating a QR code decoder that worked with Presend's API, which is built using Cloudflare Workers. This environment has strict constraints, such as no filesystem access, no Node.js modules, and a strict size limit for scripts. While decoding JPEG images proved straightforward using the jsQR library, PNG decoding required a custom implementation due to the absence of built-in PNG support in Workers.

PNG files are compressed using the deflate algorithm, which meant that decompression needed to be handled manually. However, Cloudflare Workers provide a DecompressionStream API that uses the browser-standard Streams API, eliminating the need for an external zlib library. After decompressing the IDAT chunk, parsing the PNG chunk structure and handling the per-scanline filtering process were the remaining hurdles.

PNG files consist of several chunks, including IHDR for dimensions and color type, followed by one or more IDAT chunks containing compressed pixel data, and IEND to signal the end of the file. The filtering process involves a filter byte preceding each scanline, indicating how the bytes were transformed relative to neighboring rows. Reversing this filtering process required careful integer math to correctly reconstruct the original pixel values.

One crucial issue arose when testing the decoder with real QR code images. The majority of QR code generators, including the Python qrcode library used for testing, output 1-bit PNG images by default. This compression scheme uses only one bit per pixel, significantly reducing file size. However, my decoder had only been tested with 8-bit images and had not accounted for this scenario. This oversight could have rendered the entire feature useless, as most real-world QR codes are encoded in 1-bit format.

To fix this issue, I implemented support for sub-byte pixel packing, where multiple pixels are encoded within a single byte for bit depths less than 8. Additionally, I accounted for a specification detail that defines the "bytes per pixel" value as 1 for any bit depth under 8, regardless of the actual bit depth. This fix ensured that the decoder could accurately interpret 1-bit PNG images, enabling it to handle the vast majority of QR code images encountered in the wild.

The final product is a simple, free API endpoint that can decode both JPEG and PNG QR codes, including the edge case of 1-bit images. When the decoded content is a URL, the API checks it against URLhaus, a database of known malicious URLs, all within the same request. The code is open-source and available on GitHub, along with the specific implementation files: vendor/png-decoder.js and functions/api/qr-scan.js.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

Ahsan Iqbal Reveals Trick to Grow Economy

Federal Minister for Planning, Development, and Special Initiatives Ahsan Iqbal has declared that exports are a matter of “life and … Read More The post Ahsan Iqbal Reveals Trick to Grow Economy appeared first on ProPakistani .

More from Thursday 3 September →