Trying (and Failing) to hack the Wall of Sheep

The Wall of Sheep is a popular exhibit at DEF CON. Participants run packet sniffers on an insecure Wi-Fi network and try to catch people logging into unencrypted websites and other services. If they see that happening, they post the person’s username and password on a giant display. It looks something like:

Sample Wall of Sheep

That’s an excellent reminder to be careful when you’re connected to an unknown network, and not to send your login credentials out in the open.

From the first time I saw it, though, I had to wonder: is the wall itself hackable? Could I make it look like this instead?

Snoop onto them, as they snoop onto us.

The idea kept bouncing around the back of my mind until I added it to my to-do list so I could stop thinking about it. I had to at least try it.

To do: hack the wall!

Assumptions

I know nothing about the Wall of Sheep’s internal workings. That’s deliberate. I wanted to test this for the fun of it, and part of the challenge was to see how far I could get without any knowledge of it. I had to make a few assumptions:

  1. If you’re connected to the right Wi-Fi network and submit credentials in plaintext, they’ll be shown on the wall.
  2. The process of getting captured credentials on the wall is automated.
  3. The wall is rendered by a web browser.
  4. The wall’s software has been around for a while and wasn’t written to be particularly secure. After all, it’s on the attacking end, right?
  5. No one’s tried this before, so no one’s fixed it before.

Choosing the attack

If the above assumptions are true, the obvious attack vector is Cross Site Scripting (XSS). The method is to create a snippet of JavaScript and then trick the Wall of Sheep into displaying — and executing — it. This should work:

<script type="text/javascript">alert("I was here.");</script>

But how do I get that onto the board? The password field is usually censored, such as hunter2 being masked to hunt***. That would destroy the payload, so that wouldn’t work. Is there a way to make a DNS hostname that renders correctly? Eh, maybe, but crafting that sounds like work. (Note to self: but boy, wouldn’t that wreak havoc on the web? Huh. I’ve gotta look into that.)

However, look at that lovely login field. It’s just sitting out there in full, uncensored, plaintext glory. Jackpot! That’s where I’ll inject the JavaScript.

Setting up a webserver

This attack requires a webserver to send those faked credentials to. For ease of implementation, I configured HTTP Basic authentication with:

  • Username: Me<script ...
  • Password: lol
Remember how I've wanted to do this for years? Guess who suddenly remembered to do it on the last day of DEF CON. Everything after this was done on my iPhone with Vim in an SSH client. This was not an ideal way to do something technical. Learn from my mistakes: failing to plan is planning to fail.

Getting onto the DefCon-open Wi-Fi

You brought a burner device, right? I didn’t. What could possibly go wrong connecting an off-the-shelf device to an open network at DEF CON! YOLO.

Visiting the web page

I logged into the page on my webserver’s bare IP address, watched the board, and… nothing. I reloaded it; nothing. I looked around to see if any of the participants looked like they might’ve found something; still nothing. Rats.

Enlisting help

Jan and Pat1 were participants sitting near where I was setting this up. I needed their assistance but didn’t want to outright ask for it. I started posing innocent questions to Jan: “Hey, what are you working on? What’s Wireshark?” While they kindly explained in general terms, they were understandably more interested in their own project than tutoring a passerby. Pat was more willing to teach me and I pulled up a chair to sit with them. They patiently answered my questions and pointed to interesting things on their screen. They also noticed fairly quickly that I was regularly reloading a page on my phone as I watched them. “Hey, uh, are you trying to get caught?” “Maaaaybe…” “Why?” I gave them a quick explanation of my project and they instantly bought in:

Pat: Do you think this’ll work?
Me: Probably not, but it’s worth a shot.
Pat: Oh, wow. If it does, this will be legendary!

I had a helper. Soon after, Jan noticed we were up to something, leading to one of my favorite exchanges at DEF CON:

Jan: Are you two trying to get something up there on the board?
Me, grinning: Yeah. It’s a JavaScript injection.
Jan, wide-eyed: Who the hell are you?

Thank you, Jan. I felt like a bona fide Security Researcher after that.

Another random visitor saw us huddled and asked if we were trying to hack something. Jan looked at me, looked at the visitor, said “nope”, and looked back at me. I winked at Jan. Jan nodded back. The visitor squinted at us and walked off. Jan had my back.

Pat and Jan were awesome. When we couldn't capture my phone's request, Pat asked if I happened to be on a VPN. facepalm. Yes, I had iCloud Private Relay turned on globally.

Social engineering a Shepherd

After experimentation, we had usable Wireshark captures of me logging into my website. However, they weren’t being displayed on the Wall of Sheep. It turned out that my assumption was wrong: we had to demonstrate the capture to a “Shepherd” running the contest. Pat called one over. We showed them Pat’s capture, but they weren’t convinced at first. Most website logins are through a form POSTed to the server, not through HTTP Basic authentication. The Shepherd was also skeptical that the login was successful because the server was returning the default “welcome to Nginx!” page and not something personalized for the (obviously fake) username. I leaned very hard into the “innocent observer” role, asking questions like “but isn’t that what a successful capture looks like?” and “golly gee, it looks right to me. Don’t you think?” and “it looks suspicious to me, too, but couldn’t we try it and see what happens?” Our Shepherd seemed almost ready to go along with it — until they burned my plan to the ground.

