Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Holy War on Sites That Demand Pinboard Passwords (blog.pinboard.in)
216 points by anu_gupta on Oct 14, 2014 | hide | past | favorite | 46 comments


I agree asking for passwords is bad, but he'd probably have gotten cooperation from third parties much more quickly if he were following OAuth, OAuth2 or some other widely used standard. Forcing others to write bespoke code to handle a weird non-standard auth, however simple, is a major impediment to people using the Pinboard API.

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.


My users don't value the integration over security. I'm doing this due to ongoing user complaints about IFTTT (who have just fixed their implementation, bless them) prompting for a password.

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.


Yeah, but the Pinboard API is extremely simple to use, and the token is shown in BIG BOLD LETTERS on the settings page. Frankly, it's easier to implement than username/password, especially since the audience is probably mostly comprised of tech-savvy power users.

OAuth would add a framework's worth of complexity to this simple and elegant system — qualities that the developer of Pinboard clearly holds dear.


I once had to write an OAuth client for each of the major invoice/accounting cloud services. It was a huge hassle, with very little standardization. Everyone had to add their little quirk to the system (like client-specific endpoints, or some quirky encoding, or only accepting HTTP headers and not POST fields), depleting all the value of using the OAuth "standard," leaving only a bulky OAuth library. Simple GET/POST fields are much easier and can easily be transparently maintained in a few lines of code.


OAuth is basically two decoupled things: the request authentication format and the app authorization flow.

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.


Let's review the many reasons to use something simpler than OAuth: http://insanecoding.blogspot.com/2013/03/oauth-great-way-to-...


If you talk to any HTTP API these days, you probably use a proper API client library (of which Pinboard has plenty) rather than manually crafting HTTP requests with curl. If so, it doesn't matter whether the API supports $popularAuthMethod or not. You just pass the token to the client library and let the client library handle it from there.


Especially considering that OAuth2 pretty much _is_ just a single token.


Man, I wanted to do this so badly on the original delicious.

I have some ways of identifying aggregate misbehavior if you want to catch this. Happy to help.


Confession time: I'm somewhat of an accomplice in this unspeakable evil.

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.


No apologies needed. I'm the one who's been procrastinating a proper API update. Hats off to enthusiastic contributors who shake us out of our torpor!


Maybe sites like IFTTT are doing it because it's much easier to remember a username/password (assuming you don't use generated passwords) than an API token. A global third-party api token barely provides much more safety than giving up a random password to said third-parties. If you want to prevent one third-party app from continued access you have to go around to all the others and update the token (just like with a password).

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."


The advantage of an API token is that it protects people who re-use passwords. It also allows, in principle, for finer-grained control over what apps can do on the site.

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.


The line from the docs that flurp quoted might be exactly why people didn't transition to using the API - it suggested that Pinboard was developing Oauth and no one wants to update their code twice.


Maybe allowing users to have multiple API tokens, that way you have one for IFTTT and another for each service you set up. Gmail does something similar to this btw.

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. :)


Plus the added win of keeping everyone on their toes about open redirects!


If I can translate Thomas for the benefit of non-security professionals in the room, several researchers (most prominently, Egor Homakov) have repeatedly demonstrated the combination of a) using OAuth in certain configurations and b) having an open redirect on the OAuth consumer site allows an interested attacker to achieve privileges from the OAuth provider site to the limit of a trusted consumer site.

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.


> The advantage of an API token is that it protects people who re-use passwords.

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).


Wow, that's almost as bad as sites that ask for my credit card number. Of course, my CC number is like my name: public information. Unfortunately, the companies behind the card seem to think it's more like a password. While the law protects me from most liability for fraud, they still want to change my name, er account number, every time there's an issue. That requires me to re-enter it in various websites, inevitably at the least convenient time.

Thanks for helping drag the world into the future.


If by "companies behind the card" you mean banks, the reason they send you a plastic with a new account number when there's an issue is not only to protect you (although you aren't liable for fraudulent charges it's not precisely the best use of your time to go through the process) but also to protect themselves. A non-trivial amount of the fraud claims is absorbed by the issuing banks.

I wouldn't categorize CC numbers as public information though, just ask Target or Home Depot.


Yes, credit card numbers are used as passwords and need to be secret, but that doesn't change the fact that they are also used as names and need to be public.

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.


> 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.

"Verified by Visa" and "MasterCard SecureCode": http://en.wikipedia.org/wiki/3-D_Secure


> Of course, my CC number is like my name: public information.

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.


I think one of the problems with the API token is that it's a lot more cumbersome for the user right now than the old password-based flow. (If you don't happen to have your token around or work with it daily)

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.


And with a little more automation, you can merge steps 4, 5 and 6... and you've now reinvented OAuth 2 :)


Well, the one half of OAuth that's supposed to protect the user, at least.

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.


>If you need time to do this, email me about your plans with a convincing display of contrition.

Hahahaha. I like this guy.


If you liked this blog, the @Pinboard Twitter is hilarious and occasionally offers some pretty poignant directed criticism through the snark, to boot.


I like it when people try to report the account to "management".


I also like this very much.


Oh my god, please tell us more!


Seconded. Please, Maciej!


I wish there was a story to tell! Once in a blue moon I get a tweet threatening to report me to HR or my boss. They must think I'm a summer intern who has found the company Twitter account unattended. Next time I'll think to document it.


What? Have that happened? Any links to the occurrence of this?


Good for them. I don't understand why a service would require a 3rd party username and password for any reason if an API Key/Oauth solution existed.


Curious - Does anyone know the legality of providing a username and password and passing it through to another site that doesn't have an API/oAuth? Is it all based on the ToS of that site? It sounds like IFTTT does it / has done it. I'm really surprised by that. Isn't this a big no-no?


I wish Google would do this, and end the LinkedIn scraping of people's emails. Good on Pinboard for taking a stand.


As an off question, I remember pinboard costing +$20 something to join - why is the price back down around $10?


I was under the impression[1] the signup fee rises in a linear fashion (going up from around ~9.50$ when I signed up to ~10.50$ now) - so you might be mistaken or it was adjusted.

[1]: https://news.ycombinator.com/item?id=2302547


Last year it was $20-25 to join. I'm not sure what happened. Maybe people left and the price dropped.


Your memory is probably confusing the price of an archiving account ($25/year) with the one-time signup fee, which increases slowly over time and never goes down.


Great idea, but I suggest that "holy war" is not a great metaphor to be using - especially right now.


You should rethink your username


Pot, kettle, black? ;-)


Oh, so being brave means being a belligerent culturally-insensitive ass? Gotcha. Thanks for the awesome advice, Mr. Voice of Reason.


Pinboard gonna get straight up ISIS on yo ass




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: