First, consider what problem passwords solve. User authentication. No, really! That’s it, that’s all they’re good for1 2. Passwords are shared secret between the server and the client. I have to start with this because I’ve had to dispel the notion that they have something to do with authorization. But that’s different problem entirely. A user account may be authorized to do many things, but each only has a single password.
Code](https://en.wikipedia.org/wiki/Duress_code)
thing is a topic for another day.
Security professionals have known passwords are bad for a long time. If you don’t believe me, watch me predict the future. When you’re ready, ask your nearest information security person what’s the gold standard for account security, then come back. (I promise not to change the text while you’re gone) They said Two Factor Authentication3. Now, I know what you’re thinking, and no, it’s not magic. It’s that passwords are so broken that a password and literally anything else is current best practices.
using a One Time Passcode (OTP). Bonus points for your security person if they said TOTP (Time based OTP).
Passwords make the user experience suck too. Think back, whens the last time you were trying to use a site, perhaps an online shopping site. You’ve added everything you want to the cart, ready to check out, when you forgot your password? If you can actually remember a time, I’m sorry. Not just for you, but for the site as well – frustration is the memory you have of using their software. How many friends are you gonna refer to them now? Is it less than it could be?
Say what you will about Facebook’s privacy/security. They’ve built a good UX. They’ve even gone so far as to try to “fix”4 passwords. If the password you enter isn’t correct, Facebook will jitter your password a bit, trying different letters, or capitalization trying to “guess” your password for you. As much as learning that hurt me as a security geek, It’s a good idea.
in relation to facebook.
That brings us back to the start. How many accounts to you have easy access to that you don’t know the password to off the top of your head? Even if you don’t have a password manager, I’m willing to bet the number is >= 1. So for that account, requiring a password isn’t authenticating you, it’s authenticating what ever thing is actually storing that password5. Which means passwords aren’t even doing the single thing they’re supposed to be doing: Authenticating users. They’re authenticating devices, and there’s already plenty of better ways to go about that. It time to stop using passwords.
I’ve already put my money where my mouth is6. [MechMark] is a webapp I wrote in a weekend to track who has mechnical keyboard parts they can sell to fellow makers/builders. It doesn’t use passwords at all, instead it’ll log you in via token sent to your email. (If you’re first instinct is to complain that’s not secure, be honest, you were going to let anyone with access to the users email reset the password anyways.) The [source] is on GitHub if you want to take a look.
self promotion!” – Why not both? [MechMark]: https://mechmark.bsdev.net [source]: https://github.com/GrayHatter/MechMark/
[1] Ok, that’s not the only thing, passwords are also useful as a [Duress ↩
[2] Passwords are also used as a seed for a key, but why that’s a bad ↩
[3] If you think that’s something, I knew they also said something about ↩
[4] There’s not air quotes large enough to contain the use of the work fix ↩
[5] Please don’t let it be a post-it note! ↩
[6] “HEY… This isn’t really a considered harmful essay, it’s shameless ↩
I, obviously, wasn’t surprised, but even given the base technical level of most users, they shouldn’t have been surprised either. I don’t think it shouldn’t be surprising because of an expectation this should be a thing that happens1, nor because privacy is dead. But because the gold standard should be everyone opts-in to risk with informed consent.
When I say informed consent, I say it from its use in medicine. Everyone “knows” the first rule of being a doctor is “First, do no harm”. Ignoring the point, that this particular cliche isn’t even a part of the Hippocratic Oath, it’s also not even a reasonable expectation in all cases. If it was, there’d never be any experimental treatments, no high risk surgeries. Even some low risk procedures would likely require exclusion as well. What medicine has instead is informed consent.
Informed consent at it’s minimum has 3 parts. 1) Give your recommendation, and what your treatment plan is. 2) Describe the common/possible risks of your plan. 3) List some of the alternative options. That’s really all there is, there’s some other important nuance, using language the person you’re talking to can understand, but the core is really that simple. What’s the closest equivalent we have in tech? The end user license agreement, the defining example of TL;DR2. It’s embarrassing.
I don’t mean to suggest that you shouldn’t build exactly what you want to build. Every technology, just like every treatment in medicine carries with it some risk. The stark difference is in healthcare, the person who decides what risk is worth what benefit is the person who has to take on the risk. In tech, the person making the decision about what risk worth it, is some engineer. Or more terrifyingly some corporate manager. Generally, you should avoid taking risks for others. You can do that, by asking!
The first change you can make, is making everything with an additional privacy risk exclusively opt-in. For the more experimental features or ones with a much higher chance of a negative outcome, add confirmation model that enumerates the risk in an understandable way. As an example, even the most egregious privacy violator can even get it right some times…
Notice Google Maps isn’t warning about using GPS for tracking, that’s because it shouldn’t. Physicians don’t need to explain every single risk of each and every single intervention. Were you told that lidocaine used to numb an area prior to dental work and/or sutures is cardio toxic? I’d hope not, because while true, it’s not meaningful risk for the doses used. (This is also my favorite example of why you should never hide anything from your doctors, they know and consider these things before choosing any drugs). So, don’t warn users that their email, username/password could be stolen if you get hacked. Use a good salted password hashing method, so it can’t become a meaningful risk. But it’s probably a good idea to disclose that you’re storing every single conversation had in “ear”-shot of the ultra high gain microphone that powers your new smart device. Because no one in their right mind would opt-in to that kind of thing…
P.S. The GPDR is a nice start, it also solves a lot of other related issues with internet privacy, but it’s not a substitute for consent.
]]>Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. – Antoine de Saint-Exupéry
You should apply that maxim to every single line of code, every import/include, every decision, every packet, every expectation, every thing!
It’s trivially annoying when I come across needless cruft, but it’s beyond frustrating when stuff breaks, especially when it comes from people I expect to know better. I’m not just saying this with my “Get off my lawn” voice either, I can say it standing on my security soapbox too.
A gaming community, that will remain unnamed, allows it’s members to join groups anonymously. The system is complicated, but nice. Each group gets it’s own web-based chat room, and private forums; each with its own dedicated permission system. I actually like the system, the problem is every status/presence response includes a stack of metadata. At first glance looks like there’s nothing of value getting leaked, each roll is just a number with an array of other numbers. The problem comes when one member isn’t publicly listed, and another is. Once you can resolve the group roll id to a group name you can identify every member of that group, hidden or not.
Security and privacy data goes both ways, i.e., when your code requires the client to provide information that it doesn’t need, and then breaks when that information is omitted. If you have any desire to protect as much of your online privacy as you can, you should have already disabled your browser from sending referrers on each page request. That is, unless you want to login and do some online banking. Disable referrers and visit Chase.com. I know why they’ve decided this was a good decision, but expecting a header you don’t receive, and then allowing everything to break when it’s missing isn’t how you write good software. Less is more.
It’s not just requiring less, or providing less. You should also try and do less. You obviously don’t want any online account to be compromised, but just as bad is allowing a denial of service. We can argue about the correct number of failed login attempts before you do something. But there’s no doubt that if Eve is trying to guess the username and password pair, what you shouldn’t do is preemptively reset the users password. Passwords are already hard enough for users to manage, don’t do anything extra to make it harder on them. And, under no circumstance should you allow an attacker, without the password, to force a password change1. I’m looking at you Wells Fargo!
If you’re not interested in building strong, correct systems, and you only want it to work, I’m not sure why you’re reading my blog, but you do you! Import left-pad and get on with life! But for those still reading, take a look at the code you’re working on right now, and ask yourself. “Is there anything here I can take away?” Not only will future you be grateful, and not only will I thank you when I inherit your code, but most importantly, none of your users will curse your existence, and isn’t that really what it’s all about? Making the fewest possible arch-enemies in life?
[1] XKCD Password Reuse ↩
iw
warns not to
screen scrape, I looked into exactly how it works and learned about a cool thing you can do. Because I’ve never seen
anything like this, I thought it was interesting.
Have you ever wanted to add a series of structs to your application, but enumerating them all in a single location
seems like way too much work? Well you’re in luck! There’s a GNU extension that allows you to create your own named
object segments. Anything you declare with __attribute__ (( segment("__named") ))
will be stored in it’s own segment.
Doing it this way you can simply define whatever data you want, each in it’s own self-contained file.
I’m sure you’re wondering, “If all this data is only declared in a single file, how would you access it at all?” That’s
why we named it. So that anywhere you want to access the data, include extern struct my_struct __start___named;
You’ll have to calculate the size offset at runtime, but that’s simple enough. Add an empty file that adds a two dummy
entries, (in our case we’ll use __section_[set/get]
) to the segment, then the absolute of
__section_set - __section_get
will get you the offset size. Then you can write a for loop that adds the offset size.
Be very careful not to increment the pointer by the struct size, as the size of the struct may not be the size you need
to seek for each iteration.
Also, because each of these objects need to be stored in a shared segment, but without the other files knowing about
each other; you’ll need to make sure each struct has it’s own unique name. The other files not being allowed to know
about each other means the compiler might think some of these structs aren’t actually used, and will try to optimize
them out for you. This is obviously not what you want, so be sure to include an __attribute__ (( used ))
as well.
All of this is starting to get a little complicated, so it’s time to write a macro! This is what the one in iw
looks
like. https://git.kernel.org/pub/scm/linux/kernel/git/jberg/iw.git/tree/iw.h#n107
#define __COMMAND(_section, _symname, _name, _args, _nlcmd, _flags, _hidden, _idby, _handler, _help)\
static struct cmd \
__cmd ## _ ## _symname ## _ ## _handler ## _ ## _nlcmd ## _ ## _idby ## _ ## _hidden\
__attribute__((used)) __attribute__((section("__cmd"))) = { \
.name = (_name), \
.args = (_args), \
.cmd = (_nlcmd), \
.idby = (_idby), \
.handler = (_handler), \
.help = (_help), \
.parent = _section, \
}
If you can’t remember all of this, or are in a hurry, or are tired of explaining every little detail during code review
you could use a command array. This one in
mrsh
is an example. But doing it that way you’d need a
header file too.
But that way is boring, now that you know you can create your own object segments whenever you want to, you can do so many more cool things!
“It’s probably better that you don’t know that unless you’re a kernel hacker” – ddevault
P.S.: I thought it went without saying but please, don’t do this. Always prefer simplicity over… editing multiple files.
P.P.s. Dear iw
guys, this is tongue in cheek, I love you guys. Without your work I wouldn’t be working on replacing
the actually bad software on my car.