Defeat

I asked the Shepherd how a login goes from being captured to being shown on the Wall of Sheep. Their reply doomed our fun: “I’d type it in.” Oh no. That’s not good. “Isn’t it automatic?”, I asked. The Shepherd paused to rub the bridge of their nose. “Well,” they sighed, “it was until people started sending a bunch of vile usernames and passwords and kind of ruined it2, so now we have to moderate the process.” I wasn’t giving up, though. “Could you type that username to see what happens?” “It’d just show up like that,” they replied. “Could we try it?”, I pleaded. “I mean, it’s just text. Um, that’s not a web page”, they countered.

What.

And then for the first time ever, I saw a flashing cursor down in the bottom corner of the Wall of Sheep. My heart sunk. “Is that Excel or something?” They grinned: “it’s just some old software we run.”

Disaster.

Regrouping

That’s when I formally gave up on this attempt. If it were ever possible to hack the Wall of Sheep, it wasn’t on that day. That doesn’t mean I’m abandoning this forever, though. Next year, I’m going to make a smarter effort, by:

  • Setting this up in advance. Again, Vim over SSH on a phone sucks. I’ll have the fake login working before I leave home.
  • Getting there earlier. If the Wall of Sheep is ever going to be automated and rendered in a browser, it’ll be at the opening of DEF CON before anyone’s polluted the waters.
  • Using a more common authentication method than HTTP Basic auth, like a typical login form.
  • Making the resulting page look like I’d really logged into a legitimate service.
  • Bringing a burner device, because putting my own personal device on that specific Wi-Fi network was not the best idea I’ve ever had.

And if Jan and Pat are around, I’m recruiting their help again.

To do: hack the wall harder!

  1. I didn’t get anyone’s names, or their permission to describe them. Fake names are all you get. ↩︎

  2. I appreciate the irony that I’m complaining about hackers getting stuff to show up on the Wall of Sheep in a post where I’m talking about getting stuff to show up on the Wall of Sheep. The first rule of a good prank, though, is “don’t be a jackass and ruin it for everyone else”. I was going for something that I hoped the Shepherds would find amusing and wasn’t trying to get racial slurs and other vile junk to show up on a big screen. Don’t be that person. ↩︎

How QBasic jump started my career

When I was an enlisted sailor in the US Navy, I spent an awful lot of time on a deployment hacking away on our ancient laptops to write QBasic programs to automate some of our completely-not-computer-related work. For instance, I wrote a little program to format short text messages in a particular way and write them to a floppy. Then I could hand that floppy to the ship’s radioman, and he’d run a program to load the messages and broadcast them over a packet radio to the MARS radio network. A ham operator in the States would call the recipient, read the message to them, transcribe the reply, then radio it back to our ship. I’d pick up a floppy with those replies, bring them back to the medical department where I worked, and print them out.

At that time, the quickest way to contact home was to buy a calling card for the ship’s on-board satellite phone, which cost something like $5 per minute to use. The alternative was to write a physical letter. If you were lucky and the person wrote back immediately, that would take about one month to get a response. The MARS radio system was free to use and shortened the round trip to about a day. My little program helped people use it, and I can’t exaggerate how happy this made my coworkers and bosses.

One day, a particularly enlightened boss sat me down for a talk. “Why do you lie to yourself that you want to be in medicine?” “Uh, because I want to be a doctor?” “Stop kidding yourself. You want to work with computers. We both know it.” Whoa. It was like a lightning strike. Well, of course I could go to school for that thing which had been my obsessive hobby since I was tiny! Why hadn’t I thought of that?! And so I got out of the Navy, enrolled in a computer science program, and here I am today rattling on about it.

Thank you, QBasic. You weren’t running on my beloved Amiga, but you were in the right place and time to kick off a career that I’ve loved every step of the way.

Slack was broadcasting hashed passwords for 5 years

I received an email from Slack on Thursday, 2022-08-04:

We’re writing to let you know about a bug we recently discovered and fixed in Slack’s Shared Invite Link functionality. This feature allows users with the proper permissions to create a link that will allow anyone to join your Slack workspace; it is an alternative to inviting people one-by-one via email to become workspace members. You are receiving this email because one or more members of your workspace created and/or revoked one of these links for your workspace between April 17th, 2017 and July 17th, 2022. We’ll go into detail about this security issue below.

Important things first, though: We have no reason to believe that anyone was able to obtain plaintext passwords for users in your workspace because of this vulnerability. However, for the sake of caution, we have reset impacted users’ Slack passwords. They will need to set a new Slack password before they can login again. A list of impacted users is below.

[redacted]

Now, for some technical details — feel free to skip the next two paragraphs if that doesn’t interest you. When you’re connected to Slack, we keep your client updated using a piece of technology called a websocket. This is an always-open stream of behind-the-scenes information, specific to just you and your account, that we use to push new information to your Slack client. When a new message is posted, a new file is uploaded, a new emoji reaction is added, or a new teammate joins, all of this information (plus much more!) is sent to you over a websocket. Data streamed from Slack’s servers over the websocket is processed by the Slack client apps, but often hidden from the user’s view.

