{
    "archive_path": "archive/1776557235.937238",
    "base_url": "hudlow.org/2026/practical-antiforgery",
    "basename": "practical-antiforgery",
    "bookmarked_date": "2026-04-19 00:07",
    "canonical": {
        "archive_org_path": "https://web.archive.org/web/hudlow.org/2026/practical-antiforgery",
        "dom_path": "output.html",
        "favicon_path": "favicon.ico",
        "git_path": "git/",
        "google_favicon_path": "https://www.google.com/s2/favicons?domain=hudlow.org",
        "headers_path": "headers.json",
        "htmltotext_path": "htmltotext.txt",
        "index_path": "index.html",
        "media_path": "media/",
        "mercury_path": "mercury/content.html",
        "pdf_path": "output.pdf",
        "readability_path": "readability/content.html",
        "screenshot_path": "screenshot.png",
        "singlefile_path": "singlefile.html",
        "warc_path": "warc/",
        "wget_path": null
    },
    "domain": "hudlow.org",
    "downloaded_at": "2026-04-19T00:07:21.593446+00:00",
    "downloaded_datestr": "2026-04-19 00:07",
    "extension": "",
    "hash": "19Q7CT92TWE15ZFE1F63",
    "history": {
        "archive_org": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--head",
                    "--max-time",
                    "60",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://web.archive.org/save/https://hudlow.org/2026/practical-antiforgery"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2026-04-19T00:08:45.191366+00:00",
                "index_texts": null,
                "output": "https://web.archive.org/web/20260419000826/https://hudlow.org/2026/practical-antiforgery",
                "pwd": "/data/archive/1776557235.937238",
                "schema": "ArchiveResult",
                "start_ts": "2026-04-19T00:08:23.250483+00:00",
                "status": "succeeded"
            }
        ],
        "dom": [
            {
                "cmd": [
                    "/usr/bin/chromium-browser",
                    "--proxy-server=socks5://tor-socks-proxy:9150",
                    "--disable-features=DarkMode",
                    "--run-all-compositor-stages-before-draw",
                    "--hide-scrollbars",
                    "--autoplay-policy=no-user-gesture-required",
                    "--no-first-run",
                    "--use-fake-ui-for-media-stream",
                    "--use-fake-device-for-media-stream",
                    "--simulate-outdated-no-au='Tue, 31 Dec 2099 23:59:59 GMT'",
                    "--headless=new",
                    "--no-sandbox",
                    "--no-zygote",
                    "--disable-dev-shm-usage",
                    "--disable-software-rasterizer",
                    "--disable-sync",
                    "--window-size=1440,2000",
                    "--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "--user-data-dir=/data/personas/Default/chrome_profile",
                    "--profile-directory=Default",
                    "--dump-dom",
                    "https://hudlow.org/2026/practical-antiforgery"
                ],
                "cmd_version": "131.0.6778",
                "end_ts": "2026-04-19T00:07:55.772615+00:00",
                "index_texts": null,
                "output": "output.html",
                "pwd": "/data/archive/1776557235.937238",
                "schema": "ArchiveResult",
                "start_ts": "2026-04-19T00:07:32.281432+00:00",
                "status": "succeeded"
            }
        ],
        "favicon": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--max-time",
                    "60",
                    "--output",
                    "favicon.ico",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://www.google.com/s2/favicons?domain=hudlow.org"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2026-04-19T00:07:25.150150+00:00",
                "index_texts": null,
                "output": "favicon.ico",
                "pwd": "/data/archive/1776557235.937238",
                "schema": "ArchiveResult",
                "start_ts": "2026-04-19T00:07:21.877439+00:00",
                "status": "succeeded"
            }
        ],
        "git": [],
        "headers": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--head",
                    "--max-time",
                    "60",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://hudlow.org/2026/practical-antiforgery"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2026-04-19T00:07:25.259310+00:00",
                "index_texts": null,
                "output": "headers.json",
                "pwd": "/data/archive/1776557235.937238",
                "schema": "ArchiveResult",
                "start_ts": "2026-04-19T00:07:25.178333+00:00",
                "status": "succeeded"
            }
        ],
        "htmltotext": [
            {
                "cmd": [
                    "(internal) archivebox.extractors.htmltotext",
                    "./{singlefile,dom}.html"
                ],
                "cmd_version": "0.8.5rc51",
                "end_ts": "2026-04-19T00:08:15.720960+00:00",
                "index_texts": [
                    "hudlow.org: Practical Antiforgery in Software Design (/favicon.ico?v1) (/style.css)  (/) hudlow.org  (https://github.com/hudlow)  hudlow on GitHub   (/feeds/atom)  subscribe to feed     \u2693\ufe0e\ufe0e Practical Antiforgery in Software Design \u2693\ufe0e\ufe0e Dan Hudlow / April 2026 If you are fortunate enough to tour the Fort Worth campus of the United States (https://bep.gov) Bureau of Engraving and Printing , you\u2019ll get a primer on the techniques\nthe BEP uses to make it difficult to replicate U.S. paper currency. But if you\nask the staff of the BEP\u2019s on-site museum to name the discipline that comprises\nthese techniques, the answer you\u2019ll get is \u201ccounterfeiting deterrence.\u201d Such a\ncumbersome designation is unfortunate, because it\u2019s hard to fully develop and\nappreciate an idea for which we lack a nomenclature. And this matters because these concepts are relevant, often vital, to all kinds\nof interactions we have both in the physical world and the digital realm. My\ngoal is to establish a taxonomy, demonstrate the crucial importance, and propose\nsome best practices in applying these ideas to software design. Let\u2019s start with a wieldier name for this discipline: antiforgery . \u2693\ufe0e\ufe0e Security, Cryptography, and Antiforgery A student of the software industry might, at this point, be confused. Aren\u2019t\nthese practices, in the software world, just called security? Moreover, aren\u2019t\nthe digital equivalents of the BEP\u2019s myriad printing techniques just cryptography?  In fact, in BEP jargon, \u201csecurity\u201d is synonymous with counterfeiting\ndeterrence; with what we\u2019re calling antiforgery. But outside of currency\ndesign \u201csecurity\u201d has a much broader meaning. A bank has security concerns that\ngo beyond forged currency or documents. Such as, quintessentially, robbery . And in the software field, a lot of what we call \u201csecurity\u201d is focused on \nthreats that are more like robbery than counterfeiting and defenses that are\nmore like locksmithing than intaglio printing.  So \u201csecurity\u201d is too broad. What about \u201ccryptography\u201d? While much of\ncryptography is certainly devoted to antiforgery, a lot of it is devoted to secrecy also. But there\u2019s a bigger gap we need to examine, and to do that,\nlet\u2019s go back to currency design. \u2693\ufe0e\ufe0e Technical vs. Practical The antiforgery techniques implemented by the BEP actually have two distinct\ngoals: one technical , and one practical . The technical goal is to make it\ndifficult to exactly replicate currency. The practical goal is for any attempt\nat replication to alert even the casual observer. Technical antiforgery requires exclusive access, knowledge, skills, materials,\nor technologies which are unavailable to a would-be counterfeiter. Practical\nantiforgery uses those technical capabilities to produce hard-to-replicate\nelements that are tangible and unmistakable. Cryptography, then, can provide technical antiforgery, but it is ultimately up\nto user interfaces to deliver practical antiforgery. It\u2019s all too easy, however, for conversations about antiforgery to both start\nand end with the technical. This makes sense where intractable technical\nfailures exist, as they do for personal checks, caller ID, and email. After all,\nit is usually incoherent 1  to seek practical antiforgery in the\nabsence of a technical foundation. But too often, even when an industry spends billions of dollars solving the\ntechnical problems, the practical side is neglected. In reality, technical\nantiforgery without practical antiforgery is also often moot.  Those boffins at the BEP know it\u2019s not feasible to have an expert (or a\nsophisticated machine) examine every bill in every cash transaction. It\u2019s not\nenough to make forgery difficult or even (technically ) impossible: we also\nmust make authenticity obvious. We need practical antiforgery.  \u00a9 2026 Dan Hudlow    \u2693\ufe0e\ufe0e A Study in Failure Before we apply these ideas to software, I\u2019d like to take a detour through some\nother domains where practical antiforgery is needed. And where U.S. currency\nrepresents success, it\u2019s important we also know what failure looks like. We don\u2019t have to look far: acute failures exist even in disciplines immediately\nadjacent 2  to currency design. In 2010, following a spate of frauds\nachieved with card skimmers affixed to ATMs, noted designer (https://www.subtraction.com/2010/08/17/take-the-money-and-stand-still/) Khoi Vinh observed: The fact of the matter is, the superfluously futuristic form of these machines\nis so nonsensical, so utterly impractical and useless that even a quickly\ngrafted foreign appendage like a skimmer is indistinguishable from the native\nhardware.  In the sixteen years since Vinh wrote this, banks have made (https://www.apple.com/newsroom/2014/09/09Apple-Announces-Apple-Pay/) massive (https://blog.google/products-and-platforms/platforms/google-pay/announcing-google-pay/) investments in the technology of securely transmitting banking\ninformation. And these efforts recognize the technical failures of magnetic\nstrips and reusable credit card numbers to prevent fraud. Yet, ATMs at major U.S. banks still look improvised with parts salvaged from a\nSoviet cosmodrome. The aesthetic is easily replicated by parasitic hardware,\nwith blank panels and mismatched finishes that almost seem to dare enterprising\ncriminals into action.  (ATM) An ATM outside a national bank branch \u00a9 2026 Dan Hudlow    \u2693\ufe0e\ufe0e Conditioning Gas pumps are even worse. To the parts-bin hardware aesthetic, they add a\nhaphazard array of stickers, often including QR codes. If camouflaging a card\nskimmer is easy, adding a sticker with a QR code for a phishing site is trivial. Until recently, 3  you\u2019d even see ostensibly legitimate QR code\nstickers at gas pumps (https://www.nfcw.com/2020/10/22/368814/exxonmobil-to-combine-nfc-and-qr-mobile-payments-at-the-pump/) actually soliciting payment with (https://www.nbcnews.com/tech/tech-news/qr-code-scams-on-the-rise-rcna221345) predictable results . This destructive conditioning is insidious and difficult to unwind. Having\ntrained customers that a QR code on a sticker is a reasonable payment method, any gas pump is vulnerable to this attack, whether or not that specific pump\never solicited payment via sticker.   (gas pump) A gas pump at a franchisee of a national chain \u00a9 2026 Dan Hudlow    \u2693\ufe0e\ufe0e Continuity, Context, and Trust The practical defense for these ATMs and gas pumps is continuity . A simplified\nphysical interface without unnecessary seams, gaps, protrusions, or decals is\nmuch more resistant to forgery. Moreover, when an ATM is bricked into the side of a local bank, continuity\nbetween the bank\u2019s architecture and the entirety of the ATM\u2019s physical interface\nallows the customer to trust the ATM. And we can generalize these ideas. The opportunity for forgery always exists in\nsome context , whether that\u2019s a bank in someone\u2019s neighborhood or a text\nmessage thread on his smartphone. When a context is itself resistant to\nreplication (as an entire bank branch is), we can say that it\u2019s trustworthy . But here, we must be careful not to destructively condition users to trust  a\ncontext that\u2019s not actually resistant to forgery. There\u2019s a trope in spy fiction where a character wakes up in a hospital room\nwith a TV blaring a newscast which, along with the hospital room itself, turns\nout to be a ruse recreated in a warehouse to elicit information from the\n\u201cpatient.\u201d These scenes are fantastical, but they illustrate a real\nvulnerability.   A not-so-trustworthy context in Mission Impossible: Fallout (2018)   \u2693\ufe0e\ufe0e More Contexts Especially where any kind of technology is involved, the trustworthiness of\nsomeone\u2019s context isn\u2019t just a matter of \u201cwhere\u201d she is, but also how she got\nthere. Interactions over the phone drive this point home. There\u2019s an important difference between an incoming call, which is easily\nforged, and an outgoing call placed to the number on the back of a credit card.\nEven if both calls result in a conversation with a reassuring banker, dialing\nthe number provides vital continuity between a trustworthy context (a physical\ncredit card) and that phone conversation. Here too, major financial institutions often do a bad job of helping their\ncustomers understand this distinction, with agents often asking for sensitive\ninformation on calls which they placed. And, as with QR-code payment stickers,\nthis destructive conditioning threatens a customer\u2019s interactions with all of\ntheir financial institutions.  (call context) \u00a9 2026 Dan Hudlow    \u2693\ufe0e\ufe0e More Conditioning Frequently, conscientious organizations implement constructive conditioning .\nThis can be passive via acclimating customers to aesthetics, materials,\nprocedures, or conventions that are hard to replicate (even if the technical\nreasons why they\u2019re hard to replicate aren\u2019t intuitive). Constructive conditioning can also be active , such as when a text message\nwith an authentication code includes a warning not to share it with anyone. Unfortunately, organizations are often inconsistent. In a recent transaction\nwith a national insurance company, my wife was repeatedly asked by employees for\na code that was delivered with such a warning. This hypocrisy results in subversive conditioning . Not only is a customer\nconditioned to do something unsafe; in the process they\u2019re immunized to\nconstructive conditioning. Perhaps the most acute form of subversive conditioning I\u2019ve personally\nexperienced was at the hands of a corporate bureaucracy that delivered mandatory\n\u201ccybersecurity awareness\u201d training in emails which bore all the marks of\nphishing attacks.  (second factor) \u00a9 2026 Dan Hudlow    \u2693\ufe0e\ufe0e Spatial Exclusivity Software is especially dependent on constructive conditioning to deliver\npractical antiforgery. Because software manifests chiefly as pixels on a screen,\nit can\u2019t exploit intuitions about quality 4  in the same way\nthat a finely crafted physical object can. Software generally must rely on spatial exclusivity to differentiate trustworthy and forgeable contexts. Nowhere is this distinction more \nimportant than in a web browser, where the browser\u2019s own interface elements 5  are inherently trustworthy but the content displayed isn\u2019t. Indeed, the conditioning of users to understand a web browser\u2019s exclusive\ncontrol over its address field is the foundation of the entire Internet economy.\nBuilding on the technical underpinnings of DNS and TLS, a browser\u2019s address\nfield is widely understood to be authoritative and tamper-proof. Importantly,\nthe continuity the browser provides between the address field and the\ncorresponding web page allows users to trust a web page based on its domain\nname. Current versions of Mozilla Firefox and Google Chrome follow similar\nconventions, helping constructive conditioning transfer between the two\nbrowsers. Historically, Apple\u2019s Safari has taken the most holistic and thoughtful\napproach to solving this problem. By default, Safari simplifies the address\nitself to the trustworthy portion, and it keeps all of the browser\u2019s trustworthy\nzones contiguous. Regrettably, Safari 26 on macOS Tahoe has compromised this\nadvantage by blending the browser\u2019s toolbar with forgeable content. 6    (browser chrome) Forgeable areas of web browsers shaded in red \u00a9 2026 Dan Hudlow    \u2693\ufe0e\ufe0e Subtle Subversion In addition to the passive conditioning that has taught users the relationship\nbetween the address field and the content, modern browsers implement active\nconditioning for web sites that don\u2019t use TLS because the address field, in this\ncase, should not confer trust to the content area.  (not secure) Active constructive conditioning \u00a9 2026 Dan Hudlow    But if a website presents the browser with an invalid certificate, something\ngoes horribly wrong. Two of the three major browsers implement active\nconditioning in the address field and also present authoritative information\nin the content area. Google Chrome\u2019s behavior is particularly egregious, as it even presents a\ncall-to-action to get the \u201chighest level\u201d of security. It\u2019s frustrating enough when subversive conditioning is the result of a\nsprawling bureaucracy\u2019s only-human inability to behave consistently with its\nstated policies. Here, Google Chrome implements subversive conditioning in a\ntidy, self-contained package. Only Apple\u2019s Safari seems to understand the sacred relationship between the\naddress field and the browser content area, opting not to present a warning in\nthe address field when the browser itself takes over the content area. 7    (tls-error) Subversive conditioning in Mozilla Firefox and Google Chrome \u00a9 2026 Dan Hudlow    \u2693\ufe0e\ufe0e Good Intentions Another example of destructive conditioning I experienced in corporate life was\nan \u201cexternal sender\u201d warning for emails. Because this was implemented on the\nserver side, warnings were necessarily part of the email content , acclimating\nusers to responding to a security-minded call-to-action within a forgeable part\nof the interface. This is marginally more sympathetic, because the team at Microsoft that\nimplemented support for (https://learn.microsoft.com/en-us/exchange/security-and-compliance/mail-flow-rules/disclaimers-signatures-footers-or-headers) those warnings probably didn\u2019t have\nthe prerogative to change the Outlook interface. 8  But, it\u2019s still\nmisguided and self-defeating to ask users to trust something so easily forged no matter how sketchy the rest of an email is.  (outlook) A security warning within the forgeable zone \u00a9 2026 Dan Hudlow    \u2693\ufe0e\ufe0e Tragic Irony The well-meaning but misguided efforts of those tasked with making businesses\nmore secure are often the worst offenders. Corporate \u201cdevice management\u201d and\n\u201cendpoint security\u201d services are strikingly bad at sensing the destructive\neffects of acclimating users to an ever-shifting suite of shady-looking software\nappearing on their laptops. These utilities often have opaque and vaguely malevolent names and request or\nare deployed with broad and dangerous levels of system access. Sometimes, they\ntrigger software updates that present users with spontaneous, context-free\nprompts for system passwords. This is destructive conditioning analogous to\ncalling customers on the phone and asking for sensitive information.   (installer) Spontaneous password prompts result in destructive conditioning \u00a9 2026 Dan Hudlow    \u2693\ufe0e\ufe0e Hostile Takeovers Smartphones present special challenges because pixel space is so precious and it\nis typical for a single app to control the entire screen. For a browser to offer websites the ability to control the whole screen and\nthereby forge any part of any interface would seem nakedly foolish. Indeed,\nApple\u2019s Safari eschews support for the (https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API) web standard enabling fullscreen\nwebsites unless a user has added a site to their home screen as a\npseudo-app. Surprisingly, Chrome on Android does support fullscreen websites, mitigating\nthe risk only with some temporary fine print in a floating component that\u2019s\neasily lost in an interface transition.   Right: a website forging the browser chrome\u00a9 2026 Dan Hudlow    \u2693\ufe0e\ufe0e Two Steps Forward, One Step Back Password managers represent a big leap forward in translating technical\nantiforgery into practical antiforgery. This is accomplished by the password\nmanager matching credentials to a website before it autofills them, such that\neven if a forged site fools the user, their password manager won\u2019t transmit\ntheir legitimate credentials. But even 1Password, undeniably a leader in both technical prowess and adoption 9  , sometimes succumbs to presenting forgeable interfaces. For\nexample, with the macOS app and Chrome extension both installed, a user can\ninvoke 1Password\u2019s signature password prompt from a forgeable context (a web\npage), presenting her with a floating window that can be forged inside the\ncontent area of the browser.   Right: a website replicating the 1Password unlock prompt\n    / (./practical-antiforgery/demo/1password) View demo \u00a9 2026 Dan Hudlow    \u2693\ufe0e\ufe0e Personalization Rather than depending on spatial exclusivity, an interface can be personalized in a way that makes it harder to forge. Personalization is analogous to the\n\u201csigns\u201d and \u201ccountersigns\u201d often used in spy stories: just as an agent knows not\nto reveal the countersign unless first prompted with the sign, a user is\nconditioned to distrust an interface unless it is personalized. The 1Password prompt in the above example actually is personalized, albeit not\nvery effectively. The user\u2019s email address is displayed, but only when hovering\nover the avatar, and the avatar itself can be customized, but only for\nindividual accounts, not for the family subscription I use. But even aside from these unforced errors, personalization as an antiforgery\ntechnique requires us to exercise a lot of caution. It\u2019s crucial to understand\nhow easy it is for personalization to result in destructive conditioning. Indeed, in an entirely unauthenticated context (like most login screens on the\nweb), personalization is completely useless. Even if an application first asks a\nuser to assert her identity (an email address, for example), so it can present a\npersonalized interface before asking for her password, nothing keeps an attacker\nfrom using the same flow to derive the personalized elements from the user\u2019s\nidentity. And even when personalization is limited to partially authenticated users (as is\nthe case for 1Password 10  ), it may be difficult to\nelicit or produce personalized elements that are sufficiently difficult to\nobtain (avatars, for example, don\u2019t tend to be very private) and to condition\nusers to rely on those elements to establish trust. 11     A sign / countersign exchange in television\u2019s Get Smart (1965)   \u2693\ufe0e\ufe0e Best Practices As an industry, we clearly still have a long way to go in applying the\nprinciples of practical antiforgery to software design. Doing so requires\ncritical thought, attention to detail, and vigilance. But especially for anyone lost or overwhelmed, I\u2019d like to propose a few best\npractices: In designing any interface or interaction, carefully analyze how you can\nsignal authenticity to your users. For example, render on part of the screen that a forgery cannot.   Pay special attention when prompting a user to return to your application.  For example, consider using push notifications instead of text messages or \nemails.  Applying the broader principle of (https://csrc.nist.gov/glossary/term/defense_in_depth) defense-in-depth , don\u2019t allow a system\nto rely too heavily on one or two signals of authenticity. Instead, give\nusers as many meaningful signals as you can that something is trustworthy. For example, encourage users to pick a custom accent color for your site and\nmake sure that accent color is always visible when they\u2019re logged in.  Conversely, eliminate as much authenticity noise (signals that do not\ndemonstrate authenticity) as possible. For example, use short, readable URLs that don\u2019t obfuscate your domain\nname.  If you condition a user to trust a signal, do everything in your power to\nmake that signal unobtainable to forgeries. For example, constrain the formatting options for user-generated content so\nit can\u2019t replicate parts of your application\u2019s interface.  If you condition users to distrust a signal, be vigilant that you never,\never contradict yourself.  For example, if you implore users to only enter their passwords on your\nwebsite, don\u2019t ship a phone app that prompts for a password.      \u2693\ufe0e\ufe0e The Future There are also some things I\u2019m looking forward to. The adoption of passkeys, in\nparticular, continues the trend started by password managers of translating\ntechnical advances into real practical gains. There\u2019s an opportunity for new ideas and techniques for antiforgery in\nsoftware that go beyond spatial exclusivity. Apple uses one such technique in\nthe way it presents Apple Pay Cash payments 12  in its Messages app: an\niridescent effect that reacts to accelerometer inputs in a way that a texted\nimage could not. I\u2019d love to see more hardware features used to signal the authenticity of an\ninteraction. This could be screen technology, like (https://www.samsung.com/sg/support/mobile-devices/how-to-use-privacy-display-on-the-samsung-galaxy-s26-ultra/) Samsung\u2019s new privacy\ndisplay or the lenticular displays used on the front of the\nApple Vision Pro. I can also imagine using exclusive haptics or personalized\nsound effects. There are many possibilities, especially for companies that can\ncontrol both hardware and software.   Antiforgery via motion reactivity\u00a9 2026 Dan Hudlow    Most of all, I hope to encourage more engineers to consider, discuss, and debate\nthese ideas. It\u2019s especially important that platform and browser vendors take\nseriously the need for practical antiforgery. And purveyors of security-centric\nsoftware and services need to take a hard look at where they may be doing more\nharm than good. I believe we need to move both the median approach and the state of the art\nforward. The stakes are too high for us to keep getting this wrong. I hope to\nwrite more on this topic in the future, so if you have any thoughts or ideas\nyou\u2019d like me to consider, please (mailto:dan@hudlow.org) reach out .    In Review Occasional updates from Dan Hudlow (you@example.com) (Subscribe)   Footnotes For example, it doesn\u2019t matter if it\u2019s easy to distinguish\nbetween a common material and an unusual one if the unusual material isn\u2019t\nalso difficult to acquire. One could argue that trademarks are an exception here: that Coca-Cola isn\u2019t\ntechnically difficult to replicate (i.e., Pepsi tastes like Coke) but it\u2019s\npractically difficult to replicate because Pepsi can\u2019t legally call a drink\n\u201cCoca-Cola.\u201d But we\u2019ll limit our discussion to forgery efforts unencumbered by legal\nbarriers as counterfeiting currency, for example, necessarily is. \u21a9\ufe0e   In the sense that an ATM includes machinery to authenticate currency. \u21a9\ufe0e   They\u2019ve disappeared from my local pumps, but it\u2019s hard to say if this is\nrepresentative. \u21a9\ufe0e   It\u2019s not entirely true to say that tangibly high-quality software can\u2019t be\nproduced with exclusive capabilities, but those capabilities aren\u2019t\nwell-correlated to legitimacy or monetary resources and very few businesses\nof any size or in any market sector possess them. \u21a9\ufe0e   The term of art for these elements is the browser\u2019s \u201cchrome\u201d but the\nbranding of a certain web browser overloads this word. \u21a9\ufe0e   There\u2019s some tension in the point I\u2019m making here. I just finished saying\nthat web browsers offer an advantageous continuity between the address\nfield and the web content, and now I\u2019m complaining about inadequate contrast\nbetween these contexts. This apparent contradiction is reflective of the balancing act that a web\nbrowser has to perform. On the one hand, the relationship between the\naddress and the content needs to be visually clear and tamper resistant. In this sense , continuity is needed. On the other hand, the distinction\nbetween a context that is always trustworthy and a context which we know is sometimes untrustworthy must also be clear. In this sense contrast is\nneeded. \u21a9\ufe0e   The implication actually yielded is that it\u2019s google.com, and not Safari,\nthat\u2019s warning the user of a problem. I doubt Apple frets too much about an\nunsophisticated user coming away with that impression. \u21a9\ufe0e   Plus, plenty of other email clients support Exchange, and the developers\nmight not have anticipated administrators incorporating a call to action. \u21a9\ufe0e   I shared a draft of this piece with 1Password and received this feedback: We agree that trust boundaries in security-sensitive interfaces are an\nimportant topic. It\u2019s also important to recognize that browser extensions,\nby design, operate alongside arbitrary and potentially hostile web\ncontent. We do not have control over what malicious websites choose to\nrender, and any site can visually imitate interface elements presented\nwithin or adjacent to page content. That\u2019s a broader phishing and\nuser-deception risk inherent to the web ecosystem, rather than a\nproduct-specific vulnerability. That said, phishing resistance has been consciously incorporated into our\nlock screen design for years. For example, hovering over an account avatar\non the authentic lock screen reveals the associated email address, and we\ndisplay the user\u2019s chosen account icon where applicable. These dynamic\nelements are not something a generic phishing page would typically know or\nreplicate, and they provide users with authenticity cues within the\nbrowser context. It\u2019s also worth noting that under our security model, even if a user were\ndeceived into entering a password, a password alone is insufficient for\naccount takeover without the Secret Key.  I appreciate the effort they gave to a response (and, separately, their help\nin confirming that the avatar on a family account cannot be customized), but\ndon\u2019t find the actual answers very satisfying. Please also make note of my disclosures concerning 1Password. \u21a9\ufe0e   1Password is actually unusually well-suited to personalization, because of\nits (https://agilebits.github.io/security-design/apsk.html) key-and-password\narchitecture . \u21a9\ufe0e   I suppose the platonic ideal here would be to condition users to have a\nPavlovian response to the personalized prompt such that they can\u2019t even\nbring the password to mind without it. \u21a9\ufe0e   One has to think the conceptual proximity to currency design inspired this\nunusual burst of creativity to be applied to the problem. \u21a9\ufe0e     \u2693\ufe0e Acknowledgements I owe a lot to (https://www.subtraction.com) Khoi Vinh for planting the seeds and giving me sixteen years\nto ponder this space. I\u2019d also like to thank (mailto:meem@gnu.org) Peter \u201cmeem\u201d Memishian and (https://handrews.github.io) Henry Andrews for their\nincisive reviews that significantly shaped the content of this piece.  \u2693\ufe0e Disclosures I\u2019ve used iOS and Safari for as long as they\u2019ve existed (which necessarily means\nI\u2019m an Apple customer), and have also been a 1Password customer for many years.\nI do not use Android, Chrome, or any Microsoft email products, but I am a paying\ncustomer of other Google and Microsoft products. Weirdly enough, during the course of writing this, I gave 1Password a chance to\ncomment on a draft, and then subsequently and coincidentally applied for a job\nat 1Password, interviewed, and was ultimately rejected. This created a few\nethical hazards: As long as I thought the job was still on the table, I could appear to be\nincentivized to flatter 1Password, soften my critique of their product, or\npostpone publication. (Although only if I had a low opinion of their integrity.) Now that I\u2019ve been rejected, I could appear to be incentivized to treat\n1Password vindictively. Lastly, during the period that I was both in the running for the job and\nhad already presented 1Password with a draft, it could have given the\nappearance that I was offering 1Password an opportunity to influence what I\nwrote if they hired me.  Ideally, I would have published before I applied for the job which would\nhave simplified this disclosure, but I just wasn\u2019t ready. I\u2019ve tried to\nmitigate these conflicts in several ways: I have not adjusted the wording with which I introduced 1Password since\nbefore I had any intention of applying for a job. I was careful not to mention the draft to anyone I interacted with\nregarding the job, and I think it very unlikely anyone at 1Password would\nhave been aware of both my communication about the draft and my job\napplication. I was resolved that I would publish this piece before accepting an offer at \n1Password, and give 1Password an opportunity to rescind the offer if they\nchose to.  It\u2019s also relevant that all my interactions with 1Password have been pleasant\nand I have no reason to believe they would be peeved or threatened by anything\nI\u2019ve written. But there\u2019s still a lot here that you\u2019ll have to take my word for\nwhich is why I consider this disclosure to be crucial.        "
                ],
                "output": "htmltotext.txt",
                "pwd": "/data/archive/1776557235.937238",
                "schema": "ArchiveResult",
                "start_ts": "2026-04-19T00:08:15.685281+00:00",
                "status": "succeeded"
            }
        ],
        "media": [
            {
                "cmd": [
                    "/usr/local/bin/yt-dlp",
                    "--restrict-filenames",
                    "--trim-filenames",
                    "128",
                    "--write-description",
                    "--write-info-json",
                    "--write-annotations",
                    "--write-thumbnail",
                    "--no-call-home",
                    "--write-sub",
                    "--write-auto-subs",
                    "--convert-subs=srt",
                    "--yes-playlist",
                    "--continue",
                    "--no-abort-on-error",
                    "--ignore-errors",
                    "--geo-bypass",
                    "--add-metadata",
                    "--format=(bv*+ba/b)[filesize<=750m][filesize_approx<=?750m]/(bv*+ba/b)",
                    "--skip-download",
                    "--cache-dir=/data/yt-dlp-cache/",
                    "--cookies=/data/yt-dlp-cache/cookies.txt",
                    "--proxy=socks5://tor-socks-proxy:9150",
                    "--no-playlist",
                    "https://hudlow.org/2026/practical-antiforgery"
                ],
                "cmd_version": "2024.10.7",
                "end_ts": "2026-04-19T00:08:23.152109+00:00",
                "index_texts": [],
                "output": "ArchiveError: Failed to save media",
                "pwd": "/data/archive/1776557235.937238",
                "schema": "ArchiveResult",
                "start_ts": "2026-04-19T00:08:18.328133+00:00",
                "status": "failed"
            }
        ],
        "mercury": [
            {
                "cmd": [
                    "/home/archivebox/.npm/bin/postlight-parser",
                    "https://hudlow.org/2026/practical-antiforgery"
                ],
                "cmd_version": "2.2.3",
                "end_ts": "2026-04-19T00:08:15.643764+00:00",
                "index_texts": null,
                "output": "mercury/",
                "pwd": "/data/archive/1776557235.937238",
                "schema": "ArchiveResult",
                "start_ts": "2026-04-19T00:08:11.412063+00:00",
                "status": "succeeded"
            }
        ],
        "pdf": [],
        "readability": [
            {
                "cmd": [
                    "/home/archivebox/.npm/bin/readability-extractor",
                    "/tmp/tmpfc35yan_",
                    "https://hudlow.org/2026/practical-antiforgery"
                ],
                "cmd_version": "0.0.11",
                "end_ts": "2026-04-19T00:08:00.738472+00:00",
                "index_texts": [
                    "\u2693\ufe0e\ufe0ePractical Antiforgery in Software Design\n\u2693\ufe0e\ufe0eDan Hudlow / April 2026\n\n\nIf you are fortunate enough to tour the Fort Worth campus of the United States\nBureau of Engraving and Printing, you\u2019ll get a primer on the techniques\nthe BEP uses to make it difficult to replicate U.S. paper currency. But if you\nask the staff of the BEP\u2019s on-site museum to name the discipline that comprises\nthese techniques, the answer you\u2019ll get is \u201ccounterfeiting deterrence.\u201d Such a\ncumbersome designation is unfortunate, because it\u2019s hard to fully develop and\nappreciate an idea for which we lack a nomenclature.\nAnd this matters because these concepts are relevant, often vital, to all kinds\nof interactions we have both in the physical world and the digital realm. My\ngoal is to establish a taxonomy, demonstrate the crucial importance, and propose\nsome best practices in applying these ideas to software design.\nLet\u2019s start with a wieldier name for this discipline: antiforgery.\n\u2693\ufe0e\ufe0eSecurity, Cryptography, and Antiforgery\nA student of the software industry might, at this point, be confused. Aren\u2019t\nthese practices, in the software world, just called security? Moreover, aren\u2019t\nthe digital equivalents of the BEP\u2019s myriad printing techniques just\ncryptography?\nIn fact, in BEP jargon, \u201csecurity\u201d is synonymous with counterfeiting\ndeterrence; with what we\u2019re calling antiforgery. But outside of currency\ndesign \u201csecurity\u201d has a much broader meaning. A bank has security concerns that\ngo beyond forged currency or documents. Such as, quintessentially, robbery.\nAnd in the software field, a lot of what we call \u201csecurity\u201d is focused on \nthreats that are more like robbery than counterfeiting and defenses that are\nmore like locksmithing than intaglio printing. \nSo \u201csecurity\u201d is too broad. What about \u201ccryptography\u201d? While much of\ncryptography is certainly devoted to antiforgery, a lot of it is devoted to\nsecrecy also. But there\u2019s a bigger gap we need to examine, and to do that,\nlet\u2019s go back to currency design.\n\u2693\ufe0e\ufe0eTechnical vs. Practical\nThe antiforgery techniques implemented by the BEP actually have two distinct\ngoals: one technical, and one practical. The technical goal is to make it\ndifficult to exactly replicate currency. The practical goal is for any attempt\nat replication to alert even the casual observer.\nTechnical antiforgery requires exclusive access, knowledge, skills, materials,\nor technologies which are unavailable to a would-be counterfeiter. Practical\nantiforgery uses those technical capabilities to produce hard-to-replicate\nelements that are tangible and unmistakable.\nCryptography, then, can provide technical antiforgery, but it is ultimately up\nto user interfaces to deliver practical antiforgery.\nIt\u2019s all too easy, however, for conversations about antiforgery to both start\nand end with the technical. This makes sense where intractable technical\nfailures exist, as they do for personal checks, caller ID, and email. After all,\nit is usually incoherent 1 to seek practical antiforgery in the\nabsence of a technical foundation.\nBut too often, even when an industry spends billions of dollars solving the\ntechnical problems, the practical side is neglected. In reality, technical\nantiforgery without practical antiforgery is also often moot. \nThose boffins at the BEP know it\u2019s not feasible to have an expert (or a\nsophisticated machine) examine every bill in every cash transaction. It\u2019s not\nenough to make forgery difficult or even (technically) impossible: we also\nmust make authenticity obvious. We need practical antiforgery.\n\n\n  \n\u2693\ufe0e\ufe0eA Study in Failure\nBefore we apply these ideas to software, I\u2019d like to take a detour through some\nother domains where practical antiforgery is needed. And where U.S. currency\nrepresents success, it\u2019s important we also know what failure looks like.\nWe don\u2019t have to look far: acute failures exist even in disciplines immediately\nadjacent 2 to currency design. In 2010, following a spate of frauds\nachieved with card skimmers affixed to ATMs, noted designer Khoi Vinh\nobserved:\n\nThe fact of the matter is, the superfluously futuristic form of these machines\nis so nonsensical, so utterly impractical and useless that even a quickly\ngrafted foreign appendage like a skimmer is indistinguishable from the native\nhardware.\n\nIn the sixteen years since Vinh wrote this, banks have made massive\ninvestments in the technology of securely transmitting banking\ninformation. And these efforts recognize the technical failures of magnetic\nstrips and reusable credit card numbers to prevent fraud.\nYet, ATMs at major U.S. banks still look improvised with parts salvaged from a\nSoviet cosmodrome. The aesthetic is easily replicated by parasitic hardware,\nwith blank panels and mismatched finishes that almost seem to dare enterprising\ncriminals into action.\n\n\n  \n\u2693\ufe0e\ufe0eConditioning\nGas pumps are even worse. To the parts-bin hardware aesthetic, they add a\nhaphazard array of stickers, often including QR codes. If camouflaging a card\nskimmer is easy, adding a sticker with a QR code for a phishing site is trivial.\nUntil recently, 3 you\u2019d even see ostensibly legitimate QR code\nstickers at gas pumps actually soliciting payment with\npredictable results.\nThis destructive conditioning is insidious and difficult to unwind. Having\ntrained customers that a QR code on a sticker is a reasonable payment method,\nany gas pump is vulnerable to this attack, whether or not that specific pump\never solicited payment via sticker. \n\n\n  \n\u2693\ufe0e\ufe0eContinuity, Context, and Trust\nThe practical defense for these ATMs and gas pumps is continuity. A simplified\nphysical interface without unnecessary seams, gaps, protrusions, or decals is\nmuch more resistant to forgery.\nMoreover, when an ATM is bricked into the side of a local bank, continuity\nbetween the bank\u2019s architecture and the entirety of the ATM\u2019s physical interface\nallows the customer to trust the ATM.\nAnd we can generalize these ideas. The opportunity for forgery always exists in\nsome context, whether that\u2019s a bank in someone\u2019s neighborhood or a text\nmessage thread on his smartphone. When a context is itself resistant to\nreplication (as an entire bank branch is), we can say that it\u2019s trustworthy.\nBut here, we must be careful not to destructively condition users to trust  a\ncontext that\u2019s not actually resistant to forgery.\nThere\u2019s a trope in spy fiction where a character wakes up in a hospital room\nwith a TV blaring a newscast which, along with the hospital room itself, turns\nout to be a ruse recreated in a warehouse to elicit information from the\n\u201cpatient.\u201d These scenes are fantastical, but they illustrate a real\nvulnerability.\n\n\n  \n\u2693\ufe0e\ufe0eMore Contexts\nEspecially where any kind of technology is involved, the trustworthiness of\nsomeone\u2019s context isn\u2019t just a matter of \u201cwhere\u201d she is, but also how she got\nthere. Interactions over the phone drive this point home.\nThere\u2019s an important difference between an incoming call, which is easily\nforged, and an outgoing call placed to the number on the back of a credit card.\nEven if both calls result in a conversation with a reassuring banker, dialing\nthe number provides vital continuity between a trustworthy context (a physical\ncredit card) and that phone conversation.\nHere too, major financial institutions often do a bad job of helping their\ncustomers understand this distinction, with agents often asking for sensitive\ninformation on calls which they placed. And, as with QR-code payment stickers,\nthis destructive conditioning threatens a customer\u2019s interactions with all of\ntheir financial institutions.\n\n\n  \n\u2693\ufe0e\ufe0eMore Conditioning\nFrequently, conscientious organizations implement constructive conditioning.\nThis can be passive via acclimating customers to aesthetics, materials,\nprocedures, or conventions that are hard to replicate (even if the technical\nreasons why they\u2019re hard to replicate aren\u2019t intuitive).\nConstructive conditioning can also be active, such as when a text message\nwith an authentication code includes a warning not to share it with anyone.\nUnfortunately, organizations are often inconsistent. In a recent transaction\nwith a national insurance company, my wife was repeatedly asked by employees for\na code that was delivered with such a warning.\nThis hypocrisy results in subversive conditioning. Not only is a customer\nconditioned to do something unsafe; in the process they\u2019re immunized to\nconstructive conditioning.\nPerhaps the most acute form of subversive conditioning I\u2019ve personally\nexperienced was at the hands of a corporate bureaucracy that delivered mandatory\n\u201ccybersecurity awareness\u201d training in emails which bore all the marks of\nphishing attacks.\n\n\n\n\u2693\ufe0e\ufe0eSpatial Exclusivity\nSoftware is especially dependent on constructive conditioning to deliver\npractical antiforgery. Because software manifests chiefly as pixels on a screen,\nit can\u2019t exploit intuitions about quality 4 in the same way\nthat a finely crafted physical object can.\nSoftware generally must rely on spatial exclusivity to differentiate\ntrustworthy and forgeable contexts. Nowhere is this distinction more \nimportant than in a web browser, where the browser\u2019s own interface elements \n5 are inherently trustworthy but the content displayed isn\u2019t.\nIndeed, the conditioning of users to understand a web browser\u2019s exclusive\ncontrol over its address field is the foundation of the entire Internet economy.\nBuilding on the technical underpinnings of DNS and TLS, a browser\u2019s address\nfield is widely understood to be authoritative and tamper-proof. Importantly,\nthe continuity the browser provides between the address field and the\ncorresponding web page allows users to trust a web page based on its domain\nname.\nCurrent versions of Mozilla Firefox and Google Chrome follow similar\nconventions, helping constructive conditioning transfer between the two\nbrowsers.\nHistorically, Apple\u2019s Safari has taken the most holistic and thoughtful\napproach to solving this problem. By default, Safari simplifies the address\nitself to the trustworthy portion, and it keeps all of the browser\u2019s trustworthy\nzones contiguous. Regrettably, Safari 26 on macOS Tahoe has compromised this\nadvantage by blending the browser\u2019s toolbar with forgeable content.\n6\n\n\n\n\u2693\ufe0e\ufe0eSubtle Subversion\nIn addition to the passive conditioning that has taught users the relationship\nbetween the address field and the content, modern browsers implement active\nconditioning for web sites that don\u2019t use TLS because the address field, in this\ncase, should not confer trust to the content area.\n\n\n\nBut if a website presents the browser with an invalid certificate, something\ngoes horribly wrong. Two of the three major browsers implement active\nconditioning in the address field and also present authoritative information\nin the content area.\nGoogle Chrome\u2019s behavior is particularly egregious, as it even presents a\ncall-to-action to get the \u201chighest level\u201d of security.\nIt\u2019s frustrating enough when subversive conditioning is the result of a\nsprawling bureaucracy\u2019s only-human inability to behave consistently with its\nstated policies. Here, Google Chrome implements subversive conditioning in a\ntidy, self-contained package.\nOnly Apple\u2019s Safari seems to understand the sacred relationship between the\naddress field and the browser content area, opting not to present a warning in\nthe address field when the browser itself takes over the content area.\n7\n\n\n  \n\u2693\ufe0e\ufe0eGood Intentions\nAnother example of destructive conditioning I experienced in corporate life was\nan \u201cexternal sender\u201d warning for emails. Because this was implemented on the\nserver side, warnings were necessarily part of the email content, acclimating\nusers to responding to a security-minded call-to-action within a forgeable part\nof the interface.\nThis is marginally more sympathetic, because the team at Microsoft that\nimplemented support for those warnings probably didn\u2019t have\nthe prerogative to change the Outlook interface. 8 But, it\u2019s still\nmisguided and self-defeating to ask users to trust something so easily forged\nno matter how sketchy the rest of an email is.\n\n\n  \n\u2693\ufe0e\ufe0eTragic Irony\nThe well-meaning but misguided efforts of those tasked with making businesses\nmore secure are often the worst offenders. Corporate \u201cdevice management\u201d and\n\u201cendpoint security\u201d services are strikingly bad at sensing the destructive\neffects of acclimating users to an ever-shifting suite of shady-looking software\nappearing on their laptops.\nThese utilities often have opaque and vaguely malevolent names and request or\nare deployed with broad and dangerous levels of system access. Sometimes, they\ntrigger software updates that present users with spontaneous, context-free\nprompts for system passwords. This is destructive conditioning analogous to\ncalling customers on the phone and asking for sensitive information. \n\n\n  \n\u2693\ufe0e\ufe0eHostile Takeovers\nSmartphones present special challenges because pixel space is so precious and it\nis typical for a single app to control the entire screen.\nFor a browser to offer websites the ability to control the whole screen and\nthereby forge any part of any interface would seem nakedly foolish. Indeed,\nApple\u2019s Safari eschews support for the web standard enabling fullscreen\nwebsites unless a user has added a site to their home screen as a\npseudo-app.\nSurprisingly, Chrome on Android does support fullscreen websites, mitigating\nthe risk only with some temporary fine print in a floating component that\u2019s\neasily lost in an interface transition.\n\n\n  \n\u2693\ufe0e\ufe0eTwo Steps Forward, One Step Back\nPassword managers represent a big leap forward in translating technical\nantiforgery into practical antiforgery. This is accomplished by the password\nmanager matching credentials to a website before it autofills them, such that\neven if a forged site fools the user, their password manager won\u2019t transmit\ntheir legitimate credentials.\nBut even 1Password, undeniably a leader in both technical prowess and adoption\n9, sometimes succumbs to presenting forgeable interfaces. For\nexample, with the macOS app and Chrome extension both installed, a user can\ninvoke 1Password\u2019s signature password prompt from a forgeable context (a web\npage), presenting her with a floating window that can be forged inside the\ncontent area of the browser.\n\n\n  \n\u2693\ufe0e\ufe0ePersonalization\nRather than depending on spatial exclusivity, an interface can be personalized\nin a way that makes it harder to forge. Personalization is analogous to the\n\u201csigns\u201d and \u201ccountersigns\u201d often used in spy stories: just as an agent knows not\nto reveal the countersign unless first prompted with the sign, a user is\nconditioned to distrust an interface unless it is personalized.\nThe 1Password prompt in the above example actually is personalized, albeit not\nvery effectively. The user\u2019s email address is displayed, but only when hovering\nover the avatar, and the avatar itself can be customized, but only for\nindividual accounts, not for the family subscription I use.\nBut even aside from these unforced errors, personalization as an antiforgery\ntechnique requires us to exercise a lot of caution. It\u2019s crucial to understand\nhow easy it is for personalization to result in destructive conditioning.\nIndeed, in an entirely unauthenticated context (like most login screens on the\nweb), personalization is completely useless. Even if an application first asks a\nuser to assert her identity (an email address, for example), so it can present a\npersonalized interface before asking for her password, nothing keeps an attacker\nfrom using the same flow to derive the personalized elements from the user\u2019s\nidentity.\nAnd even when personalization is limited to partially authenticated users (as is\nthe case for 1Password 10), it may be difficult to\nelicit or produce personalized elements that are sufficiently difficult to\nobtain (avatars, for example, don\u2019t tend to be very private) and to condition\nusers to rely on those elements to establish trust. 11\n\n\n\n\u2693\ufe0e\ufe0eBest Practices\nAs an industry, we clearly still have a long way to go in applying the\nprinciples of practical antiforgery to software design. Doing so requires\ncritical thought, attention to detail, and vigilance.\nBut especially for anyone lost or overwhelmed, I\u2019d like to propose a few best\npractices:\n\nIn designing any interface or interaction, carefully analyze how you can\nsignal authenticity to your users.\nFor example, render on part of the screen that a forgery cannot. \n\nPay special attention when prompting a user to return to your application. \nFor example, consider using push notifications instead of text messages or \nemails.\n\nApplying the broader principle of defense-in-depth, don\u2019t allow a system\nto rely too heavily on one or two signals of authenticity. Instead, give\nusers as many meaningful signals as you can that something is trustworthy.\nFor example, encourage users to pick a custom accent color for your site and\nmake sure that accent color is always visible when they\u2019re logged in.\n\nConversely, eliminate as much authenticity noise (signals that do not\ndemonstrate authenticity) as possible.\nFor example, use short, readable URLs that don\u2019t obfuscate your domain\nname.\n\nIf you condition a user to trust a signal, do everything in your power to\nmake that signal unobtainable to forgeries.\nFor example, constrain the formatting options for user-generated content so\nit can\u2019t replicate parts of your application\u2019s interface.\n\nIf you condition users to distrust a signal, be vigilant that you never,\never contradict yourself. \nFor example, if you implore users to only enter their passwords on your\nwebsite, don\u2019t ship a phone app that prompts for a password.\n\n\n\n\n\n\u2693\ufe0e\ufe0eThe Future\nThere are also some things I\u2019m looking forward to. The adoption of passkeys, in\nparticular, continues the trend started by password managers of translating\ntechnical advances into real practical gains.\nThere\u2019s an opportunity for new ideas and techniques for antiforgery in\nsoftware that go beyond spatial exclusivity. Apple uses one such technique in\nthe way it presents Apple Pay Cash payments 12 in its Messages app: an\niridescent effect that reacts to accelerometer inputs in a way that a texted\nimage could not.\nI\u2019d love to see more hardware features used to signal the authenticity of an\ninteraction. This could be screen technology, like Samsung\u2019s new privacy\ndisplay or the lenticular displays used on the front of the\nApple Vision Pro. I can also imagine using exclusive haptics or personalized\nsound effects. There are many possibilities, especially for companies that can\ncontrol both hardware and software.\n\n\n\nMost of all, I hope to encourage more engineers to consider, discuss, and debate\nthese ideas. It\u2019s especially important that platform and browser vendors take\nseriously the need for practical antiforgery. And purveyors of security-centric\nsoftware and services need to take a hard look at where they may be doing more\nharm than good.\nI believe we need to move both the median approach and the state of the art\nforward. The stakes are too high for us to keep getting this wrong. I hope to\nwrite more on this topic in the future, so if you have any thoughts or ideas\nyou\u2019d like me to consider, please reach out.\n\n\n\n\n\n\nIn Review\n\n\n\n\n\n\nFor example, it doesn\u2019t matter if it\u2019s easy to distinguish\nbetween a common material and an unusual one if the unusual material isn\u2019t\nalso difficult to acquire.\nOne could argue that trademarks are an exception here: that Coca-Cola isn\u2019t\ntechnically difficult to replicate (i.e., Pepsi tastes like Coke) but it\u2019s\npractically difficult to replicate because Pepsi can\u2019t legally call a drink\n\u201cCoca-Cola.\u201d\nBut we\u2019ll limit our discussion to forgery efforts unencumbered by legal\nbarriers as counterfeiting currency, for example, necessarily is. \u21a9\ufe0e\n\n\nIn the sense that an ATM includes machinery to authenticate currency. \u21a9\ufe0e\n\n\nThey\u2019ve disappeared from my local pumps, but it\u2019s hard to say if this is\nrepresentative. \u21a9\ufe0e\n\n\nIt\u2019s not entirely true to say that tangibly high-quality software can\u2019t be\nproduced with exclusive capabilities, but those capabilities aren\u2019t\nwell-correlated to legitimacy or monetary resources and very few businesses\nof any size or in any market sector possess them. \u21a9\ufe0e\n\n\nThe term of art for these elements is the browser\u2019s \u201cchrome\u201d but the\nbranding of a certain web browser overloads this word. \u21a9\ufe0e\n\n\nThere\u2019s some tension in the point I\u2019m making here. I just finished saying\nthat web browsers offer an advantageous continuity between the address\nfield and the web content, and now I\u2019m complaining about inadequate contrast\nbetween these contexts.\nThis apparent contradiction is reflective of the balancing act that a web\nbrowser has to perform. On the one hand, the relationship between the\naddress and the content needs to be visually clear and tamper resistant. In\nthis sense, continuity is needed. On the other hand, the distinction\nbetween a context that is always trustworthy and a context which we know\nis sometimes untrustworthy must also be clear. In this sense contrast is\nneeded. \u21a9\ufe0e\n\n\nThe implication actually yielded is that it\u2019s google.com, and not Safari,\nthat\u2019s warning the user of a problem. I doubt Apple frets too much about an\nunsophisticated user coming away with that impression. \u21a9\ufe0e\n\n\nPlus, plenty of other email clients support Exchange, and the developers\nmight not have anticipated administrators incorporating a call to action. \u21a9\ufe0e\n\n\nI shared a draft of this piece with 1Password and received this feedback:\n\nWe agree that trust boundaries in security-sensitive interfaces are an\nimportant topic. It\u2019s also important to recognize that browser extensions,\nby design, operate alongside arbitrary and potentially hostile web\ncontent. We do not have control over what malicious websites choose to\nrender, and any site can visually imitate interface elements presented\nwithin or adjacent to page content. That\u2019s a broader phishing and\nuser-deception risk inherent to the web ecosystem, rather than a\nproduct-specific vulnerability.\nThat said, phishing resistance has been consciously incorporated into our\nlock screen design for years. For example, hovering over an account avatar\non the authentic lock screen reveals the associated email address, and we\ndisplay the user\u2019s chosen account icon where applicable. These dynamic\nelements are not something a generic phishing page would typically know or\nreplicate, and they provide users with authenticity cues within the\nbrowser context.\nIt\u2019s also worth noting that under our security model, even if a user were\ndeceived into entering a password, a password alone is insufficient for\naccount takeover without the Secret Key.\n\nI appreciate the effort they gave to a response (and, separately, their help\nin confirming that the avatar on a family account cannot be customized), but\ndon\u2019t find the actual answers very satisfying. Please also make note of my\ndisclosures concerning 1Password. \u21a9\ufe0e\n\n\n1Password is actually unusually well-suited to personalization, because of\nits key-and-password\narchitecture. \u21a9\ufe0e\n\n\nI suppose the platonic ideal here would be to condition users to have a\nPavlovian response to the personalized prompt such that they can\u2019t even\nbring the password to mind without it. \u21a9\ufe0e\n\n\nOne has to think the conceptual proximity to currency design inspired this\nunusual burst of creativity to be applied to the problem. \u21a9\ufe0e\n\n\n\n\n            \n            \n                \n                  \u2693\ufe0eAcknowledgements\nI owe a lot to Khoi Vinh for planting the seeds and giving me sixteen years\nto ponder this space.\nI\u2019d also like to thank Peter \u201cmeem\u201d Memishian and Henry Andrews for their\nincisive reviews that significantly shaped the content of this piece.\n\n                \n            \n            \n                \n                  \u2693\ufe0eDisclosures\nI\u2019ve used iOS and Safari for as long as they\u2019ve existed (which necessarily means\nI\u2019m an Apple customer), and have also been a 1Password customer for many years.\nI do not use Android, Chrome, or any Microsoft email products, but I am a paying\ncustomer of other Google and Microsoft products.\nWeirdly enough, during the course of writing this, I gave 1Password a chance to\ncomment on a draft, and then subsequently and coincidentally applied for a job\nat 1Password, interviewed, and was ultimately rejected. This created a few\nethical hazards:\n\nAs long as I thought the job was still on the table, I could appear to be\nincentivized to flatter 1Password, soften my critique of their product, or\npostpone publication. (Although only if I had a low opinion of their\nintegrity.)\nNow that I\u2019ve been rejected, I could appear to be incentivized to treat\n1Password vindictively.\nLastly, during the period that I was both in the running for the job and\nhad already presented 1Password with a draft, it could have given the\nappearance that I was offering 1Password an opportunity to influence what I\nwrote if they hired me.\n\nIdeally, I would have published before I applied for the job which would\nhave simplified this disclosure, but I just wasn\u2019t ready. I\u2019ve tried to\nmitigate these conflicts in several ways:\n\nI have not adjusted the wording with which I introduced 1Password since\nbefore I had any intention of applying for a job.\nI was careful not to mention the draft to anyone I interacted with\nregarding the job, and I think it very unlikely anyone at 1Password would\nhave been aware of both my communication about the draft and my job\napplication.\nI was resolved that I would publish this piece before accepting an offer at \n1Password, and give 1Password an opportunity to rescind the offer if they\nchose to.\n\nIt\u2019s also relevant that all my interactions with 1Password have been pleasant\nand I have no reason to believe they would be peeved or threatened by anything\nI\u2019ve written. But there\u2019s still a lot here that you\u2019ll have to take my word for\nwhich is why I consider this disclosure to be crucial."
                ],
                "output": "readability/",
                "pwd": "/data/archive/1776557235.937238",
                "schema": "ArchiveResult",
                "start_ts": "2026-04-19T00:07:57.096956+00:00",
                "status": "succeeded"
            }
        ],
        "screenshot": [],
        "singlefile": [],
        "title": [
            {
                "cmd": [
                    "/usr/bin/curl",
                    "--silent",
                    "--location",
                    "--compressed",
                    "--proxy",
                    "socks5://tor-socks-proxy:9150",
                    "--max-time",
                    "60",
                    "--user-agent",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)",
                    "https://hudlow.org/2026/practical-antiforgery"
                ],
                "cmd_version": "8.10.1",
                "end_ts": "2026-04-19T00:07:56.175815+00:00",
                "index_texts": null,
                "output": "hudlow.org: Practical Antiforgery in Software Design",
                "pwd": "/data/archive/1776557235.937238",
                "schema": "ArchiveResult",
                "start_ts": "2026-04-19T00:07:56.095101+00:00",
                "status": "succeeded"
            }
        ],
        "wget": []
    },
    "icons": null,
    "is_archived": true,
    "is_static": false,
    "latest": {
        "archive_org": "https://web.archive.org/web/20260419000826/https://hudlow.org/2026/practical-antiforgery",
        "dom": "output.html",
        "favicon": "favicon.ico",
        "git": null,
        "media": "ArchiveError: Failed to save media",
        "pdf": null,
        "screenshot": null,
        "singlefile": null,
        "title": "hudlow.org: Practical Antiforgery in Software Design",
        "warc": null,
        "wget": null
    },
    "link_dir": "/data/archive/1776557235.937238",
    "newest_archive_date": "2026-04-19T00:08:23.250483+00:00",
    "num_failures": 1,
    "num_outputs": 8,
    "oldest_archive_date": "2026-04-19T00:07:21.877439+00:00",
    "path": "/2026/practical-antiforgery",
    "schema": "Link",
    "scheme": "https",
    "snapshot_abid": "snp_01KPHH07RGEA6F78A501CC2VK2",
    "snapshot_id": "34f28b54-193a-4ab6-8ef9-3897d8c16e62",
    "sources": [
        "/data/sources/1776557234-import.txt"
    ],
    "tags": null,
    "tags_str": "",
    "timestamp": "1776557235.937238",
    "title": "hudlow.org: Practical Antiforgery in Software Design",
    "url": "https://hudlow.org/2026/practical-antiforgery"
}