Reading List
The most recent articles from a list of feeds I subscribe to.
I had a great time at DEF CON 31
I had a great time at DEF CON 31
I've always admired DEF CON from a distance. I've watched DEF CON talks for years, but I've never been able to go. This year I was able to go, and I had a great time. This post is gonna be about my experiences there and what I learned.
In short: I had a great time. I got to meet up with people that have only been small avatars and text on my screen. I got to see talks about topics that I would have never sought out myself. I'm gonna go again next year if the cards allow it.
The con itself
DEF CON is split between three hotels and a conference center in the Vegas strip: The Flamingo, the LINQ, Harrah's, and Ceasar's Forum. This was my first clue that this conference was big. I didn't realize how big it was. I'm used to conferences that have maybe two tracks of talks, but DEF CON had at least 14 when you count all the villages. I didn't even get to see all the villages, and I didn't get to see all the talks I wanted to see due to the logistical constraints of everything being spread out through Vegas.
The lines were also brutal. People were jokingly calling it LineCon, but damn they really meant it. I guess this is the sign that DEF CON has been a success, because even smaller village talks had massive lines. I didn't get to see the talks I wanted to see because I didn't want to wait in line for an hour or more. I'll likely catch the ones I missed on YouTube.
I pre-registered for the conference and I was able to get one of the coveted hard plastic badges that had room to add "shards" to customize it. I got a shard that has a picture of Twilight Sparkle holding a soldering iron on it.
This is going to make a great souvenir. I'm going to put it on my desk.
The AI village
One of the neatest experiences I had was at the AI village. There we tried to do prompt injection on models to try and get them to repeat misinformation and do other things like that. I found a fairly reliable way to get the models to say that Donald Trump was president of the USA: use Lojban, toki pona, and Esperanto.
So basically, my conversations with the AI models ended up looking like this:
It was utterly trivial, especially when you mixed Lojban, toki pona and Esperanto in prompts. I doubt this is going to work for much longer in the models I tested, but it was a very fun thing to discover.
The cryptography/privacy village
I also loved the puzzles in the Cryptography/Privacy Village. I didn't get to finish them (I'll likely get to them at some point), but I was able to implement the Vigènere cipher in Go. I put my code here in case it's useful.
The furry village
I hung out a lot in the furry village though. It was a chill place with an open bar and when you paid the price of admission, you got access to what was probably the cheapest bar on the strip. It was really a chill place to hang out with like-minded people of the furry persuasion and talk about tech. I got to meet a couple other online nerdfriends there.
Photography
I also got to practice my photography skills and play with the new 35mm lens that Hacker News paid for with ad impressions. I love the bokeh on this thing. Here's an example of how good the bokeh gets:
It's goddamn magical. The best part is that this is done in optics, not software. To be fair to Apple, their Portrait Mode does an amazing attempt at making the bokeh effect happen, but you can see the notable haze around the objects that the AI model determines is the subject. This manifests as straws in cups going into the blur zone and other unsightly things. It works great for people and pets though. With my DSLR, this is done in optics. It's crisp and clear as day. I love it.
I'm going to include my photographs in my future posts as the cover art in addition to using the AI generated images that people love/loathe.
The talks
Here are the talks I went to:
- The Mass Owning of Seedboxes
- Hacking Your Relationships: Navigating Alternative and Traditional Dynamics
- Software Security Fur All
- Legend of Zelda: Use After Free (TASBot glitches OoT)
- Domain Fronting Through Microsoft Azure and CloudFlare: How to Identify Viable Domain Fronting Proxies
- Attacking Decentralized Identity
The Mass Owning of Seedboxes
This talk was awesome. The core thesis was that seedbox providers do a very bad job at security and that it makes it easy to grab credentials to coveted private trackers and ruin other people's ratios. The speaker was anonymous and I'm not going to go into too many details about the talk to protect the "off the record" nature of the talk, but I loved it.
It makes me glad that I self-host things instead of farming it out to a third party that will just mess it up.
Hacking Your Relationships: Navigating Alternative and Traditional Dynamics
I only caught the tail end of this talk in the furry village, but it was about the practical considerations with polyamory and other non-traditional relationship structures, as well as the legal/social implications of coming out as polyamorous. I'm not polyamorous myself, but I have friends that are poly and I want to support them when and where I can. I liked it and kinda wish I caught the entire talk.
Software Security Fur All
This talk was by Soatok, someone I look up to a lot with regards to cryptography and security implementations. They talked about how the industry kinda sucks at doing its job and lamented how elitist the security space can be. Then they talked about security first principles in a way that I found really approachable.
I'm not really the best with security/cryptography code, but I do know enough that I should farm it off to someone that knows what they are doing as soon as possible.
I think one of the most impressive parts of this talk was that Soatok gave it in a fursuit. In Vegas. In summer. I can't imagine how hot that must have been.
Legend of Zelda: Use After Free (TASBot glitches OoT)
This talk was about how the SGDQ run of The Legend of Zelda: Triforce% worked from a technical level. Triforce% is a work of art and they went into gorey detail on how they hacked the game from the controller ports into memory. It was a great talk. They also tried to replicate the run live but ran into an issue where the game crashed at the worst time.
Ocarina of Time is one of the most rock-solid games out there, but everything broke in half when they found a use-after-free exploit in the game. They then figured out how to get arbitrary code execution and made the any% world record fall below 5 minutes. It's a glorious explanation of why use-after-free bugs are a problem. Really do watch the Retro Game Mechanics Explained video on how it works. It's a great watch.
It was a great talk and I got to talk with one of the speakers in the furry village afterwards. I'm glad I got to see it.
Domain Fronting Through Microsoft Azure and CloudFlare: How to Identify Viable Domain Fronting Proxies
Domain fronting is one of my favorite bug classes to consider. It's a classic time-of-check vs time-of-use bug where you have your SNI header claim you want to connect to one domain but then go and make your HTTP host header claim you want to connect to another. This is one of the tricks used to bypass nation-state firewalls like the Great Firewall, and it's a really neat trick. You basically put a postcard inside an envelope.
Somehow this technique is best documented on YouTube of all places. It's not really talked about in too much detail and CDN providers are usually quick to lock it down because it is a threat to their continued operation in countries that really want to filter internet traffic.
The basic threat model here is that if Cloudflare proxies like 20% of the Internet, that is critical mass enough that they can't just go and block Cloudflare without impeding the bread and circuses pipeline that their citizens rely on for entertainment. This is why people do domain fronting, it allows them to connect to websites that are simply blocked.
I have a friend that has been trying to help people inside Iran get free/open access to the Internet after they had some regime change recently. Domain fronting is one of/the main tool that they use because it's the only thing that's effective when government state actors block things like WireGuard and OpenVPN. He laments when big providers block domain fronting and are very reluctant to even acknowledge that it's a useful tool for people affected by extremist regimes and their censorship. I don't know of a good solution here.
Attacking Decentralized Identity
I admit, the well has been poisoned for me with regards to decentralized identity. I personally think that the problem is so intractable that it's probably a better use of our limited time on Earth to do something else and just farm it out to the usual suspects (or Tailscale!).
Going into it, I had read the Decentralized IDentifier (DID) spec and the DID Specification Registry method list that included a bunch of methods named after cryptocurrency projects. This really poisoned the well for me and I came into that talk thinking that it was some anuscoin shit that was thinly veiled as generic enough to pass muster to normal people.
I was wrong. It's actually a much lower level fundamental change to how we trust and validate identity in general. The basic idea is that the first model of identity on the internet was per-community and isolated to that community. The second model was logging in to bigger services to prove your identity and having those services vouch for you. This new third model essentially is having you vouch for yourself using public key cryptography.
It reeks of W3C disease including the use of JSON-LD for interchange and the acroynm is horrible. This technology is also so new that it hasn't even gotten close to stabilizing yet. I'm going to wait until it gets more mature before I try and use it.
Conclusion
Overall, I had a great time. I got exposed to things I never would have seen at home. I got to talk and dine with people that have only been words on a screen to me. I got to walk 50 kilometers around Vegas and take some great pictures of the city. I'm gonna do it again next year if I can. Maybe I can drag my husband along with me.
Notes on using a single-person Mastodon server
I started using Mastodon back in November, and it’s the Twitter alternative where I’ve been spending most of my time recently, mostly because the Fediverse is where a lot of the Linux nerds seem to be right now.
I’ve found Mastodon quite a bit more confusing than Twitter because it’s a distributed system, so here are a few technical things I’ve learned about it over the last 10 months. I’ll mostly talk about what using a single-person server has been like for me, as well as a couple of notes about the API, DMs and ActivityPub.
I might have made some mistakes, please let me know if I’ve gotten anything wrong!
what’s a mastodon instance?
First: Mastodon is a decentralized collection of independently run servers instead of One Big Server. The software is open source.
In general, if you have an account on one server (like ruby.social
), you
can follow people on another server (like hachyderm.io
), and they can
follow you.
I’m going to use the terms “Mastodon server” and “Mastodon instance” interchangeably in this post.
on choosing a Mastodon instance
These were the things I was concerned about when choosing an instance:
- An instance name that I was comfortable being part of my online
identity. For example, I probably wouldn’t want to be
@b0rk@infosec.exchange
because I’m not an infosec person. - The server’s stability. Most servers are volunteer-run, and volunteer moderation work can be exhausting – will the server really be around in a few years? For example mastodon.technology and mastodon.lol shut down.
- The admins’ moderation policies.
- That server’s general reputation with other servers. I started out on
mastodon.social
, but some servers choose to block or limit mastodon.social for various reasons - The community: every Mastodon instance has a local timeline with all posts from users on that instance, would I be interested in reading the local timeline?
- Whether my account would be a burden for the admin of that server (since I have a lot of followers)
In the end, I chose to run my own mastodon server because it seemed simplest – I could pick a domain I liked, and I knew I’d definitely agree with the moderation decisions because I’d be in charge.
I’m not going to give server recommendations here, but here’s a list of the top 200 most common servers people who follow me use.
using your own domain
One big thing I wondered was – can I use my own domain (and have the username @b0rk@jvns.ca
or something) but be on someone else’s Mastodon server?
The answer to this seems to be basically “no”: if you want to use your own
domain on Mastodon, you need to run your own server. (you can kind of do this,
but it’s more like an alias or redirect – if I used that method to direct b0rk@jvns.ca
to b0rk@mastodon.social
, my
posts would still show up as being from b0rk@mastodon.social
)
There’s also other ActivityPub software (Takahē) that supports people bringing their own domain in a first-class way.
notes on having my own server
I really wanted to have a way to use my own domain name for identity, but to share server hosting costs with other people. This isn’t possible on Mastodon right now, so I decided to set up my own server instead.
I chose to run a Mastodon server (instead of some other ActivityPub implementation) because Mastodon is the most popular one. Good managed Mastodon hosting is readily available, there are tons of options for client apps, and I know for sure that my server will work well with other people’s servers.
I use masto.host for Mastodon hosting, and it’s been great so far. I have nothing interesting to say about what it’s like to operate a Mastodon instance because I know literally nothing about it. Masto.host handles all of the server administration and Mastodon updates, and I never think about it at all.
Right now I’m on their $19/month (“Star”) plan, but it’s possible I could use a smaller plan with no problems. Right now their cheapest plan is $6/month and I expect that would be fine for someone with a smaller account.
Some things I was worried about when embarking on my own Mastodon server:
- I wanted to run the server at
social.jvns.ca
, but I wanted my username to beb0rk@jvns.ca
instead ofb0rk@social.jvns.ca
. To get this to work I followed these Setting up a personal fediverse ID directions from Jacob Kaplan-Moss and it’s been fine. - The administration burden of running my own server. I imported a small list of servers to block/defederate from but didn’t do anything else. That’s been fine.
- Reply and profile visibility. This has been annoying and we’ll talk about it next
downsides to being on a single-person server
Being on a 1-person server has some significant downsides. To understand why, you need to understand a little about how Mastodon works.
Every Mastodon server has a database of posts. Servers only have posts that they were explicitly sent by another server in their database.
Some reasons that servers might receive posts:
- someone on the server follows a user
- a post mentions someone on the server
As a 1-person server, my server does not receive that many posts! I only get posts from people I follow or posts that explicitly mention me in some way.
The causes several problems:
- when I visit someone’s profile on Mastodon who I don’t already follow, my server will not fetch the profile’s content (it’ll fetch their profile picture, description, and pinned posts, but not any of their post history). So their profile appears as if they’ve never posted anything
- bad reply visibility: when I look at the replies to somebody else’s post (even if I follow them!), I don’t see all of the replies, only the ones which have made it to my server. If you want to understand the exact rules about who can see which replies (which are quite complicated!), here’s a great deep dive by Sebastian Jambor. I think it’s possible to end up in a state where no one person can see all of the replies, including the original poster.
- favourite and boost accounts are inaccurate – usually posts show up having at most 1 or 2 favourites / boosts, even if the post was actually favourite or boosted hundreds of times. I think this is because it only counts favourites/boosts from people I follow.
All of these things will happen to users of any small Mastodon server, not just 1-person servers.
bad reply visibility makes conversations harder
A lot of people are on smaller servers, so when they’re participating in a conversation, they can’t see all the replies to the post.
This means that replies can get pretty repetitive because people literally cannot see each other’s replies. This is especially annoying for posts that are popular or controversial, because the person who made the post has to keep reading similar replies over and over again by people who think they’re making the point for the first time.
To get around this (as a reader), you can click “open link to post” or something in your Mastodon client, which will open up the page on the poster’s server where you can read all of the replies. It’s pretty annoying though.
As a poster, I’ve tried to reduce repetitiveness in replies by:
- putting requests in my posts like “(no need to reply if you don’t remember, or if you’ve been using the command line comfortably for 15 years — this question isn’t for you :) )”
- occasionally editing my posts to include very common replies
- very occasionally deleting the post if it gets too out of hand
The Mastodon devs are extremely aware of these issues, there are a bunch of github issues about them:
My guess is that there are technical reasons these features are difficult to add because those issues have been open for 5-7 years.
The Mastodon devs have said that they plan to improve reply fetching, but that it requires a significant amount of work.
some visibility workarounds
Some people have built workarounds for fetching profiles / replies.
Also, there are a couple of Mastodon clients which will proactively fetch replies. For iOS:
- Mammoth does it automatically
- Mona will fetch posts if I click “load from remote server” manually
I haven’t tried those yet though.
other downsides of running your own server: discovery is much harder
Mastodon instances have a “local timeline” where you can see everything other people on the server are posting, and a “federated timeline” which shows sort of a combined feed from everyone followed by anyone on the server. This means that you can see trending posts and get an idea of what’s going on and find people to follow. You don’t get that if you’re on a 1-person server – it’s just me talking to myself! (plus occasional interjections from my reruns bot).
Some workarounds people mentioned for this:
- you can populate your federated timeline with posts from another instance by using a relay. I haven’t done this but someone else said they use FediBuzz and I might try it out.
- some mastodon clients (like apparently Moshidon on Android) let you follow other instances
If anyone else on small servers has suggestions for how to make discovery easier I’d love to hear them.
account migration
When I moved to my own server from mastodon.social
, I needed to run an account migration to move over my followers. First, here’s how migration works:
- Account migration does not move over your posts. All of my posts stayed on my old account. This is part of why I moved to running my own server – I didn’t want to ever lose my posts a second time.
- Account migration does not move over the list of people you follow/mute/block. But you can import/export that list in your Mastodon settings so it’s not a big deal. If you follow private accounts they’ll have to re-approve your follow request.
- Account migration does move over your followers
The follower move was the part I was most worried about. Here’s how it turned out:
- over ~24 hours, most of my followers moved to the new account
- one or two servers did not get the message about the account migration for some reason, so about 2000 followers were “stuck” and didn’t migrate. I fixed this by waiting 30 days and re-running the account migration, which moved over most of the remaining followers. There’s also a tootctl command that the admin of the old instance can run to retry the migration
- about 200 of my followers never migrated over, I think because they’re using ActivityPub software other than Mastodon which doesn’t support account migration. You can see the old account here
using the Mastodon API is great
One thing I love about Mastodon is – it has an API that’s MUCH easier to use than Twitter’s API. I’ve always been frustrated with how difficult it is to navigate large Twitter threads, so I made a small mastodon thread view website that lets you log into your Mastodon account. It’s pretty janky and it’s really only made for me to use, but I’ve really appreciated the ability to write my own janky software to improve my Mastodon experience.
Some notes on the Mastodon API:
- You can build Mastodon client software totally on the frontend in Javascript, which is really cool.
- I couldn’t find a vanilla Javascript Mastodon client, so I wrote a crappy one
- API docs are here
- Here’s a tiny Python script I used to list all my Mastodon followers, which also serves as a simple example of how easy using the API is.
- The best documentation I could find for which OAuth scopes correspond to which API endpoints is this github issue
Next I’ll talk about a few general things about Mastodon that confused or surprised me that aren’t specific to being on a single-person instance.
DMs are weird
The way Mastodon DMs work surprised me in a few ways:
- Technically DMs are just regular posts with visibility limited to the people mentioned in the post. This means that if you accidentally mention someone in a DM (“@x is such a jerk”), it’s possible to accidentally send the message to them
- DMs aren’t very private: the admins on the sending and receiving servers can technically read your DMs if they have access to the database. So they’re not appropriate for sensitive information.
- Turning off DMs is weird. Personally I don’t like receiving DMs from strangers – it’s too much to keep track of and I’d prefer that people email me. On Twitter, I can just turn it off and people won’t see an option to DM me. But on Mastodon, when I turn off notifications for DMs, anyone can still “DM” me, but the message will go into a black hole and I’ll never see it. I put a note in my profile about this.
defederation and limiting
There are a couple of different ways for a server to block another Mastodon server. I haven’t really had to do this much but people talk about it a lot and I was confused about the difference, so:
- A server can defederate from another server (this seems to be called suspend in the Mastodon docs). This means that nobody on a server can follow someone from the other server.
- A server can limit (also known as “silence”) a user or server. This means that content from that user is only visible to that user’s followers – people can’t discover the user through retweets (aka “boosts” on Mastodon).
One thing that wasn’t obvious to me is that who servers defederate / limit is sometimes hidden, so it’s hard to suss out what’s going on if you’re considering joining a server, or trying to understand why you can’t see certain posts.
there’s no search for posts
There’s no way to search past posts you’ve read. If I see something interesting on my timeline and want to find it later, I usually can’t. (Mastodon has a Elasticsearch-based search feature, but it only allows you to search your own posts, your mentions, your favourites, and your bookmarks)
These limitations on search are intentional (and a very common source of arguments) – it’s a privacy / safety issue. Here’s a summary from Tim Bray with lots of links.
It would be personally convenient for me to be able to search more easily but I respect folks’ safety concerns so I’ll leave it at that.
My understanding is that the Mastodon devs are planning to add opt-in search for public posts relatively soon.
other ActivityPub software
We’ve been talking about Mastodon a lot, but not everyone who I follow is using Mastodon: Mastodon uses a protocol called ActivityPub to distribute messages.
Here are some examples of other software I see people talking about, in no particular order:
- Calckey
- Akkoma
- gotosocial
- Takahē
- writefreely
- pixelfed (for images)
I’m probably missing a bunch of important ones.
what’s the difference between Mastodon and other ActivityPub software?
This confused me for a while, and I’m still not super clear on how ActivityPub works. What I’ve understood is:
- ActivityPub is a protocol (you can explore how it works with blinry’s nice JSON explorer)
- Mastodon servers communicate with each other (and with other ActivityPub servers) using ActivityPub
- Mastodon clients communicate with their server using the Mastodon API, which is its own thing
- There’s also software like GoToSocial that aims to be compatible with the Mastodon API, so that you can use a Mastodon client with it
more mastodon resources
- Fedi.Tips seems to be a great introduction
- I think you can still use FediFinder to find folks you followed on Twitter on Mastodon
- I’ve been using the Ivory client on iOS, but there are lots of great clients. Elk is an alternative web client that folks seem to like.
I haven’t written here about what Mastodon culture is like because other people have done a much better job of talking about it than me, but of course it’s is the biggest thing that affects your experience and it was the thing that took me longest to get a handle on. A few links:
- Erin Kissane on frictions people run into when joining Mastodon
- Kyle Kingsbury wrote some great moderation guidelines for woof.group (note: woof.group is a LGBTQ+ leather instance, be prepared to see lots of NSFW posts if you visit it)
- Mekka Okereke writes lots of great posts about issues Black people encounter on Mastodon (though they’re all on Mastodon so it’s a little hard to navigate)
that’s all!
I don’t regret setting up a single-user server – even though it’s inconvenient, it’s important to me to have control over my social media. I think “have control over my social media” is more important to me than it is to most other people though, because I use Twitter/Mastodon a lot for work.
I am happy that I didn’t start out on a single-user server though – I think it would have made getting started on Mastodon a lot more difficult.
Mastodon is pretty rough around the edges sometimes but I’m able to have more interesting conversations about computers there than I am on Twitter (or Bluesky), so that’s where I’m staying for now.
Introducing nixexpr: Nix expressions for JavaScript
As a regular reminder, it is a bad idea to give me ideas. Today's bad idea is brought to you by managerial nerd sniping, insomnia, and the letter "Q".
At a high level: writing complicated data structures in JavaScript kinda sucks. Here's an example of the kinds of things that I've been writing as I go down the ElasticSearch tour-de-insanite:
{
highlight: {
pre_tags: ['<em>'],
post_tags: ['</em>'],
require_field_match: false,
fields: {
body_content: {
fragment_size: 200,
number_of_fragments: 1,
},
},
},
}
This works, this is perfectly valid code. It creates an object that has a few nested layers of stuff in it, but overall I just don't like how it looks. I think it looks superfluous. What if we could make it look a little bit nicer? How about something like this?
{
highlight = {
pre_tags = [ "em" ];
post_tags = [ "</em>" ];
require_fields_match = false;
fields.body_content.fragment_size = 200;
fields.body_content.number_of_fragments = 1;
};
}
This is a Nix expression. It's a data structure that looks like JSON, but you have the power of a programming language at your fingertips. Note the difference between these two parts:
{
fields: {
body_content: {
fragment_size: 200,
number_of_fragments: 1,
},
},
}
{
fields.body_content.fragment_size = 200;
fields.body_content.number_of_fragments = 1;
}
These are semantically equal, but you don't have to use so much indentation and layering. These settings are all related, so it makes sense that the way that you use them is on the same level as the way that you define them.
If you want to try out this awesome power for yourself,
Install Nix and then add
@xeserv/nixexpr
to your JavaScript dependencies.
npm install --save @xeserv/nixexpr
Then you can use it like this:
import { nix } from "@xeserv/nixexpr";
const someValue = "this is a string";
const myData = nix`{
hello = "world";
someValue = ${someValue};
}`;
console.log(myData);
I originally wrote this in Go for my scripting automation tool named yeet, but I think it's generically useful enough to exist in its own right in JavaScript. I think that there's a lot of things that the JavaScript ecosystem can gain from Nix, and I'm excited to see what people do with this.
This was made so I could write scripts like this:
// snipped for brevity
const url = slug.push("within.website");
const hash = nix.hashURL(url);
const expr = nix.expr`{ stdenv }:
stdenv.mkDerivation {
name = "within.website";
src = builtins.fetchurl {
url = ${url};
sha256 = ${hash};
};
phases = "installPhase";
installPhase = ''
tar xf $src
mkdir -p $out/bin
cp web $out/bin/withinwebsite
cp config.ts $out/config.ts
'';
}
`;
And then I'd be able to put that Nix expression into a file. I'll get into more details about this in a future post.
How it works
This is a very cheeky library, and it's all powered by one of the most fun to abuse Nix functions ever: builtins.fromJSON. This function takes a string and turns it into a Nix value at the interpreter level and it's part of the callpath for turning a string into an integer in Nix. It's an amazingly powerful function in its own right, but it gets even more fun when we bring JavaScript into the mix.
Any JavaScript data value (simple objects, strings, numbers, etc) can be
formatted as JSON with the JSON.stringify
function:
> JSON.stringify({"hi": "there"})
'{"hi":"there"}'
This includes strings. So if we use JSON.stringify
to convert it to a JSON
string, then string encode it again, we can inject arbitrary JavaScript code
into Nix expressions:
let formattedValue = `(builtins.fromJSON ${
JSON.stringify(JSON.stringify(value))
})`;
The most horrifying part about this hack is that it works.
What's next?
If this ends up getting used, I may try and make "fast paths" for strings and numbers so that they don't have to go through the JSON encoding/decoding process. But so far this works well enough for my purposes.