One of the hidden events we send over the websocket is a notice that a shared invite link was created or revoked. The bug we discovered was in this invite link event: along with the information about the shared invite link, we included the hashed password of the user who created or revoked the link. This information was sent over the websocket to all users of the workspace who were currently connected to Slack. The hash of a password is not the same as the password itself; it is a cryptographic technique to store data in a way that is secure, but not reversible. In other words, it is practically infeasible for your password to be derived from the hash, and no one can use the hash to log in as you. We use a technique called salting to further protect these hashes. Hashed passwords are secure, but not perfect — they are still subject to being reversed via brute force — which is why we’ve chosen to reset the passwords of everyone affected.

When your users reset their passwords we recommend selecting a complex and unique password. This is easiest to do by using a password manager to help generate and store strong, unique passwords for every service.

If you have additional questions, or if you need our help as you investigate this issue, you can reply to this message or email us feedback@slack.com.

We know that the security of your data is important. We deeply regret this issue and its impact on your organization.

Sincerely, The team at Slack

In summary, for 5 years Slack sent your hashed password to everyone on your Slack server every time you invited (or uninvited) someone to it.

This email leaves a few questions unanswered:

  • How can you have a major vulnerability like this for 5 years?
  • What hashing algorithm did they use? Argon2? MD5?
  • Did they use per-user salts or one global one?
  • Where is the open, public notification of the issue?

However, they did get one thing right: use a password manager to generate a strong, random password for every single service you use, and never, ever, under any circumstances, use the same password for more than one service. Because if you’ve invited anyone to Slack in the last 5 years, and you use the same password for Slack and your bank, I hope you’re on friendly terms with all of your coworkers.

Update 2022-08-06

Slack has now posted about this on their blog.

Not Upgrading for Stage Manager

Apple’s iPadOS 16 features a new multitasking mechanism called Stage Manager, but only on very new iPad models equipped with Apple’s M1 CPU. The ludicrous reason Apple gave for this limitation is that the recent M1 chip is the first iPad CPU capable of using swap space.

If you listen quietly, you can hear millions of computer science graduates rolling their eyes at that ridiculous excuse. Far less capable computers have supported swap space for decades, and I won’t bother going into details of how nervy Apple’s claim is. Admit it, gang: you want to give people a reason to buy new hardware to use the shiny new feature. I could respect an honest explanation that doesn’t insult my intelligence.

But because of this dishonesty, I’m holding onto my still-overpowered 2018 iPad Pro until it dies, or until Apple releases a feature I can’t live without. If there were a legitimate technical reason to hold back new features on older hardware, I might use that as a reason to upgrade. Now, though, I don’t trust Apple not to pull the same trick next year. If I bought a 2022 iPad Pro because of this, and next year they released a feature in iPadOS 17 that would only work on 2023 models for another contrived reason, I’d be livid.

Apple’s trick isn’t going to make me upgrade more often, but less often. I’m not risking my hard-earned money until I have to.

Don't buy a cheap Apple Watch Series 3

Don’t buy an Apple Watch Series 3. Many recent articles enthuse about its current wonderfully low prices, but it’s a trap. The Series 3 is slow, technologically obsolete, and unsupported by the upcoming watchOS 9. Anyone buying it as their first Apple Watch will be disappointed by the awful performance.

I could only recommend it for someone who broke their newer Apple Watch, wants something to tide them over until the new Series 8 is released, and can recycle it or donate it to someone who’d be OK with a dead-end device.

The dynamic range of emotions

“Dynamic range” describes the difference between the softest and loudest bits of a musical recording. If the sound was recorded poorly so that the soft and loud parts are similar, it stops being interesting. Imagine the 1812 Overture where the cannon fire was at the same volume as the brass, or Skrillex without the drop. Without softness to compare it to, you can’t have loudness.

I was thinking about a loved one who passed away, and about the ebb and flow of happy memories mixed with tragic moments. The difficult parts were devastating, but I don’t think I’d forget them if I could. Without the sadness to compare with, could the happiness be as wonderful? I wouldn’t risk foregoing the lows if it meant the highs were less joyous.

Internet Explorer is finally dead

I was working the night shift at a motel while going to school during the day, when my parents saw a help wanted ad for a local ISP. This was in the late 90s when public use of the Internet was starting to take off, and that sounded like a lot more fun than balancing books every night.

It was. Although I technically worked in tech support, at least at first, in a small shop everyone learns how to do everything. Soon I was learning networking, configuring routers, managing Linux systems, and doing full stack web development. At the time, that meant using Gimp to carve up images to shoehorn into HTML table layouts, and using Perl to write CGI scripts to process forms.

That meant having very strong opinions about web browsers, and the preferences tended to fall into two camps:

  • If you used Windows and were new to the Internet, you liked Internet Explorer.
  • Everyone else preferred Netscape Navigator.

