Holy War on Sites That Demand Pinboard Passwords
blog.pinboard.in
blog.pinboard.in
Also, promising to break working integrations with the "ban hammer" seems like a poor reward to give users for alerting you to a problem. If a user values the integration more than the security of their bookmark list (as I'm guessing many people do, given the number of people using Pinboard via IFTTT), they won't be reporting that to you.
OAuth would add a framework's worth of complexity to this simple and elegant system — qualities that the developer of Pinboard clearly holds dear.
Request authentication in OAuth 2 is typically done by adding the HTTP header "Authorization: Bearer <access-token>" to every request. Pinboard does something similar but different. Sure, it would be nice if everyone used the same format, but it's so easy to stick a token in an HTTP request that I don't care if Pinboard uses its own format.
The app authorization flow is how a 3rd-party app gets an access token. (It's when the 3rd-party site redirects the user's browser to a Pinboard app approval page, where the they can click "allow", which tells Pinboard to give an access token to the 3rd-party site.)
Right now Pinboard just has you copy/paste a fixed token, which is fine, too. I think having an app authorization flow would make for a slightly better user experience.
The hardest part is designing an app authorization flow that is secure. Most of us are just not capable of doing that, so it's much safer to just use OAuth 2. As a side benefit, you can use existing OAuth 2 libraries, which will save you time on the server and on each client.
Yeah, the OAuth 2 spec is not written well. I had to jump back and forth a bunch trying to figure out exactly what the spec wanted me to do. But overall I think the benefits of using OAuth 2 for your app authorization flow outweight the annoyances.
I'm available at an attractive daily consulting rate for anyone who needs help adding an auth token to their query string with each API call.
I have some ways of identifying aggregate misbehavior if you want to catch this. Happy to help.
I maintain the (unofficial but widely used) Pinboard API client library for PHP. Until recently, it only supported password authentication. Development had all but ground to a halt in the last couple of years, partly because the API itself hasn't changed at all since 2012, and partly because I didn't want to spend any more time on API v1 when API v2 might hit production anytime, but mostly because I just forgot.
As a result, web services written in PHP are probably more likely to use password auth with Pinboard than those written in other languages. Sorry, @idlewords!
But thanks to an enthusiastic contributor who appeared out of nowhere and chastised me for slacking off, the PHP client library has now gained most of the features that it had been missing for years, including token auth. Even better, the API allows you to get a user's token given his username and password, so you can easily convert your existing database to tokens without any user interaction.
Don't get me wrong, I'm in favor of removing user's passwords from third-parties (and blocking those who won't update). I'm just wondering why Pinboard hasn't built a proper OAuth system which would remedy all the above problems. It even mentions OAuth on the api docs: "This token is intended as a stopgap measure to prevent third-party sites from having to store Pinboard credentials while the site moves to full Oauth support."
I've really soured on OAuth since writing those docs. It adds a lot of complexity, and from the user's perspective is hard to distinguish from phishing. Initially I figured API tokens would be a stopgap, but have come to believe they're a good solution. I'll make sure to update the API docs accordingly.
As well as the other end of the spectrum, people who don't and change theirs regularly. Having access survive password changes is great (but should robably come with a "Are you doing this because you got hacked?" question on the change form to invalidate API tokens).
Although I agree with you, there's a good chance that people who reuse passwords do so because they don't want to remember usernames/passwords everywhere and by forcing the user to go get their API-token it's just making things harder for them again. But, maybe this just isn't a problem for Pinboard users.
Too bad about OAuth, it does solve both problems above. :)
What does that mean? Alice uses Bob's site, which she trusts, and authorizes it to operate her Twitter account for some limited purpose. Bob's site includes an open redirect. Mallory carefully crafts a URL that theoretically exists on Bob's domain but redirects to a server Mallory controls (which displays a cute cat photo and exfiltrates the OAuth token) and then posts it, as one does with cat photos, somewhere where Alice can see it. If Alice sees that cat photo, Mallory can now manipulate Alice's Twitter account to the maximum extent permitted Bob.
Thanks for helping drag the world into the future.
I wouldn't categorize CC numbers as public information though, just ask Target or Home Depot.
This is the fundamental problem. We're using a single thing both as a secret and as non-secret public information. This confusion of purposes is what results in the massive data breaches we constantly hear about on the news.
When you buy something at a physical store like Target, their computers will store your credit card number. Why? They aren't Amazon. It won't ease your next purchase as you'll still have to present your card. Isn't it dangerous?
Yes, but consider what happens when you return something. They can't just give you cash. That would open the door to money laundering and plain old theft. They have to put the money back on in your card account. But which account? They need to name the account when informing the credit card company of the refund, which means they need to store the name. That name is the credit card number. I suppose they could store a hash of your account number and require you to swipe your card when returning items, but that's inconvenient. You might not have the correct card with you. You may have cut it up. You may be returning an item for somebody else.
A credit card number is the name of the account. As such, it must be public and cannot be secret. If instead it is to be the password, then the account really ought to have a different public name. After all, we need the ability to talk _about_ an account without the mere conversation granting all parties permission to _charge_ the account.
Here's another way to look at it: My bank will let most anybody take money out of my checking account -- provided they present the bank with two things: They need to tell my bank which account to take money out of, and they need to present an authorization token granting them permission to do so. One type of authorization token is called a "check" (though there are others). An "account number" is how a person specifies which account -- it is nothing more than the name of the account. Simply presenting the account number is not normally enough to grant access to withdraw from the account.
Everybody to whom I write a check will know my account number. It's not a secret. For convenience, it's even written on the check. What protects my account is that my bank is only allowed to withdraw money when presented with an appropriate authorization token. They aren't even a secret tokens: they are single-use, tied to a specific person and a single amount, and they can only be activated by me. Stealing my checkbook won't help you. Stealing a check I wrote to somebody else won't help you. You can't cash a check multiple times. You can't withdraw any more or less money than I authorized.
The problem with credit cards is that the account name is also the authorization token. Moreover, it's a multi-use, unrestricted token. It's a name that many people need to know and store long-term, but anybody can use it, multiple times, to withdraw any amount of money they choose. The credit card industry doesn't yet have anything that works like checks, which is why they work so hard at fraud detection.
The future is probably limited-use auth tokens for websites and chipped cards for physical stores.
For websites, I'm sure it'll be the same process as signing in to a random website with your facebook account. Imagine buying something on a website, but instead of entering your credit card number, you are redirected to your credit card company's website. You "sign-in-with Visa" by entering your account password. You are then redirected back to the website you came from, this time with an authorization token. That token will only be usable by the website you authorized. It would be useless to anybody who stole it. You may even be able to add restrictions. You could make a token that can only be used once. Or once a month for up to a year, and no more than $10 each time. The token will contain your unencrypted account number, so you won't need to enter that, but it also won't be secret. Only the token as a whole can authorize a charge, not the mere account number. The secret is your account password that only you know.
For physical stores, chipped cards will likely contain the secret. Or maybe cellphone hardware or apps. They can be used to create a valid auth token for a without ever having to surrender the secret to the computer that's processing the purchase.
Passwords are authorization tokens, but not all tokens work like passwords. Passwords are an inappropriate kind of authorization token to use for purchases. Confusing an account name with such a token is even worse.
"Verified by Visa" and "MasterCard SecureCode": http://en.wikipedia.org/wiki/3-D_Secure
Actually, your credit card number is intended to be more like a password. Not a one-time-use password (that would be a better solution) but a password. And yes, the procedures for using a card DO involve showing that password to systems (well, of course!) and people (uh, oh... not so good) along the way.
Right now to connect an API consumer, you have to:
1) Do the things on the consumer's site until you're prompted for the token
2) Open pinboard.in (presumely in a different tab)
3) Login to pinboard
4) Go to "settings"
5) Go to "password"
6) Copy API token
7) Switch back to consumer's site
8) Paste token
Steps 4 and 5 might be more difficult than they look: If people didn't use the token before or never had to change their password, they might not know how to get to settings > password. Or they might not know where to find the token at all.
I think you could make things a lot more convenient if API consumers could put a direct link to https://pinboard.in/settings/password on their page. That way, the flow would look like this:
1) Do things on the API consumer's site until you're prompted for the token
2) Follow link to token page
3) Login to pinboard
4) Copy API token
5) Switch back to consumer's site (or click "back" twice)
6) Paste token
7) Profit!
Right now, this almost works, except that if you're not already logged into pinboard, the link will just take you back to the front page. So you'd have to change the login prompt so it remembered where you came from. That sounds like a pretty insignificant change, but I think it could make a difference.
This still wouldn't be near OAuths other design goal, which is to enable API providers to grant and block access to their API individually for each consumer, independent of what their users think.
I personally view it as a sign of integrity that this abillity is apparently not a priority for Pinboard to implement.
Hahahaha. I like this guy.