<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Engineering Blog on </title>
		<link>https://entelecheia.io/engineering/</link>
		<description>Recent content in Engineering Blog on </description>
		<generator>Hugo</generator>
		<language>en-us</language>
		
		
		
		
			<lastBuildDate>Fri, 04 Sep 2026 00:00:00 +0800</lastBuildDate>
		
			<atom:link href="https://entelecheia.io/engineering/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>Hiding a String in a Numeric ID</title>
				<link>https://entelecheia.io/engineering/hiding-a-string-in-a-numeric-id/</link>
				<pubDate>Fri, 04 Sep 2026 00:00:00 +0800</pubDate>
				<guid>https://entelecheia.io/engineering/hiding-a-string-in-a-numeric-id/</guid>
				<description>&lt;p&gt;When designing IDs that a person may need to read, copy, type, or pass to someone else, usability matters as much as uniqueness. A lookup ID may have to be dictated over the phone, written down, or entered by hand. For arbitrary machine-generated lookup IDs, numbers are a particularly practical format for human communication. People already handle long numbers: credit card numbers are routinely read, copied, and dictated despite containing sixteen digits.&lt;/p&gt;&#xA;&lt;p&gt;Numbers are also easier to speak than arbitrary letters and symbols. There is no need to distinguish &amp;ldquo;B&amp;rdquo; from &amp;ldquo;D,&amp;rdquo; explain capitalization, or say whether a character is the letter &amp;ldquo;O&amp;rdquo; or the digit &amp;ldquo;0.&amp;rdquo; A number can be read aloud.&lt;/p&gt;&#xA;&lt;p&gt;For this reason we use a twenty-digit numeric lookup ID, written in four groups of five digits. The grouping makes the number easier to scan and check, following the same general principle as a credit card:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;12505-89847-63568-88524&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;A lookup ID such as this looks like nothing more than a random string of digits. But the number itself can carry a small amount of hidden information. If designed correctly, this eliminates the need for the server to maintain a separate table mapping every ID to metadata.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Shoulder Surfing QR Code: A Defense</title>
				<link>https://entelecheia.io/engineering/qrcode-shoulder-surfing/</link>
				<pubDate>Tue, 04 Aug 2026 00:00:00 +0800</pubDate>
				<guid>https://entelecheia.io/engineering/qrcode-shoulder-surfing/</guid>
				<description>&lt;p&gt;QR codes are a convenient way to pair a mobile device with a desktop application or a web application running on the desktop: the desktop displays a code, and the phone scans it. But scanning the code does not prove which device scanned it.&lt;/p&gt;&#xA;&lt;p&gt;Imagine an attacker standing nearby, watching through a hidden camera, or watching a screen share in an online meeting, who scans the pairing code with his own phone before the legitimate user does. Without another authentication step, the desktop could end up connected to the attacker&amp;rsquo;s phone instead of the user&amp;rsquo;s.&lt;/p&gt;&#xA;&lt;p&gt;That can open the door to a social-engineering attack. An attacker who controls what appears in the paired session may impersonate contacts or otherwise manipulate the user into revealing sensitive information.&lt;/p&gt;&#xA;&lt;p&gt;So how do you protect against this when the attacker can see almost everything? Assume he can observe the desktop screen, the phone screen, and the keyboard, and can scan any QR code shown on the monitor. With his own phone, he can do anything the user can do.&lt;/p&gt;&#xA;&lt;p&gt;The only things he cannot do are physically operate the user&amp;rsquo;s phone or type on the user&amp;rsquo;s keyboard. Those are the only two meaningful advantages the legitimate user has. The pairing process has to build on them.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Sanitizing PDFs Uploaded by Users</title>
				<link>https://entelecheia.io/engineering/sanitizing-pdf/</link>
				<pubDate>Sat, 11 Jul 2026 00:00:00 +0800</pubDate>
				<guid>https://entelecheia.io/engineering/sanitizing-pdf/</guid>
				<description>&lt;p&gt;PDFs uploaded by users should be treated as untrusted files. A document may have come from a scanner or a word processor, but a PDF is capable of containing much more than the text and images visible on its pages.&lt;/p&gt;&#xA;&lt;p&gt;A valid PDF can include JavaScript, actions that run when the document is opened, embedded files, annotations, rich media, and references to external resources. Some of these features can cause a PDF reader to perform actions the user did not expect. A maliciously constructed file can also be unusually expensive to parse or exploit weaknesses in the software processing it.&lt;/p&gt;&#xA;&lt;p&gt;The goal is to remove everything we do not need and leave only the document itself. We sanitize the PDF on the uploader&amp;rsquo;s device, before sending it anywhere else, so that downstream systems receive a newly created document rather than the original file. The original PDF is treated as potentially hostile input and is never passed through unchanged.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Sanitizing Images Uploaded by Users</title>
				<link>https://entelecheia.io/engineering/sanitizing-jpeg/</link>
				<pubDate>Sat, 04 Jul 2026 00:00:00 +0800</pubDate>
				<guid>https://entelecheia.io/engineering/sanitizing-jpeg/</guid>
				<description>&lt;p&gt;Images uploaded by users should be treated as untrusted files. We focus on JPEG because, in most cases, an image uploaded by a user can simply be converted to JPEG first (if it&amp;rsquo;s not yet a JPEG). A JPEG may have been produced by a normal camera or phone, but it may also have been deliberately constructed to exploit a bug in an image parser, consume excessive memory, or carry data that has nothing to do with the picture.&lt;/p&gt;&#xA;&lt;p&gt;Simply checking that a file has a &lt;code&gt;.jpg&lt;/code&gt; extension is obviously not enough. Even a valid JPEG can contain unexpected metadata, embedded thumbnails, comments, and other structures. It can also be a decompression bomb: a relatively small file that expands into an enormous bitmap when decoded.&lt;/p&gt;&#xA;&lt;p&gt;The goal is to sanitize the image so that a later consumer of the picture gets a file without those exploits. We do that on the device of the user who uploads it, before the file goes anywhere else. If the JPEG exploits a parser bug, consumes too much memory, or otherwise misbehaves, it is his application that has to deal with it.&lt;/p&gt;&#xA;&lt;p&gt;We&amp;rsquo;ll take this case by case in the next sections: first a basic filter on the file, then a dimension check &lt;em&gt;before&lt;/em&gt; decoding, then redrawing the picture onto a new canvas.&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