Netscape was better in almost every way, except for the most crucial: Windows came with Internet Explorer. And from Microsoft’s point of view, that was just peachy. They were able to leverage their famous “embrace, extend, and extinguish” policy to push ever more Windows-specific functions onto the web. Why struggle with tricky HTML forms when you could embed ActiveX controls right there in the web page? Or why use the industry standard HTML, CSS, and JavaScript definitions when you could use Microsoft’s own proprietary versions that were very slightly more convenient to use (even though it meant the page wouldn’t load in Netscape on Windows or any other OS)?

For the next decade, Microsoft used every trick in their book to make Internet Explorer the standard web browser, even though it was very non-standard. And once they succeeded, they got bored and forgot to improve it further, at least until Google’s Chrome started getting popular.

And through it all, my colleagues and I continued to try to make web pages that looked good and worked well in all browsers. That process looked like:

  • Develop the web page, testing with Firefox or Chrome, until you got it working.
  • Test it on the other browser to make sure it still worked.
  • Find a creaky Windows box to test it with, see what broke because Internet Explorer didn’t process standard HTML correctly, and tweak it until it looked mostly correctly in all 3 browsers.
  • Go home and drink.

The Browser Wars were a real, serious struggle, and it wasn’t at all obvious whether open technologies or proprietary vendors were going to win.

The web’s in much better shape now, with several major desktop and mobile browsers that work more or less the same. Sure, there are still differences that have to be dealt with, but at least they all use basically the same DOM, and the same JavaScript runs on most browsers unless you’re pushing at the edges.

And now, all these years later, Internet Explorer is finally dead. After many long years of fighting against that abomination, I won’t miss it one bit.

Do not use Readdle's Spark email app

I’ve written before about Readdle’s Spark email client, which is popular, highly rated, and a beautifully powerful app. It’s also too dangerous to use. I recommend dropping it immediately.

Readdle is a good, reputable company. I respect and appreciate them. However, Spark’s design is fatally flawed: to use its advanced features, your email username and password (or token — same thing) have to be stored on their servers so that they can access your email account on your behalf. That’s bad under normal circumstances, but astoundingly risky today. Readdle was founded in Ukraine and still has many Ukrainian employees. Russia is currently invading Ukraine, a sovereign country. If Russia manages to do this, they could likely have access to the login credentials of every one of Spark’s users. This would be catastrophic. Imagine Russia’s security agencies having full access to your work account, being able to use your personal email to reset your banking website’s password, or reading every email you’ve ever sent or received.

Spark isn’t the only email app designed this way. I believe it’s the most popular, though, and that means its dangerous-by-design architecture is used by a lot of people. This isn’t acceptable and it can’t be fixed. If you use Spark, I strongly recommend following their instructions to delete all your data off their servers immediately, and then changing the password of every account you’d used it with.

And when you’re done, see if their other apps look interesting to you. Risks with Spark aside, Readdle makes delightful software and could use our support right now.

Microsoft's gotta Microsoft

A long time ago, back in the dark days of the Browser Wars, Microsoft hated Free Software, especially Linux and the GNU General Public License. We knew this was factually true when one of their employees leaked the Halloween documents and confirmed all our worst suspicions. The world has changed since then, with Linux systems powering most Internet services and Unix-powered phones dwarfing the number of traditional Windows computers. Microsoft seemed to learn humility in their new role as underdog, going to surprising lengths to win a reputation as a kinder, gentler giant.

I’m not buying it. Oh, I did for a while. Although I’d used Emacs for many years, Microsoft’s shiny, MIT-licensed Visual Studio Code lured me away. Shortly after, Microsoft bought GitHub, the world’s most popular website for hosting FOSS projects, saying:

When it comes to our commitment to open source, judge us by the actions we have taken in the recent past, our actions today, and in the future.

Now I read that as more of a threat than a promise. Microsoft has made a few telling missteps since then:

  • They replaced the default MIT-licensed Pyright “language server” in VSCode’s Python extension with Pylance, their proprietary fork.
  • GitHub released their controversial Copilot project which uses AI to insert other entities’ code into a programmer’s project.
  • They accidentally replaced the license of a Free Software project with their own.

Taken together, this strikes me as a pattern. Microsoft pioneered the technique of “embrace, extend, extinguish”: embracing a standard someone else made, extending it with Microsoft’s proprietary add-ons, then extinguishing the competitor by taking its market share. They were legendary in their successful use of fear, uncertainty, and doubt in making potential customers afraid of using competing products.

The Pylance bait-and-switch could be straight out of the old playbook: get everyone to switch to their new, friendly-seeming product, then start replacing it with their proprietary technologies. The GitHub shenanigans would be textbook FUD if it turned out to be purposeful: what better way to get potential customers to accidentally inject GPL-licensed code into their projects, causing them a bunch of legal grief and getting them to switch to Microsoft’s own “business-friendly” licensed products?

I don’t have evidence for this, of course. I doubt anyone does. And Hanlon’s razor says these missteps likely have perfectly benign explanations. However, a big part of my job is analyzing risks and finding problems before they become major issues. My internal alarms are sounding that maybe Microsoft hasn’t changed as much as they’d like us to believe. I hope I’m wrong, but in the meantime, I’m migrating my personal projects away from all Microsoft dependencies.

