Scott Conway

Information Security Researcher

Simple SMS Forwarding with Gotify / ntfy

tl;dr - Download this app and configure a webhook for ntfy to publish as JSON. Note that when using a public ntfy server, your topic name is essentially a password, and that you need to trust that the server admins aren’t reading your messages. Thus, I recommend self-hosting with authentication required, if possible.

I travelled internationally a bit last year, and at one point in my journey, I attempted to access one of my domestic US bank accounts online. Oh, right, it only allows for 2FA via SMS message. Of course. My US SIM card was in my phone, halfway across the world from US cell service, so there was no way I was going to receive that SMS message. From this annoyance, I vowed to have some solution for the next time I went abroad (that didn’t involve switching to an international coverage plan).

When I travel abroad in the future, I plan to leave my SIM card in a cell-connected device that will be able to forward messages to me. I’ve looked at the following options:

At first, I thought a dedicated SMS forwarding application for Android would be the best option. At the time, I couldn’t find a FOSS one that appeared to work with Android 10+. Gotta love the ever-changing APIs in Android. I briefly looked into writing my own, and realized that it simply wasn’t worth it when I could instead spend more time exploring alternatives.

It’d be nice if I didn’t need to mess with Android at all. I dabbled in PlaySMS’s docs for a short while, and realized the following:

Back to Android.

Easer exists, and it can almost do exactly what I want. In order to get message content from an incoming SMS message, you’ll need to use the “Receive SMS” event. When creating a script that uses this profile, you’ll need to link the “SMS Sender” and “SMS Content” dynamics to your desired profile. I prefer to use my self-hosted Gotify server, but nfty is another great notification service. In both examples, msg_content is unsanitized input coming straight from the SMS message body. In the case of ntfy, we can specify text/plain as the content type. Gotify, however, only accepts application/json, application/x-www-form-urlencoded, and multipart/form-data. Since Easer does not seem to support any sort of string post-processing on dynamics (as of 2023-02), I can’t figure a good way to forward text messages to Gotify. All of those content-types have control characters that could be sent in the SMS message body.

Easer config for GotifyEaser config for nfty

Besides the issue of dealing with unsanitized input, Easer has a few other problems in this configuration:

With all of these deficiencies, I started looking for a dedicated app, yet again. This time, I came upon SMS to URL Forwarder. The interface is super simplistic, and only allows for the creation of JSON-based POST requests. And that’s it. After configuring it, it just works. It even re-joins split SMS messages so they only generate a single notification.

Simple SMS Forwarder config

In addition to an SMS forwarding service, I’ve set up an always-on VNC server on my designated “always-at-home” cell phone for international travel. I chose to use droidVNC-NG on a phone running LineageOS 16, based on Android 9. Why such an old version of Android? In order to make my VNC server foolproof (and not require root), it needs to be able to auto-start at boot. Android 10 changed the screen recording permission so that you cannot grant an application the permission forever - you must enable it each time the application starts to record the screen. This wouldn’t play well with a power cycle, so I chose to go with a more permissive version of Android. Of course, the VNC service requires authentication, and sits behind a network jump-box that supports actual authentication standards.

There’s one annoyance with leaving your SIM card in a dedicated phone at home - you won’t have cell service when you’re travelling to/from your point of egress in your home country. I can see that being a bit of an annoyance. Simple solution - throwaway SIM cards! Give amazon or your preferred e-commerce site a query for “trial SIM card” or similar. As of 2023-02, a few mobile providers offer SIM cards with domestic US service in the range of $1-$10. They have minimal calling/texting/data plans and they only provide service for a week or so. However, $2 for service to and from the point of egress sounds worth it to me. Specifically, I’d recommend Mint Mobile’s trial SIM cards - the setup process isn’t too annoying. At some point, I may even automate it! These cards are also great for signing up for services that require phone numbers, as they’re real instead of VoIP numbers. I’ve never had an issue using one for sign-ups thus far.