The great 1980s Dungeons and Dragons panic - <AUTHOR> http://www.bbc.co.uk/news/magazine-26328105

<comment><USER2> It feels very odd reading about this "moral panic" of my childhood, as nobody where I grew up was in any way panicked at all. Did I somehow miss out on it? I played lots of D&D with my elder brother and his friends, and we went to a fairly large church in England, but nobody showed the slightest disapproval. One of my brother's friends' clothing was commented on once (he always wore camo pants and army boots), but the game was never frowned upon.

<comment><USER3> While the story is from the BBC, all the anti-D&D sources they cite seem to be in the US. So it looks like this moral panic was more of a US phenomenon.

</comment></comment><comment><USER4> Ah this brings back memories. My sister, who is still very religious, went into full blown panic mode when she discovered some D&D materials on my desk. This also brings back memories of tape backmasking to find "hidden" satanic messages in rock/metal songs

</comment><comment><USER5> Earlier discussion (by about 30 minutes): [https://news.ycombinator.com/item?id=7571223](https://news.ycombinator.com/item?id=7571223)

(bbc.co.uk vs bbc.com in the URL)

</comment><comment><USER6> For me it was in the 90s, and I remember the so-called specialists that were warning parents about the dangers of RPGs.

As usual FUD about something that was misunderstood.</comment>


Let your site visitors mine BitCoins for you - <AUTHOR> http://www.bitcoinminer.com/

<comment><USER2> Nice to see that having search still doesn't prevent people from submitting the same stories over and over again:

<http://news.ycombinator.com/item?id=2560148>

<http://news.ycombinator.com/item?id=2566365>

<http://news.ycombinator.com/item?id=2604593></comment>


Why does your API still use HTTP Basic Auth? - <AUTHOR> http://swaggadocio.com/post/48223179207/why-the-hell-does-your-api-still-use-http-basic-auth <comment><USER2> This would be improved by a recognition that security involves trade offs, particular when you have existing apps in production that you don't want to break compatibility with. That isn't a laughable consideration: "A security problem in customer's code? Fire them as a customer!" Would indeed be effective at reducing their exposure but is not in their interests and has certain drawbacks with regards to one's odds of remaining employed as a security professional. Many apps - probably most apps - are not under active development, because the customer believes them to work. Sudden breaking API changes are bad news for them, possibly irreversibly bad news if e.g. the original developer can't be located to fix the problem.

A more sensible resolution to this issue, as a hypotherical security professional at an API company, would be moving more of the burden for security onto the company rather than the API consumer, by e.g. limiting the downside risk of a credentials compromise. (Similar to how banks don't say "The bad guys got your password? Sucks to be you, your balance is now $0", one would be well-advised to eventually have something on the roadmap to e.g. disallow unauthorized or poorly considered code from causing business catastrophe prior to getting a human in the loop.). You'd also want to e.g. make sure your sample code is secure of of the box, and write your first-party libraries to "just work" to the maximum extent possible, such that greenfield development would tend to be secured by default.

That's being pretty generic, but it's my understanding that many API companies actually do put quite of bit of work into internal anti-abuse tooling, for this and related reasons.

<comment><USER3> I don't think this is something you can mitigate with libraries, especially not as you need client libraries for a dozen or so languages and I (at least) wouldn't be willing to install software just to try out some service -- you pointed out in your blog how much users dread installing software, in my mind client libraries are even worse as you have to install them and their dependencies (which may or may not conflict with your own) which may involve more or less crappy tools (e.g. my JRuby build now depends on maven, because I need to use your client libraries) before you can even test the service.

So just use HTTPS and leave it at that.

</comment></comment><comment><USER4> As an API and security professional I've found to be secure and performant one should do the following with APIs:

\- Dont listen on HTTP, force HTTPS (Tune your ciphers! see <https://www.ssllabs.com/ssltest/index.html>)

\- Ensure that any client libraries you supply for API interaction must verify the server certificate

\- Only use the users password to obtain a long random key from the server either through an admin web interface where possible or by an API request that supplies the username and password and receives the key.

\- Make authenticated requests of the API with the key

\- Store any passwords as bcrypt hash in the DB for security

\- Only store the key as SHA2-256 hash in your DB for performance

\- Actually yes do use HTTP Basic as it's a convenient way to transmit the key (see how Stripe does it) making things easy for your users and perfectly secure as long as you prohibit plain HTTP.

\- Stay the heck away from HMAC's and signing requests, you have SSL, properly tuned it's secure. HMAC is pointless here and really confuses the users.

<comment><USER5> Users should use "a long random key"

But you should store "the key as SHA2-256 hash in your DB"

why hash it?

<comment><USER4> Because if someone gets access to your database somehow you're not exposing all of the keys for all of your users.

While you're likely in serious trouble if someone gets your DB this helps minimize damage. Besides to authenticate a request you dont need the plaintext of the key, a hash is fine.

<comment><USER6> Storing SHA in the database or anything not produced by PBKDF2, bcrypt or scrypt is wrong and doesn't help you much "minimizing damage." Advising SHA doesn't seem to come from a real professional.

<comment><USER4> I don't think you understand the distinction here, this is a random key, not a user generated password. The purpose of using something like bcrypt is to protect against brute forcing hashed passwords.

You cannot brute force search against a large random number that is hashed with unsalted SHA or the like. This would require you to guess the number, hash it and check to see if the hashes match. A large random number encoded as a 64 character string is simply too big to guess, even at millions of guesses per second.

Thus using bcrypt to protect your api keys does nothing but impose a serious bottleneck in how many api requests per second you may authenticate.

<comment><USER7> Exactly!

</comment></comment></comment></comment></comment></comment><comment><USER8> (I work at Stripe.)

We've thought about closing HTTP access in the past. As with a lot of security, it's a usability trade-off.

We work hard to make sure that people only ever access Stripe over HTTPS. Most people use the Stripe API through an existing library. Since the API doesn't work over HTTP, any such library is guaranteed to use HTTPS. Stripe itself is on Chrome's built-in HSTS list, sets HSTS headers, etc.

The scenario Stevie describes is unlikely to be an issue unless the user is implementing his or her own library. In that case, though, they're almost certainly going to be using test API credentials. Stripe's API will never return a successful response when you access it over HTTP, so you'll figure out that you can't do this on the very first request.

More broadly, what exactly is being defended against isn't particularly clear. There are much easier ways for someone implementing their own library to screw up (skipping cert verification is extremely common and leaves you perpetually vulnerable to HTTPS MITM), and there are many other plausible vectors for an attacker.

Even if we _did_ change this, we'd only have solved one small class of accidental key leaks. You could accidentally specify "stripe.com" instead of "api.stripe.com", for example, and stripe.com will of course always accept HTTP. Or you could typo the domain and send your key to someone else entirely.

If we ever did want to solve this, we'd probably do something like:

\- Monitor HTTP Authorization headers sent to api.stripe.com.

\- Notify the user if they ever accidentally send a secret key in the clear.

\- In addition to notifying the user, we could potentially roll the key automatically (though this runs the risk of breaking production code).

But I don't think disabling HTTP helps much. (I do think it'd be good if we started monitoring the frequency with which this happens -- if it's common, we should certainly do something like the above; if it ~never happens, it presumably doesn't matter.)

Separately, I think that the HMAC-based signature scheme that Stevie proposes is something we might want to do at some stage. A very early version of Stripe actually had something very similar. The issue with all protocols in this vein is that they involve considerably more complexity on the user's end and are harder to debug. But they definitely have some nice security properties.

</comment><comment> martin-adams If we're worried about a man-in-the-middle attack sniffing insecure credential on port 80. If the host closed port 80, couldn't the man in the middle just open it up again, you know, in the middle?

Maybe one recommendation should be supported vendor supplied SDKs which don't touch HTTP, only HTTPS. Another option is to detect credentials being sent over HTTP and notifying the clients, maybe deactivating their key if action isn't taken in a period of time.

<comment><USER9> I think the idea is that if the real port 80 never answers, real customers are highly unlikely to set up their apps in the vulnerable state in the first place. That said, having port 80 open, but returning an appropriate error code to all attempts to use the API, would probably have the same effect (while still answering on port 80, for anyone who just wants to ping it to see "are they up" --- one of the excuses the OP has heard for leaving port 80 open).

<comment><USER10> No, that's exactly the problem the post is complaining about. It still results in credentials being sent in plaintext in the original request.

<comment><USER11> Right, but the problem will be caught when the app is still in development. Then the devs will fix the app and by the time it gets to end-users, it won't do that anymore.

</comment></comment></comment></comment><comment><USER12> This is an important issue, but as the article says, Auth Basic over SSL is perfectly secure (if you don't redirect 80 to 443 of course). And since it is so simple to set up and use, I can see why some providers would use it (I do for example).

Summary of the article: [http://tldr.io/tldrs/516fc7e340d4a84c4100020e/why- the-hell-d...](http://tldr.io/tldrs/516fc7e340d4a84c4100020e/why-the-hell- does-your-api-still-use-http-basic-auth)

<comment><AUTHOR> Great TL;DR. Is that algorithmically generated or by a human?

<comment><USER13> It's crowd-sourced from actual people using a browser extension.

<http://tldr.io/what-is-tldr>

(see how I gave you a tl;dr of the link explaining how the tl;dr is generated?)

<comment><USER14> Is there a tl;dr page for that page? :)

<comment><USER12> Actually, there is: [http://tldr.io/tldrs/50509fb5e37267fc34000007/tl-dr-what- is-...](http://tldr.io/tldrs/50509fb5e37267fc34000007/tl-dr-what-is-it)

But this page is a bit outdated, this is what we use now: [http://tldr.io/tldrs/514d1c2ec02bf6ba46001aba/more-on-the- tl...](http://tldr.io/tldrs/514d1c2ec02bf6ba46001aba/more-on-the-tldr-io- extension)

</comment></comment></comment></comment></comment><comment><USER15> Don't use the "signature" gem. Rails already provides a MessageVerifier class that wraps OpenSSL's HMAC; the "signature" wrapper uses "==" to compare HMAC values, and is thus timeable.

Really, don't use HMAC-of-the password authentication tokens at all, though. They're not nearly as secure as TLS.

Better still, don't use passwords in your API at all. Passwords are for humans. APIs use keys.

<comment><USER16> _Better still, don't use passwords in your API at all. Passwords are for humans. APIs use keys._

You make great points, but just as a point of clarification (because I saw numerous people confused by this yesterday), this is merely nomenclature, no? What you are calling a key is really a long, random password (in Amazon's case the secret Access key).

<comment><USER17> Nomenclature is important. As the joke says, naming things is one of the only two difficult problems in computing. [1]

A good password is a long string of random characters, and an API key is a long string of random characters, but they are not the same because the semantics are different. Passwords are typically chosen by customers, changed (let's be honest) very rarely and on a haphazard schedule, often reused across a bunch of different systems no matter how frantically we wave our hands, and (most important of all) have "user" semantics and scope: a password lets a user log in and do logged-in-user stuff.

Whereas an API key can be issued by the system, and is thereby guaranteed (assuming a clueful programmer) to be long and random and unique and not shared with the customer's Gmail account and bank account. You can expire it often. You can issue more than one per customer. (With passwords, this is theoretically possible but practically impossible; customers barely understand how to handle _one_ password.) You can issue it to entities that aren't themselves customers, and that don't have "user" semantics. You can scope it to particular uses, issuing a key that is only good for checking balances but not for initiating transactions, for example.

\---

[1] The other being cache coherency. And avoiding off-by-one errors when enumerating lists.

<comment><USER4> You also hash the two differently in your database. With passwords you want to bcrypt (or similar) them to protect against exposure of the DB and an attacker brute forcing the hashes. Since this is virtually impossible for long random strings you're able to just SHA2-256 the keys for DB storage. This becomes important because you're likely checking the key every API request and bcrypt would be a significant API rate limiter.

<comment><USER15> Exactly what is the point of obfuscating single-purpose API keys at all?

<comment><USER16> Doesn't exactly the same concerns arise? A single purpose may be a major purpose, such as "transfer monies between accounts", and aren't exactly the same concerns relevant between passwords and keys?

If someone gets a list of unencrypted (or poorly encrypted) passwords, they have the rights of the user. If someone gets a list of unencrypted (or poorly encrypted) keys, they have the rights of the API caller. The concerns seem identical.

<comment><USER17> I will state the argument as I understand it:

The difference is that you can, and should, rotate your API keys automatically and fairly frequently (I will leave it to experts to tell us _how_ frequently is prudent.)

Moreover, when you think your DB has been compromised you can flush all the API keys and reissue them. Depending on the application this may be more or less of a pain for the customers, but at least it is possible, because the keys are random and generated by you and not shared across services.

These facts mean that API keys, properly implemented, have a much smaller attack surface. You need not worry, for example, that a three-year-old backup file that someone harvested out of the trash at your ISP has valid API keys on it. The window for attack is, in fact, limited to "someone has stolen a very fresh copy of my live DB, but I have not yet realized it, and there is still something valuable left to compromise other than _the data in my app's live DB_." And this window often isn't very important. Often, closing it is akin to reinforcing the barn door after the horse has bolted and the barn has burned to the ground.

Passwords, on the other hand, get reused. You are using bcrypt to hash passwords not just to protect your app, but to protect your customer Gmail accounts that share the same password.

<comment><USER4> In common usage the user will take an server generated API key and embed it within their application that makes API requests. Take a very typical example of a merchant selling snowboards and using Stripe to process the payments as an example.

Since this API key is embedded within their app it'll require a programmer to change (and customers often may be non technical with sites built on contract). These are things you dont want to force customers to change with any frequency as it can cause pain and expense. You dont want to ever be forced to flush all your API keys, it could be a serious disaster.

Now there's protocols that rollover access keys hourly or the like such as OAuth a but that's a complex and often unnecessary use case that's beyond most API implementors. See how Google does OAuth 2.0 with their APIs for an example.

Since it's secure, simple and performant to hash API keys stored in your DB and just compared hashed values for authentication why would you ever not want to do it?

<comment><USER15> If you lose the database containing either your API keys or hashes of your API keys, you need to revoke the keys. Not doing so is negligent.

The correct next step after discovering that you may have lost custody of API key information is to ensure that the keys are worthless, not to scramble to try to protect the keys.

This is another reason you want to be clear about the difference between a "key" and a "password", because passwords are sticky. A benefit of working with keys is that they are not; you can zorch a key with minimal provocation.

<comment><USER4> If you lose your DB you're in trouble regardless. We're talking about the level of trouble here. I'd rather be faced with a 30 day key rollover of all my users than a forced immediate change.

I dont see any reason to continue the argument. It's clear to me that you should hash your API keys in your DB.

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER18> There's a very good reason for using HTTP basic auth: if you want to store password hashes on your server using a modern scheme like bcrypt or PBKDF2, you can't use digest authentication. The author suggests rolling your own authentication scheme based on HMAC-SHA, but then all the clients need to implement this scheme whereas HTTP basic auth is already part of most HTTP libraries. And do you really trust yourself to get the crypto right?

HTTP basic auth over SSL seems like the way to go - and you need to use SSL on your API anyway to prevent hijacking. The points about not allowing HTTP access to the API make sense, but avoiding basic auth entirely isn't a good security tradeoff.

<comment><AUTHOR> I did not suggest "rolling your own crypto". HMAC is detailed in an RFC (<http://tools.ietf.org/html/rfc2104>), is widely used, e.g. Amazon AWS, and is part of OpenSSL. At no point do you have to "roll your own". If you don't implement this correctly the request will simply fail, the credentials won't be exposed at any point. Please spare me the FUD.

<comment><USER19> You are suggesting 'roll your own auth,' though. Which is more difficult to get right than most people think.

</comment></comment></comment><comment><USER20> HTTP Basic Auth is actually a great solution as long as you've blocked non-SSL traffic, so I half-agree with you. Absolutely close port 80 so it's not possible to accidentally attempt basic auth with the server in the clear.

The bit I disagree with is this:

As well as being tremendously simple, HTTP Basic by itself is also tremendously insecure, i.e. it is implemented by simply Base64 encoding the username and password concatenated with a colon ":" character. It then follows that HTTP Basic should only be used, if at all, over securely encrypted connections.

I agree - HTTP Basic is…well, basic. But you imply that even over SSL, HTTP Basic Auth is only marginally acceptable, and that's not the case. Everything you do securely online is transmitted in plaintext behind SSL. If a vanilla API key behind SSL is barely secure, you're pretty much hosed.

<comment><AUTHOR> I don't imply or perhaps did not mean to imply this.

</comment></comment><comment><USER6> What's always needed is simply properly used TLS (https). Even wording in the article is misleading. It's not about "closing port 80" but about "using only TLS."

Once you use TLS is the "HTTP basic" often the optimal solution. After reading the whole article, I still don't understand why would anybody try to make HTTP "secure" instead of simply using TLS. So my question to the author, paraphrasing the article title:

Why the hell simply not using TLS and thereby avoiding the "basic auth is bad" misdirection?

<comment><USER21> It's pretty much like forms based auth which is used by virtually every user facing web site with a login, wherein the data you send over is plaintext.

And as we know, that needs to be done over TLS.

</comment></comment><comment><USER22> Isn't this is a problem with the client, curl in this case? According to the spec:

> HTTP provides a simple challenge-response authentication mechanism which may > be used by a server to challenge a client request and by a client to provide > authentication information.

The client should make two requests. The first with no credentials to see if the resource is protected (the challenge part). The server will then respond with a 401 Unauthorised status and a WWW-Authenticate header indicating what authentication to use. The client will then make another request with the given authentication.

The insecurity is caused by curl not doing this challenge response, it is just sending the credentials straight away.

<comment><USER23> By my reading, the spec is not that clear about it. It does say that

 _A user agent that wishes to authenticate itself with an origin server-- usually, but not necessarily, after receiving a 401 (Unauthorized) --_

implying, imo, that no prior 401 response is needed. On the other hand, the spec also says

 _A client SHOULD assume that all paths at or deeper than the depth of the last symbolic element in the path field of the Request-URI also are within the protection space specified by the Basic realm value of the current challenge. A client MAY preemptively send the corresponding Authorization header with requests for resources in that space without receipt of another challenge from the server._

which would imply that at least one 401 response should be received before sending credentials.

Of course the most important part of the spec is this:

 _The Basic authentication scheme is not a secure method of user authentication, nor does it in any way protect the entity, which is transmitted in cleartext across the physical network used as the carrier._

<comment><USER24> I don't think there's any ambiguity here...the first quote indicated that a client is absolutely allowed to send auth headers without receiving a 401 response. I read the second quote as giving client implementers a suggestion on when they should automatically send the auth headers, without actually requiring them to do so.

<comment><USER25> I agree, and the practice of sending an Authorization header without first receiving a challenge is common enough that there's a phrase for it: preemptive authentication.

See, for example, the Apache HttpClient documentation: [http://hc.apache.org/httpclient- legacy/authentication.html#P...](http://hc.apache.org/httpclient- legacy/authentication.html#Preemptive_Authentication)

</comment></comment></comment></comment><comment><USER26> Why the hell would you over complicate your API with things like s3 auth or other bs like oauth?

HTTP Basic Auth works pretty well with SSL and should be enough for most cases. Also, it's dead simple for the API to return a token that can be used after authentication in non-SSL endpoints of the API.

<comment><USER27> The title is a little misleading as the author is talking about HTTP vs HTTPS rather than the HTTP auth specification vs oauth (et al). Essentially his whole blog post could be reduced to this: _servers shouldn't open port 80 on auth API sub-domains._

While he does have a point, I do think part of the blame lies with the client side as well. If you're dumb enough to transmit user details over clear text protocols then you really shouldn't be allowed near any sub-systems which require authentication.

<comment><USER26> hmm, not really... the post ends with: P.S. Don't use HTTP Basic. Thanks.

That just don't make any sense to me and implicitly suggests using other authentication methods.

</comment></comment></comment><comment><USER28> I like HTTP APIs that use basic auth over SSL. Why? Because as the blogpost demonstrates nicely, curl is a wonderful tool to test, demo and debug things.

As soon as you introduce e.g. MACs to the mix, you can forget about most unix-y commandline tools.

I think we can all agree that there are better options when it comes to authentication, but I'd rather have something I can work with easily than worry about that tiny amount of possible "plain http pre redirect" mistakes.

What about using http digest auth as a middle ground? It's still curl compatible and a tiny bit more secure.

<comment><USER29> I agree, things like Oauth are also massively overkill for what should be simple jobs. The other day I was writing a script for my own personal use that needed to get some metadata from Imgur. Their API /requires/ OAuth, when even a json snippet for a public picture would have been just fine. Ended up just scraping the page as it was a one off script and was much faster than signing up, creating an application, implementing a library, etc.

<comment><USER30> You can use a subset of OAuth - I tend to use the so called "0-leg" version of OAuth, which is pretty much the same as a username/password (consumer key + secret), but with added benefits such as protection against replay attacks.

It's also pretty simple to implement on client side and server side. I usually give our clients a little library to get started with requests.

<comment><USER31> I've implemented OAuth client-side a few times in a few languages. The signing process itself may not be that difficult to understand, but there are a lot of fiddly moving pieces, the specs are painful to read, and everyone has their own unique take on the spec.

I wouldn't call it simple. It's complex to get right, and outright damaging to non-web clients except in the case where xAuth or similar is available.

</comment></comment></comment></comment><comment><USER32> I get the feeling that most people commenting here haven't actually implemented an API that is under heavy use and has strict security requirements.

One of the main problems with Basic Auth that the author fails to mention is that if your passing passwords with every request, you're also hashing that password with EVERY request (assuming your doing REST, ie no client state on the server). And if you're properly hashing passwords in your DB, you should be using a slow hash like bcrypt. That means a single request that might take 30ms now takes perhaps 500ms. And many workloads are going to require multiple hits to the API to accomplish simple tasks, so your talking about both a strain on the system, and a horrible experience from the client's perspective.

<comment><USER33> This is a very good point, and is the sort of situation where API tokens can come into play and be useful. A client can make a single request to "open a session" and receive a short-lived key that is used as the password credentials for subsequent requests. Store active keys - since they are short- lived, offline attacks are less of a concern and you can probably choose to not slow-hash them. When the token expires and a request fails authentication, the client simply requests a new one and retries. The token lifetime is a much easier adjustment for which to weigh security versus performance/load considerations, compared to against broader password storage security.

<comment><USER4> You've described OAuth in part with its refresh and access tokens.

</comment></comment></comment><comment><USER34> This article highlights an important issue. But closing port 80 is sufficient to address this problem. Having considered this article, I think I would still design an API to use HTTPS only, with port 80 closed, with Basic Auth. There's no security problem then, and it's a whole lot easier to manage with existing tools.

(eg, as rb2k_ points out, it makes it easy to use curl to debug things).

<comment><AUTHOR> I agree with you and rb2k_ as it says in the post. HMAC-SHA is suggested for vendors adamant (Stripe) about listening on port 80 on their API host.

</comment></comment><comment><USER35> Agree that the practice of just redirecting http requests to https is a bad idea.

Hope this can help raise awareness why it's bad.

</comment><comment><USER36> Basic Auth should be used only with HTTPS/SSL - who does otherwise? Do not think HTTP Basic is a bad design choice with SSL for securing your service. Any security is brittle if you don't understand what you are upto. That said key based authentication is more apt for APIs.

<comment><USER37> People who can.

</comment></comment><comment><USER38> I was playing about with Fiddler with some mobile apps on my iPhone a while ago and noticed one app was using HTTP basic auth with HTTPS _but_ the application was ignoring SSL errors (I was using a self signed cert on my PC to perform MITM and decrypt HTTPS traffic). This is almost as bad as using HTTP and basic auth because you're basically ignoring the fact that the certificate should not be trusted (at least give the user a choice?). You would be surprised to see how many apps ignore SSL errors and allow you to use any old self signed cert.

<comment><USER39> We had to (begrudgingly) disable cert validation when we still supported older iOS versions, as it was impossible to find an affordingly-priced CA that issued compatible certificates.

</comment></comment><comment><USER40> A great alternative if you can't (or don't want to) close port 80 is to return a 401 for non-HTTPS requests to your API, rather than redirecting with a 301 from HTTP->HTTPS.

This has the side effect of making sure that HTTP clients can never silently redirect, and it's impossible for a developer to ever get their code working without explicitly using SSL. If it never works in development, they'll never ship such code to production.

</comment><comment><USER41> I tend to use an api_key, because it's easier to manage. I'll setup a route to authenticate, where I'll use basic auth to return an api_key, and the remainder of the api either requires an api_key or no authentication at all.

For Rails developers, Ryan Bates does a great job of explaining a few ways to secure your api.

<http://railscasts.com/episodes/352-securing-an-api>

</comment><comment><USER42> I agree that HTTP Basic over SSL is probably fine for requests from a server, in order to prevent sniffing of the connection.

However, I've recently been thinking about how to use a third-party API directly from client-side Javascript, or even from a resident application. If you're doing that, then you really need some way to use keys with validity that is limited by time or scope. In that case, HMAC offers some real advantages.

</comment><comment><USER43> If people can accidentally send plain text password to Stripe for a 403 response and don't care about it, I can't see why people can't accidentally send plain text password to the HMAC-SHA protected port 80.

They are the same thing, both will not work.

(Unless you close the port 80, using HMAC-SHA can't solve the issue.)

</comment><comment><USER44> The problem it seems to me with Stripe and others is that they stuff the API key in as the Basic Auth username. Wouldn't is be safer to use, say, a merchant ID as the username and then the API key as the password (since the password is not transmitted on the errant HTTP)?

</comment><comment><USER3> This may be decent advice for security purposes but unless I can test your API directly from the commandline using CURL I am unlikely to ever get as far as trying out your service.

In other words, use HTTP BASIC (or similar) if you want new users.

</comment><comment><USER45> Closing port 80, great suggestion.

Until you can point me to an alternative authentication scheme that I can expect api consumers to generally have ready-made support for, it's pretty well the only good suggestion in this article.

</comment><comment><USER46> I am a firm believer that all APIs should be available over Basic Auth, even if it's only a small subset to access your own data.

Slinging OAuth shouldn't be necessary to hack your own fun scripts and get your own data.

foauth.org

</comment><comment><USER47> Offer a test bed for your API, where people can test their clients. That way developers will start to use SSL before they they go in production, and no production passwords should leak that way.

</comment><comment><USER48> Obviously it is user agent failure. Why would you want transmit private information clear text?

Edit: File bug to browser makers. Personally use http proxy to remove auth and cookies from insecure traffic.

<comment><USER49> Sending the password more or less in plain text is defined by the http standard. It's not a bug per see...

And I doubt you can convince any browser maker to drop basic auth support.

</comment></comment><comment><USER50> http basic auth is implemented in the server, not in the webapp, that's one fine reason. redirecting from http to https is ALWAYS an issue, http basic auth or not. now then again it'd be nice to have a "better auth" than basic auth that is still not part of the web app.. but yeah.

</comment><comment><USER51> Because I need the user's password in plaintext for example.

<comment><USER52> If you need the user's password in plaintext (or something easily derived from it), then your authentication scheme shouldn't send it over the network at all: there are better ways to handle that scenario.

Also keep in mind that a machine storing plaintext passwords has the same security requirements as a Kerberos KDC, and those requirements are very, very high. Don't do this unless you know what you're doing, and even if you do, you should seriously consider a different scheme (or just using Kerberos itself: they've already gotten things right, so you don't have to risk getting things wrong).

</comment></comment><comment><USER53> So if you offer a https only API and anyone makes the mistake of using http instead, what should be the response of your system? A simple error message with 404 code and without special/identifying headers?

<comment><USER28> The main problem isn't the response, the problem is that on the initial request, the insecure password will be sent in plaintext.

<comment><USER53> But that's not the problem of the API provider. If you explain that you only allow HTTPS and someone makes an HTTP on an unsecured connection, well...

<comment><USER54> Oh but it IS the problem with the provider. Or rather, it will be when some crazy PR storm hits the interwebz with "$YOURCOMPANYNAME leaked passwords!" when someone comes up with some clever way to hack/manipulate traffic with XSS or something. I was able to fetch private authtokens of a Wii game because port 80 was open on one of nintendo's servers(I assume it's there to test in plain text and just didn't close it later) and I was able to fool the software into using port 80 instead of port 443. That wouldn't have worked if port 80 was closed.

<comment><USER53> Makes total sense. Thanks

</comment></comment></comment></comment></comment><comment><USER55> Too much focus on closing port 80. They could just host something else on port 80.

<comment><USER56> No, the whole problem is a http server (ANY http server, serving ANY content) listening on port 80.

Once the tcp connection is accepted on port 80, "dumb" clients (like curl) can just come barging through the door shouting plaintext auth credentials without knocking first, and no http server can stop them from doing that (because that is how the http protocol works).

The only way to stop them from doing that is rejecting connections on port 80. (Dropping packets looks even more like service outage, which was mentioned.)

<comment><USER57> The author made this seem outlandish, but really it's a reasonable and easily done way to go about things. Just have a special subdomain for your API (I don't know, api.*.com) and only listen on 443 with it. Done.</comment></comment></comment>


Cakebrew: The Mac App for Homebrew - <AUTHOR> http://www.cakebrew.com/ <comment><USER2> The engineering world would be a much better place if more people built beautiful, easy to use GUIs on top of the confusing command line apps we all rely on. I switched to Tower for git a couple years ago, and seeing people struggle with diffs and rebasing on the command line makes me sad.

This software may be version one and still have some kinks to work out, but I love it anyway. Nice work!

<comment><USER3> > The engineering world would be a much better place if more people built > beautiful, easy to use GUIs on top of the confusing command line apps we all > rely on.

I'd correct that to:

 _The engineering world would be a much better place if more people built beautiful, easy to use command line apps_

It can be done, although it takes a lot of effort to do well- and a lot of the developers who write CLIs* have very few notions of HCI design. As a result the vast majority of CLIs are inspired from programs that are decades old, and in which no thought was given to the interface, thus perpetuating the cycle.

When well executed, a CLI is insanely superior to a GUI on many fronts (with a few exceptions, naturally, such as image/video editing), and more respectful of the users. It is much more friendly to users with vision or motor impairments: any font and any color scheme can be applied, any method of text input can be used, text readers behave in a much more predictable manner, etc. And of course it enables scripting to a level that GUIs just can't compare to.

Ideally you'd have a well designed CLI for the users who want it & scripting, and a well designed GUI - but let's face it, doing both is a huge drain of time. If you're going to do one, then a CLI is much, much preferable.

On the usability scale, there isn't "CLI apps" on one end and "GUI apps" on the other. Some GUIs are extremely usable, some aren't; some CLIs are extremely usable, some aren't.

I am a staunch supporter of the idea that while GUIs became mainstream and CLIs were relegated to a niche position, it should have been the opposite. But we had mediocre CLIs and decent GUIs, so it's only natural that it went that way. Great CLIs would have been preferable on many fronts.

Traditionally, the main argument against CLIs is the lack of discoverability that GUIs afford, which is a very valid point. That being said, most CLIs don't make an effort to enhance discoverability, which makes the argument still valid, but a little unfair.

Ultimately, I fully subscribe to Jeff Raskin's argument that if you're going to build a tool that users will use on a daily or weekly basis, then it's better to build something with a steep learning curve the first few hours which then results in an efficient and effective tool, rather than something that any newcomer can master within seconds but that will be tedious for extensive use.

GUIs that you can master in seconds belong in smartphone apps that you will use a handful of times and then delete a few weeks/months later (this isn't dismissive- if there's a market for it, then it's legitimate). Powerful CLIs that are a bit rough the first handful of hours but become extremely powerful tool belong in your browser, your email client, your text editor, your calendar, and so on: tools that you expect to use for years, if not your lifetime.

* : In this comment, by CLI I mean any form of program that runs solely in a command line, but that also includes highly interactive apps built with ncurses etc. There are very, very few command line apps that are solely "type a command, get an output" anymore.

<comment><USER4> A toddler can pick up and learn to use an iPad in an hour or two.

That will never, EVER be true of CLIs, no matter how well designed.

Your perspective on this subject seems to be from an extremely narrow viewpoint that ignores the actual real world outside of your own use cases.

<comment><USER3> A toddler also can't operate a letterpress, solder, or fly a plane. Your point?

There are designers who worry about designing for toddlers, but that's a very specific niche, not at all representative of the average computer user. Hence my comment was not concerned with designing software interfaces for toddlers. Of course I wouldn't advocate using a CLI for an application meant for toddlers.

(My perspective on the subject comes from someone with a graduate degree in HCI, papers published at major ACM conferences, and who has shipped dozens of interactive software titles in the past decade (including some that have, surprisingly, been destined primarily for toddlers). I'd love to pursue a constructive conversation, but your ad hominem makes it hard.)

<comment><USER4> I apologize—I suppose I am somewhat irrationally offended by your seeming disregard for the biggest advance in user interfaces in the history of computers, the graphical touchscreen. _Especially_ considering your position as an expert. GUIs have made computing available to the masses—not just to experts—and that is incredibly important. And touchscreen interfaces have accelerated this advance.

> A toddler also can't operate a letterpress, solder, or fly a plane. Your > point?

My point is that you are focused on a very narrow set of use cases (e.g. operating a letterpress, soldering, or flying a plane). For the vast majority of computing tasks, a (possibly touch-based) GUI interface is ideal. Yes, CLIs are better for some things, but those things are a tiny minority.

> There are designers who worry about designing for toddlers, but that's a > very specific niche, not at all representative of the average computer user. > Hence my comment was not concerned with designing software interfaces for > toddlers. Of course I wouldn't advocate using a CLI for an application meant > for toddlers.

But I take it from this that you WOULD advocate using a CLI for email, social media, shopping, instant messaging, reading a magazine, designing buildings/airplanes/computers, audio recording and production, data visualization, doing your taxes, operating points of sale, etc., etc., etc.

(And now I imagine that you will try to convince me that a CLI _is_ actually better for one or more of those things. I am unlikely to believe you.)

GUIs are better, not because they are more efficient, but because they are _intuitive_. People can understand them, so they can actually use them effectively. Being able to use an inefficient tool is vastly better than being unable to use an efficient one. Focusing on intuitiveness has opened up computing to the entire human race, instead of just an elite few.

<comment><USER3> The word "intuitive" is casually thrown around when talking about interfaces, and yet it has a very specific meaning in HCI, far from what most people believe. As posted in another comment: [http://www.asktog.com/papers/raskinintuit.html](http://www.asktog.com/papers/raskinintuit.html)

I don't deny that GUIs have their uses, and that there are certain use cases where they do outperform text-based keyboard-driven interfaces. But the reality is that those use cases are nowhere near as overwhelmingly numerous as GUI proponents make it out to be, and that for the vast majority of text driven tasks (including email, instant messaging, engineering work, doing your taxes, operating points of sale, etc.) they are superior in most regards. Note that I do not advocate abandoning all graphical tools on the computer - you're naturally always going to need an image editor, a video player, something to edit 3D models, etc. The framebuffer is always valuable; GUIs, not so much.

On top of that is the consideration that a lot of our computer use these days converges in the browser, which is a very unusual beast altogether. We originally designed the browser to view documents, and it has now evolved in a weird steam machine that does pretty much anything and everything. It's problematic, because the web is notable for being "disrespectful" of concerns such as accessibility to handicapped users. (note that the best citizens when it comes to such matters, such as Hacker News, Wikipedia, Reddit, and quite a few others, aren't that far off from purely textual interfaces)

Obviously it's going to be hard for me to convince you otherwise in a HN comment. That being said, if you have a genuine interest in the topic, I recommend that you read Jef Raskin's "The Humane Interface", and Ted Nelson's series "Computer History for Cynics". They're a good introduction that allows one to think about the design of computer interfaces independently from the GUI mindset that has imposed itself on the profession over the past couple of decades. The modern GUI (which is really Xerox Parc's GUI) is really not all it's made out to be, and there are many compelling things about the alternative branches (check out for example Plan9, for something completely different).

<comment><USER4> Xerox Parc's GUI changed the world in the Macintosh and Windows, bringing computing to the masses.

The iOS-like GUI changed the world again in the iPhone, Android, and the iPad.

The reason they did is that they were better. Not because they were pretty. You seem to be convinced that these paradigms were not massive improvements on their predecessors. I'm not sure how you manage to maintain that view.

What makes them better is that they are visual in nature. Human beings have an immense amount of latent machinery to help us deal with visual things. Literacy, on the other hand, is an incredibly recent phenomenon. Interfaces that are based on words for communicating semantics instead of primordial visual cues like space, size, contrast, color, movement, etc., will never be able to compete on intuitiveness/ease-of-use/ease-of-learning.

<comment><USER5> Problem I have with most touch interfaces (and to a wider extent the whole closed iOS ecosystem) is that they still have to show how they actually improve productivity. So far all we've seen is dumbing down the "user experience", turning computers from a productivity and creativity device into a pure media consumption device, glorified TVs basically. This is much much worse then the BASIC home computers of the 80's.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER6> Nice idea, but I immediately got a frozen app when trying to update formulae: [http://i.imgur.com/3XDi0NA.png](http://i.imgur.com/3XDi0NA.png)

EDIT: On further inspection, it did not only freeze... it broke a lot of my formulae. I'd be very wary of using this application.

<comment><USER7> This thing needs to use threads. It's almost embarrassing to not make use of that when facilities like Grand Central are readily available.

The app locked up for me beach ball-style when doing an update. There's no reason for this. Do not block the UI thread. Ever!

<comment><USER8> My first thought after clicking a single button. GCD threads are cheap and easy - just launch a spinner and start a thread, don't block the main one.

</comment></comment></comment><comment><USER9> Looks good but I'm curious, why is it not distributed signed with an Apple developer account? That means there is no kill switch Apple can flip in case it turns out to be malicious software. (Especially important for a package manager!)

Is it just the $99 fee or is there some other reason not to sign it?

<comment><USER10> Fair question, but keep in mind the standard Brew install is piping a shell script from curl.

<comment><USER9> Yeah, off of an open source repository on github that the community can inspect. But here you are being asked to trust a binary from some developer out there.

That's the reason Apple added this signing feature. I'm just wondering if there's really a good reason for a developer to not follow it.

<comment> vhost- >Yeah, off of an open source repository on github that the community can inspect.

That doesn't make it better. What if your internet connection craps out while it's downloading the line "rm -rf /usr/local/bin/old-binary" and it happens to stop at "rm -rf /usr"?

Oops.

<comment><USER11> Is it on a stream-and-run method of executing tasks? Surely it looks for an end-of-line or end-of-command terminator like "\n"

<comment> vhost- Curl will still pipe partials: [http://blog.existentialize.com/dont-pipe-to- your-shell.html](http://blog.existentialize.com/dont-pipe-to-your-shell.html)

<comment><USER11> That's so sketch and dangerous.

</comment></comment></comment></comment></comment></comment></comment><comment><USER12> This is one of those things where I don't have any idea what's going on. I assumed from the title it was about using your Mac to write apps for your Mac. But reading the page I can't even confirm or deny that theory.

<comment><USER13> A quick google search of 'homebrew' tells me: 'Homebrew — The missing package manager for OS X'

Ah, now it makes sense.

<comment><USER14> Hah, interesting and facetious way to LMGTFYing someone.

</comment></comment></comment><comment><USER15> Nice. Now add "brew cask" support ([https://github.com/phinze/homebrew- cask](https://github.com/phinze/homebrew-cask) basically brew for GUI apps) and I could see non-developers using it as well.

<comment><USER16> What's the point of homebrew cask? Why is it any easier than finding an app I need and installing it normally?

<comment><USER17> Same reason people love package managers in general. A single bash script can install all the programs you want. Add Homebrew Cask and even your GUI apps can be included in that script alongside wget, vnstat, whatever.

<comment><USER16> Makes sense to me! Probably not worth re-installing programs I already have, though, would you agree?

<comment><USER17> Yea, I only do a "brew cask search" for new apps I want to install. I believe you would want to avoid attempting to re-install an app via Cask that was installed normally (~/Applications vs /Applications). Personally, I would do a clean install to transition an app to being managed by Cask.

</comment></comment></comment></comment></comment><comment><USER18> Looks great! Small grammar suggestion: >Too much afraid to use the terminal

Should just be "Too afraid to use the terminal"

<comment><USER19> Or just "Afraid to use the terminal?"

</comment></comment><comment><USER20> Crashes on 10.8.5 [1] due to NSColor being used improperly

[1] [https://aroch.io/cakebrew.log](https://aroch.io/cakebrew.log) (Sorry for the self-signed cert...)

<comment><USER21> +1 Crashes on 10.8.5 on launching.

</comment></comment><comment><USER22> What can I do with this that I cannot do with the command line?

My use of brew is rudimentary, but I only ever use four brew commands:

brew install brew update brew upgrade brew uninstall

If this helps make brew more popular, then I think it is a great addition. It seems I am not the target audience, but hopefully one exists!

<comment><USER23> Maybe make it easier to discover features. I didn't realize you could pass options to brew install. If you do 'brew options package_name' you can see the options you can pass. For example, poppler can be compiled with glib support by running 'brew install poppler --with-glib'.

I'm just surprised I can't 'brew install cakebrew'.

</comment></comment><comment><USER24> Congrats, this is wonderful. Now I just wish someone would create a utility to sort out conflicts caused by running MacPorts at the same time (or a straightforward way to migrate to just one or the other).

<comment><USER25>
        port installed > installed_packages.txt
        sudo port -fp uninstall installed
        sudo rm -rf \
            /opt/local \
            /Applications/DarwinPorts \
            /Applications/MacPorts \
            /Library/LaunchDaemons/org.macports.* \
            /Library/Receipts/DarwinPorts*.pkg \
            /Library/Receipts/MacPorts*.pkg \
            /Library/StartupItems/DarwinPortsStartup \
            /Library/Tcl/darwinports1.0 \
            /Library/Tcl/macports1.0 \
            ~/.macports

Then install equivalent Homebrew packages based on installed_packages.txt. It takes less time than you'd think.

</comment></comment><comment><USER26> Cakebrew is a godsend!! Starting using it now, I have to say I'm not disappointed!

Coming from MacPort, Homebrew actually is one of the simplest commend line tool I used to install an application on a Mac. Still, numerous occasions I had to spent a considerable amount of time troubleshooting warnings and library conflict issues. In situation that I need to setup development environment quickly such as PHP and Apache, Laravel etc, the last thing I wanted is more overhead.

I only wish something like this would exist for Composer, or is it already exist that I'm not aware of?

<comment><USER27> How will Cakebrew fix that?

I know what you mean (I've had problems with a few things), but those are problems with the formulae, not Homebrew itself.

</comment></comment><comment><USER8> Nice app, but it's in desperate need of threading. I get that it's launching brew and putting it's output in a panel, which can be slow, but it'd be better to kick off a GCD thread to do the work and update the UI when it's finished. The beachball is never a good experience, and every command I tried to run briefly beachballed.

<comment><USER28> This was my first issue with it too. It makes it feel clunky and slow. The UI is generally not that great anyway. E.g. updating and upgrading is too complicated. There should be one button to do it. And it should update automatically when launching.

The sheet that shows the output of an upgrade command does not have clickable links if something fails. It's also really small.

Even then always unfinished [PortAuthority for macports]([http://www.codebykevin.com/portauthority.html](http://www.codebykevin.com/portauthority.html)) was a lot better. The GUI package manager for Mac OS X I liked best was [Fink Commander]([http://finkcommander.sourceforge.net/about/](http://finkcommander.sourceforge.net/about/)).

Cakebrew looks like the authors have never seen a graphical package manager before.

</comment></comment><comment><USER29> Looks great, but brew is such a simple tool. It's one of the ones I don't think I need a GUI for. Maybe if I start installing lots of packages it will come in handy.

</comment><comment><USER30> Looks good. Although out of all the CLIs I use on a daily basis, I'd have to say Brew is probably the easiest and most user-friendly.

</comment><comment><USER31> I'm not likely to use this personally, but kudos for taking the time to make what looks like a lovely GUI to sit on top of HB :)

</comment><comment><USER32> Congrats for the launch, fellow brazilian.

<comment><USER33> nice to see a programmer from central brazil for a change.

</comment></comment><comment><USER34> Finally! This is such a good idea. For non technical people that need specific tools this is golden. Great job!

</comment><comment><USER35> Why only for 10.7 or later?

</comment><comment><USER36> Very nice, thank you!

</comment><comment><USER37> Oh look, Fink.

</comment><comment><USER38> Glad it's so easy and simple to use. It looks great. What is it?

<comment><USER39> It's a GUI for Homebrew (brew.sh - OSX package manager; akin to aptitude or yum etc).

<comment><USER38> Oh I see! Not homebrew as in home-made software :D Now it all makes sense.

</comment></comment></comment><comment><USER40> ok, I get it, I'm not part of the in-crowd. WTF is homebrew please?

And can we please stop it with the sites that blather on about stuff in a way that assumes every visitor knows the jargon and slang.

<comment><USER41> Even if you've never used a Mac, not knowing about homebrew is somewhat living-under-a-rock-ish.

Googling Homebrew comes up with

#1 - brew.sh, the homebrew homepage #2 - the homebrew github #3 - the homebrew wiki

It's really not that hard to figure this stuff out.

</comment></comment><comment><USER42> Is anyone else disappointed this thread is not about brewing your own beer?

</comment><comment><USER43> Nice web page. What is it?

<comment><USER43> Downvotes noted. Apologies.

</comment></comment><comment><USER44> Really cool!

</comment><comment><USER45> why do people find it necessary to add a GUI to every fucking thing

<comment><USER46> Because there are plenty of users who are not comfortable using a cli for even a few things. Homebrew specifically is a pretty core staple in the OS X community and this now provides more accessibility for those people.

</comment></comment><comment><USER47> Anyone else find the phrase 'King of the Forest' slightly cringe-worthy?</comment>


Ask HN: What podcasts do you recommend CS/geek related? - <AUTHOR> <comment><USER2> Software engineering daily - A daily pod of around 1h per episode every day a person from a company/startup/OSS is interviewed about their product and or company. Can be quite heavy from time to time but you always learn something new Talk python to me - Great show about python, feels a bit lighter and the talks varies from interviews to more rants about the python community python bytes - Same as above darknet diaries - Documentary style about hacks etc.

</comment><comment><USER3> The only one I listen to regularly is the 1Password podcast Random but Memorable. I work for 1Password but have no influence on or responsibility to the podcast, I just genuinely enjoy it.

I also have in my library:

* Rework by Basecamp * The Knowledge Project with Shane Parrish * CoRecursive with Adam Gordon Bell * Hope in Source (unique because it's all about Faith and open source)

</comment><comment><USER4> [https://lexfridman.com/ai/](https://lexfridman.com/ai/) This is one more AI but interesting guests

</comment><comment><USER5> ATP.fm</comment>


Looking for a developer to partner up with on side project - <AUTHOR>

So I'm a design guy and entrepreneur. I've always found it hard to find good engineers for my startups.
The idea is basically simple - a directory of hand-picked, qualified web engineers. The target market would be startups who are always on the lookout for good engineers.
Here is a mockup of the homepage: http://i.imgur.com/JcN2c.jpg
So I have the design covered, and need a developer as a partner who can build this out. Plan is to charge the startups to view the database. There are a few sites doing this (stackexchange is one), but I would like to target small startups and be a more robust & affordable alternative.
If you're interested send me some info about you and your work to marcom10[at]gmail[dot]com <comment><USER2> I don`t see this as working. On StackOverflow, you can view the answers engineers have written for specific problems and see how they are viewed by other people.

<comment><AUTHOR> Sure there are other sources to use, just as there are many job boards for employers to post on. Point is I plan on making this better than Stackoverflow for a fraction of the cost. Also my plan is to target early-stage and smaller startups rather than huge corps.

</comment></comment><comment><AUTHOR> homepage mockup clickable: <http://i.imgur.com/JcN2c.jpg>

</comment><comment><USER3> Looks cool but what is impeding 'bad' engineers to register and show up in your web?

Good luck :)

<comment><AUTHOR> Good question -- the idea is that engineers will be hand-picked based on past experience, work, recommendations, endorsements etc. So not everyone that applies will be listed. This is something I'd like to clarify / flesh out further with the partner

<comment><USER3> Cool man, I'll apply!</comment></comment></comment>


The IIT entrepreneur with an idea bank - <AUTHOR> http://business.rediff.com/slide-show/2009/sep/23/slide-show-1-tech-entrepreneur-with-an-idea-bank.htm <comment><AUTHOR> FYI:

100 Indian Rupee (Rs.) = 2.06622 US Dollar

100 US Dollar(USD) = 4839.76000 Indian Rupee(INR)

<comment><USER2> The sentence mentioning money, when converted into US$ reads

"it took us a year to get started with an initial investment of 3000 $ and a government grant."</comment></comment>