Dealing with Princeton's flawed privacy research

This has been an odd week. Last Friday I got an email from someone asking about my hobby website’s CCPA compliance, ending with

I look forward to your reply without undue delay and at most within 45 days of this email, as required by Section 1798.130 of the California Civil Code.

The message sounded more legitimate than the usual spam I get, as it was asking about a real law in the jurisdiction where I live, and because it referred to a real website that I operate. That last line looked to my not-a-lawyer eyes like something a professional litigant might send out when they’re trying to gather information before deciding whether to sue someone. Mass frivolous lawsuits are a thing, after all, and I dreaded the idea that I might have had to defend my personal project in court.

This Friday, a friend told me that a researcher at Princeton sent the emails as part of a study on CCPA compliance they’re conducting with Radboud University. That changed my whole outlook: the letter came from a fake person with a fake email domain, lying about their intentions, and lying that the CCPA required me to reply to it. The stress it caused me wasn’t fake, though.

I submitted a link to my story to Hacker News, which a few people saw. Then someone else submitted another story and it took on a life of its own. It turned out that a lot of people got these emails. The researchers stated that they used the Tranco database of “popular” websites, and my tiny little site was only ranked as high as about number 350,000 in that list. I wasn’t alone. Princeton sent similar emails to other personal projects, and stories abounded that companies had hired counsel and incurred legal expenses to reply to complete fabrications. People had been frightened and were becoming angry.

Based on advice from Hacker News readers, I contacted Princeton’s Research Integrity & Compliance department and Institutional Review Board, and Radboud’s Research Data Management and Ethics Committee with my concerns. Radboud responded quickly. Princeton hasn’t responded.

What especially bothers me is that I think this is an important subject to study. I’m a Californian and I support the CCPA protecting my privacy. I want to know if companies are complying with their legal obligations, and I think a large research university like Princeton is the right kind of entity to conduct an effective study. I also believe that the researchers had the right intentions and wanted to do a good job. My problem with it is that I think they made a grave error in misrepresenting their legitimate research questions as coming from a fictional person, and wrote it in a way that set off a lot of “oh no, I think I’m about to be sued” alarms.

I suspect the data collected from misled responses is corrupted beyond repair. For instance, many entities who replied are likely to have formulated a policy solely because they received the email. I think, then, that the appropriate next steps for Princeton and Radboud are to immediately send explanation and apology emails to all the recipients of the original emails, and to delete all responses they received from recipients of the misleading messages.

This was such an unnecessary mess. It’s a shame because this could have been crafted in a way that resulted in better data and without scaring the research subjects. Do better next time, Princeton.

Update 2021-12-2: The researches updated their website to read, in part:

Our top priority has been issuing a one-time follow-up message that identifies our study and that recommends disregarding prior email. We are sending those messages.

We have also received consistent feedback encouraging us to promptly discard responses to study email. We agree, and we will delete all response data on December 31, 2021.

...And Back to OmniFocus

I recently wrote about switching from OmniFocus to Reminders and gave a lot of reasons why I thought that was a good plan. I was wrong and I’ve since moved back.

Apple has made Reminders into a solid app with a lot of nice features, but I realized I’ve been taking OmniFocus for granted. First, I sorely missed its “defer dates”. That is, I don’t need to be reminded to buy Halloween candy when it’s nearly Christmas time. I don’t even want to see that on my action list because it clutters up both my list and my thinking. Second, you can set OmniFocus to repeat an action a certain amount of time after that action’s completion date, not only its due date. “Pay the electric bill” needs to happen at the same time each month, but “make a haircut appointment” should happen a few weeks after my last haircut, whenever that was. Finally, OmniFocus’s project options like “complete with last action” are unmatched. Mix in many less crucial but nice-to-have features like nested tags, and per-tag location reminders, and it’s too good to walk away from.

I started moving my actions back out of Reminders and into OmniFocus and switched to using the OF 4 beta on my iPhone and iPad. That beta is turning into what I’d hoped OmniFocus would become: a stunning app that’s a pleasure to use. If it follows this current path, and OmniFocus 4 for Mac follows soon after, I think it’ll be amazing.

I’m glad I tried this experiment, and if nothing else it forced me to deeply review all of my actions before copying them from one system into another. Apple should be proud of Reminders and I bet it does everything most people need. It’s not (yet) enough for me, though. Until then, OmniFocus, I’m back.

About the Manifesto for Ubiquitous Linking

I’ve written before about Hook, a nifty way of linking things you’re working on together so you can seamlessly bounce between them. I’ve thoroughly integrated it into my workflow now and adore how quickly I can jump from one document to another — in a different app, even — without ever looking away from my work. It helps me reach and maintain a state of flow.

Hook depends on an app’s ability to support deep linking to its contents. Many apps are helpful, like OmniFocus. It supports both a right-click “Copy as Link” action to all sorts of items, and allowing other apps to ask it for a link to its currently selected item. Consequently, Hook’s OmniFocus support is top-tier, and I can make links between a to-do item and the website that documents how to do it. Other apps are less helpful, like Apple’s own Reminders app which supports neither users nor other apps asking for a direct link to an item. It somewhat supports drag-and-drop linking to other apps, but that’s not nearly so convenient and powerful as OmniFocus’s methods.

Apps should be more like OmniFocus than Reminders. To that end, Hook’s author Luc P. Beaudoin collaborated with an all-star list of Apple software developers to write the Manifesto for Ubiquitous Linking, which says in part:

We affirm that the ability to copy a link to a resource is as important for cognitive productivity as the ability to copy other types of information. This applies to all persistent digital information.

We invite software developers to do their part, by

  1. ensuring their users can conveniently obtain a link to the currently open or selected resource via a user interface; and
  2. providing an application programming interface (API) to obtain or construct a link to that resource (i.e., to get its address and name).

I could not agree with this, or endorse it, more heartily. Anyone can write an app that locks away content behind its own twisty maze of navigation links. The best and most powerful applications open themselves to users. Today I can link from an OmniFocus action to a DEVONthink document, and from there to an Obsidian note, whether on my Mac or my phone or iPad. Tomorrow, I want to go directly into any of my apps. If you’re an Apple developer, please take the time to read and consider this manifesto.

Better incentives for showing web ads

I use ad blockers on all my devices. Still, I understand that the sites I enjoy depend on ad revenue. When a site I visit a lot asks me to add them to my blocker’s “allow list”, I will (unless they’ve plastered a dozen ads across each page). Individual websites are the wrong entities to be asking for that permission, though.

Few websites directly sell the ads they display. Instead, they’ll contract that process out to giant ad networks like Google AdSense, Amazon Publisher Services, or dozens of other companies specializing in embedding relevant ads in the appropriate sites. Those are the companies who should be asking me for permission to show their advertisements. If an ad network earns a reputation for serving legitimate ads, free of malware, I won’t mind seeing their ads on a site I like to visit. If another network develops a bad name for showing questionable ads or serving JavaScript Bitcoin miners, I don’t want to see their junk on any website, even if I’m a fan of that site.

An ad blocker that asked me to permit ads from specific networks, or to block them from others, would be an improvement for all reputable actors involved. While almost no one wants to see advertising, users could choose to see ads from only well-behaved networks to support the sites they enjoy. Ad networks would gain viewers by acting decently and regulating themselves. Websites could increase revenue by working with legitimate ad networks and avoiding shady ones.

Everyone involved would have an incentive to make decisions that benefit each other. That sounds much better than the mess we have now.

AirTag lost its way

Apple released their new AirTag product six months ago, and as competent as it is for finding lost gear, Apple’s done everything possible to hamstring the little device to make it frustrating to use.

The product idea is simple: you buy one and attach it to something you don’t want to misplace, like your car keys. Then you can use your iPhone to locate that thing when you inevitably misplace it. For that one specific use case, and if you live alone, AirTag is magical. The “Find My” app tells you how far and in what direction the lost device is so that you can walk right up to it. I’ve owned and used various Tile devices before, and AirTags are easier to use and work better. From a hardware standpoint, I can’t imagine what I’d improve about them. However, Apple’s software decisions are constraining the lovely hardware to the point that I don’t want to use it anymore.

All of AirTag’s problems come down to a single issue: Apple is afraid that someone will use an AirTag to stalk another person, to the point that they’ve deliberately encumbered it to near uselessness:

  • If your phone detects that an AirTag is moving around with you, and its owner isn’t nearby, then the phone will warn you about it. That’s great if you’re being stalked, but terrible if it’s notifying a thief that there’s a tag in your backpack that they’ve just stolen.
  • Inexplicably, Family Sharing doesn’t work for AirTags. I can’t help my wife find her car keys, even though we’re already using the “Find My” app to share our locations. If someone were coercing me to carry an AirTag around so they could track me, they could also coerce me into sharing my location with them through that same app.
  • If I grab my wife’s keys for a quick trip to the grocery store, her AirTag on them will start beeping to alert me to its presence. That’s just silly; see the previous point.
  • The latest iOS beta lets you manually scan for hidden AirTags, sure to be a favorite must-have feature among thieves.

Apple claims that AirTags are meant for lost items, not stolen ones, but that’s a smokescreen for the fact that they haven’t figured out how to reconcile privacy with having the things work as expected. Despite their claims, of course they’re for recovering stolen items! If it weren’t for the disastrous software features, they’d be perfect for tracking down a purse thief or the person who stole your kid’s bike. Apple is selling a soup spoon, then acting shocked and dismayed when someone wants to use it to eat stew. If Apple can’t see why someone would naturally want to use an AirTag to get stolen things back, then that’s a telling failure of their imagination.

Anti-tracking features are good. No one wants to enable stalkers and I don’t blame Apple for that. However, they’re so paralyzed by even the possibility that someone might use an AirTag in a bad way that they’ve made it useless for a bunch of good ways. If Apple’s going to lock it down this hard, they shouldn’t have bothered releasing AirTag to the public. It would have been far less frustrating if it had never left the design lab.

I wanted to love AirTags, but I regret my purchases. It could have been a wonderful little gadget had Apple defined it by its possibilities instead of its limitations. I won’t be buying more.

From OmniFocus to Reminders

My wife’s been a Mac user much longer than I have. Years after she’d been happily using an iMac G4, a family friend asked if I’d like a bargain deal on their unused eMac. I was hooked. I’d recently learned about Getting Things Done (aka GTD) and wanted to try that on my new computer. At the time, on that OS, for Serious Users, that meant adopting either Things or OmniFocus. Then, as now, Things was the prettier choice. However, I had come to Mac OS after years on a Linux desktop and I knew that looks weren’t everything. I bought OF after a short trial period and I was off to the races.

It’s fair to say that OmniFocus changed my life. I’d been a disorganized mess who was constantly forgetting what I was supposed to be doing, and was often paralyzed when faced with too many choices of what I could be working on next. With my new OF/GTD system, I started taming that and getting my life in order. OmniFocus was one of the earliest purchases for my first iPhone. When I later got an iPad, I gulped at the price and then bought OF for it, too. When OmniFocus 2 came out, I bought an upgrade on launch day. When OmniFocus 3 came out, I did the same.

And when the OmniFocus 4 pre-beta became available for iOS, I installed it immediately. This time, though, something was different. Well, not with OF itself. That was the problem. OF 4 looked a lot like OF 3, which was pretty similar to OF 2, which closely resembled OF 1. Sure, The Omni Group had done a tremendous amount of behind-the-scenes work over the years. It was and is a brilliant product for power users. Yet sometimes even power users want something simple, and although OmniFocus scales up wonderfully, it never scaled down. Its industrial grade user interface would be instantly familiar to a user from 2008, with a hundred available options to tweak every last little detail. I realized that my own needs weren’t that incredibly complex and became curious whether maybe another app would be able to tell me to schedule a haircut.

Meanwhile, Apple’s own Reminders app had started life as a severely underpowered afterthought compared to OmniFocus, Things, and other powerhouses. In iOS 14, it hit adolescence and sprouted new features that started to hold their own against commercial alternatives. In iOS 15, it went through another growth spurt into something that started to look feasible. I found a blog post from Jon Mitchell about someone in my situation who had made the leap from OmniFocus to Reminders. That sounded implausible and drastic but it gave me the nudge to try the experiment for myself.

It worked. There are a few features from OmniFocus that I miss, like defer dates, perspectives, and “repeat from date of completion”, but those turned out not to be that important. And in exchange, I got a lot of nice benefits:

  • Reminders is integrated throughout the OS, and lots of apps are happy to export their contents to one of its lists.
  • I can share lists with my wife and family.
  • Taken together, those two features mean that Paprika can send its grocery list to Reminders so that my wife and I can both check off items while we’re at separate stores.
  • The user interface is vastly simpler and friendlier. Looks aren’t everything, but they’re not nothing.
  • I can ask my HomePod, “Hey Siri, what’s my first reminder?”, and it will tell me what to do next.
  • A lot of apps can be made to show reminders, like Calendar 366 which integrates them into a daily calendar view.
  • The Apple Watch app is genuinely nice to use.
  • It’s free.

Since beginning that test, I found myself moving more actions from OmniFocus to Reminders. One day I noticed that there weren’t many actions left in OF anymore, and I sat down to move over the few stragglers. Wow. I’d been at inbox zero many times, but never at actions zero in over a decade of using OmniFocus. And then I did the previously unthinkable: I deleted OF from my iPhone and iPad. I’ve fully committed to a life managed by what used to look like a toy to me. Over the last couple of months, it’s been fine. I still miss the advanced features I mentioned earlier, but not enough to be tempted to go back. Again, my life isn’t so complex that I need an extremely powerful tool to organize it. I’m learning that something simple and fun to use is good enough for me.

I still adore OmniFocus and I can imagine a world where I’d switch back. Maybe Apple will grow bored with developing Reminders and never improve it over today’s state, which is good but far from perfect. Perhaps OmniFocus 4 will be released as an absolutely stunning app that’s a pleasure to use. However, I think I’ll stick with Reminders for now. It’s helping me Get Things Done, and that’s what matters.

Notability's subscription model is an insult

Ginger Labs’s Notability is a popular note-taking app for Apple computers. It’s a nice way for taking and organizing handwritten notes and syncing them to all your devices. This week its authors ruined it by switching from a pay-once model to a subscription rental in the most despicable way I’ve seen.

First, their only concession to existing paid users is that people who’ve bought a previous version get a year’s free subscription to the new version. After that, the app will revert to a broken “free version” which removes features those customers had paid for, like cross-device syncing and unlimited editing (more on this later). This would seem to violate Apple’s guidelines which say:

If you are changing your existing app to a subscription-based business model, you should not take away the primary functionality existing users have already paid for. For example, let customers who have already purchased a “full game unlock” continue to access the full game after you introduce a subscription model for new customers.

That’s incredibly shady. For comparison, when Day One switched to a subscription model, they respected existing customers by giving them a permanent license to use the new app in the same ways they had used the old one. Those customers wouldn’t get access to new paid features, but they could keep the features they’d purchased. I think that’s a reasonable and fair approach. Not so with Notability, though: unless you pony up for a subscription, after that first year the app will become mostly unusable.

Second, and incomprehensibly, Ginger Labs paid their engineers to incapacitate Notability in the most horrid way I know of. From the Notability Subscription FAQ:

What counts as an edit?
Edits are directly tied to your usage of the app and are counted as any changes you make in a session like handwriting, erasing, or adding text or media.

Recording and modifying audio do not count as edits nor does adding or moving notes/pages.

If you’re using the free version of the app, you will be given an editing allowance each month. You can track the status of your remaining edits in the settings menu, and at any point can choose to subscribe to unlock unlimited editing.

That’s right: if someone who’d previously bought Notability doesn’t continue to pay its new rental fee, the app will count how many times they’ve made a change to a note and cut them off when they hit their limit. They are literally charging by the letter. Imagine a word processor that stopped working after you’d written too many words. That’s not a free version. It’s what we use to call “demoware” and it’s a giant insult to existing customers.

No thanks, Ginger Labs. You can keep the new Notability. There are far too many free and paid alternatives to put up with those abusive changes and limitations. I’m exporting all my notes to another system so that I can delete this abomination off all my devices.

Update: In a Fast Company article about the move, lead engineer Colin Gilboy from Ginger Labs said:

We want to make sure that people can’t just use Notability and make it all the way through med school for free. That would leave us without a business.

I have no words for the utter audacity of that statement writing off paid customers. No one was using Notability “for free”.

Update 2: Ginger Labs has announced that they’re “making some changes”:

Everyone who purchased Notability prior to our switch to subscription on November 1st, 2021 will have lifetime access to all existing features and any content previously purchased in the app.

That’s something, but doesn’t undo the damage. It takes a single terribly bad decision to lose customers’ trust. I won’t be fooled twice.

Jira is a code smell

Good Project Managers are important. As an Application Programmer, they’re your Interface to the rest of the organization. They’re your API. Believe me, you want that interface between you and their managers, unless you like giving status updates and making projection reports to pass around.

In fairness to PMs, we engineers don’t make it easy for them to do their jobs. Does this sound familiar?

PM: How long do you think that’ll take?
Engineer: Oh, I don’t know.
PM: Can you give me an estimate?
Engineer: Uh, a while.
PM: OK. I’ll write “a while” on my report. I’m sure the CEO will love that.
Engineer: Fine. 2 months.
PM: Thanks!

Now, think of all the task management applications you’ve been asked to use. Each claims to be useful for engineers (“put all your requirements and future work in one place!”), but they’re also marketed to PMs (“be able to tell your manager how long the engineers are going to take!”).

Jira is one of these. It’s awful. It’s a code smell, and if you’re interviewing at a company that says “we track everything in Jira!”, ask a lot of follow-up questions to figure out if you genuinely want to work there.

Jira itself is… fine. In isolation, it’s neither wonderful nor terrible. It just is, like a rock, tree, or slime mold. Its main feature — and what makes it potentially evil — is its immense configurability that makes it irresistible to the wrong kinds of Project Managers. A good PM will see it, tweak a couple of knobs, and start putting stories in it for the engineers to hack on. A bad PM will see it, embrace every configuration option available, and saddle Engineering with a 23 step status workflow where each story goes from “Inkling” to “Idea” to “Rough Draft” to “Planning Review Meeting 3” to “Code Complete” to “Ready for Testing” to “Testing” to “Tested” and eventually on to “Done”, “Shipped”, “Finished”, “Announced”, “Demoed”, and then “T-Shirts”. The bad PM will love this because they can give reports like “this sprint is 43.8% done and we’re 97.53% likely to hit our target”, and the engineers will hate this because they’ll spend as much time updating story statuses as they do working. A good PM won’t care about all that and will prefer to use something simpler.

A useful task manager will be somewhat opinionated. It will almost, but not quite, do what everyone wants, and will annoy everyone equally with the few things they think it does wrong. A tar pit of a task manager will claim to be everything to everyone after customization, meaning that a few people will think it’s heavenly and everyone else will despise it with the heat of a thousand suns.

Jira is one of the bad ones. If you run across someone who adores it, tiptoe away quietly and quickly.

Introducing Glass Knife

I’ve been using Obsidian lately for taking notes and I’m certain I’ll be saying more about that later. I’m a convert. It’s what I’ve wanted for ages: a pretty UI that sits above a folder full of Markdown files. This makes it trivially easy to share data between programs, and to manipulate Obsidian’s “vault” by directly tweaking those files with external programs.

In that spirit, I’ve released the scripts I use to automate my own workflows as the Glass Knife project. They’re not polished yet but I use them daily, and I’ll keep the project updated as I tweak them for my own use.

Released The Policy Wonk

Today we released the first public version of “The Policy Wonk”, or just “Wonk”. It’s a nifty tool we’ve been using at Amino for several months to manage our ever-growing set of AWS IAM policies, and acts as a sort of compiler/optimizer to combine lots of them together.

Although it’s a young project, I’m proud of how it shaped up and I think it’ll be useful for lots of people.