The reason it was “relevant” is simply because there’s more Monty Python fans on here than basketball fans. Which is fine if we’re talking purely about +votes but it doesn’t justify flagging a submission.
Peer moderation is abused on this site and it’s getting steadily worse. I’m on the verge of giving up on HN entirely, just like many of my other professionals I personally know already have done. Ultimately it will be HNs loss because the quality of content posted will decline.
Another thing to bare in mind, for those who are rolling their own, is how you caress those passwords from the DB.
The common approach is a simple DB SQL select. But that then means if your web server gets exploited an attacker can dump the entire password database.
The safer option is to write a stored procedures to return or modify that table and set permissions on that table so even your web app creds can’t directly query the password table. Then your web service only has access to check a single password, rather than downloading every hash on the DB.
If you can also offload the encryption/decryption and hashing then that is another step forward too.
I'll bite. It doesn't seem obviously wrong to me. I would also love to know if I'm misunderstanding something.
I've never seen it done this way, but I think postgres pgcrypto could support this.
If I had to guess, I haven't seen it done this way because authentication frameworks are not normally in a position to lock down access to the database in this way (e.g. it couldn't create a password table that the web app credentials can't see, because it's integrated into the web app and uses the web app credentials to create the password table). The way they typically behave is:
- When updating password, run bcrypt in the web server and INSERT
- When testing password, SELECT the bcrypt hash down to the web server, and test on the web server.
Have you used this stored procedure strategy in production? I'm particularly interested if it's caused any challenges with resource usage in the database server?
The top answer in this stack overflow question makes the argument that you should bcrypt in the web server to lessen the time it's unhashed:
> Use php bcrypt if you can, it'll lessen the time that the password remains unhashed.
https://stackoverflow.com/questions/2647158/how-can-i-hash-p...
I'm not sure I agree with this argument, unless perhaps the database is hosted by a separate vendor (which would mean another party is receiving the unhashed password). Also note: the strategy proposed in that answer doesn't have the benefit of a stored procedure preventing a SELECT all, so maybe the less time argument makes sense in that case.
Perhaps there's a valid discussion around - is this going overboard? Is preparing for a leak of web app database credentials an attack vector we really need to prepare for? If we do, are password hashes the critical data we need to be securing in this manner? When hashes leak I've been asked to change my password as precautionary measure, but hashing algos are such that this event shouldn't be catastrophic. Unlike a credit card number leak, for example, which would cause a bigger headache.
I learned this technique when I worked on the blue team of a cyber security firm.
It’s not about sending your passwords in clear text to your RDBMS. You’d still use bcrypt like you normally would but instead of querying the password table directly you’d have that prewritten as a stored procedure. That way you can have different permissions for the password table.
Some frameworks and/or other managed solutions might already be doing this but it’s worth mentioning anyway since people are talking about hand rolling their own auth.
I don’t know why I added the part about offloading encryption though. That doesn’t make sense. I guess that will teach me talking security before my first coffee of the day
I can't really use bcrypt like I normally would, since bcrypt normally* concatenates the cost and salt into a single string with the hash that I store in my database:
https://en.wikipedia.org/wiki/Bcrypt
I believe I can split out the cost and salt. That would let me:
1. SELECT the user's salt and cost from a table that is accessible with my web app credentials.
2. Run bcrypt on the user-provided password with the selected salt and cost within my webapp.
3. Ask my stored procedure if my resulting hash matches the hash in the database, even though I cannot SELECT the hash directly with my web app credentials.
Am I understanding this correctly? I imagine it would have been easier pre-bcrypt, when generating salts was less abstracted away from the developer.
I can't think of a reason this wouldn't work, and it adds a layer of security if implemented properly. But I say that hesitantly, as I would all things crypto, particularly since I wouldn't consider it common practice and I'm not sure if I'm overlooking something. I'm pretty sure I'd need to hack on bcrypt-ruby more than comfortable to actually implement.
* I say normally because that's what the wiki says and how bcrypt-ruby behaves, but I haven't done wider research.
bcrypt does not allow me to not use a salt. A connection is the same if it's the same file descriptor and it's been open continually. My client uses public key pinning to ensure it is talking to my actual server. I don't have any mechanism to prevent someone who can break TLS and take over TCP connections from impersonating users in my online game.
Re salt, presumably you’re storing that bcrypt as a hashed string though?
Re TCP connections, I was thinking HTTP proxies. Sounds like this isn’t HTTP traffic though so that’s not an issue.
Also why was my previous comment negative karma’ed? All I was doing was asking a couple of questions on a post that’s quite vague. The amount of abuse HNs rep system gets is pretty absurd.
This string includes the algorithm, the difficulty, the salt, and the hash, so bcrypt.verify can do everything for me when someone tries to log in.
I appreciate your line of questioning. My reply to the top-level thread is pretty low value, since most people are trying to build web services that need sessions that persist across connections.
Complaining about downvotes is usually a way to collect more downvotes. This is partially because people are aware that it is against the guidelines at https://news.ycombinator.com/newsguidelines.html and partially because people get some sadistic pleasure out of punishing minor transgressions.
You're getting negative karma'ed because your comment shows a lack of understanding of what bcrypt is and what it does.
Here's a short explanation: bcrypt is a hash function that you should use for storing hashed passwords. When calculating the bcrypt hash of a string, a salt is automatically added. The result you get looks something like this: `$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy` The 2a specifies which version of bcrypt was used, the 10 is the number of rounds, N9qo8uLOickgx2ZMRZoMye is the salt and the remaining characters are the hash. When checking this hash against a password you have to call a second function and pass in the password as well as the hash. This second function will automatically parse the passed in hash and calculate the hash of the password with the same number of rounds and the same salt.
Your opinions of Go are quite clear, given every time there is a thread on HN about Go your relish telling everyone how backwards a language it is. Yet weirdly you’re not the only competent engineer out there.
I’ve been programming for 30+ years and used many of the languages you’ve described. In fact I’ve written code professionally in well over a dozen different languages (I stopped counting somewhere in the last decade). Yet I still find myself productive in Go. It’s not just the compiler speed either. You talk as if people are idiots or are delusional when actually Go is quite a nice language for a great many people with real world problems to solve.
I’m sure I’ll get downvoted for saying this but there is so much snobbery and elitism in these kinds of threads and it’s absurd. Live and let live guys.
Google has fuck all to do with my decision to use Go and nor has it ever been a consideration. In fact I’m about as decoupled from Google as one can reasonably expect to be.
I think you need to do some research into what “personal preference” actually means because you seem to think your own preference is gospel and everyone who disagrees is a magpie (which is just an indirect way of saying “idiot”). And frankly it’s getting tiresome watching you derail every software development thread.
Yeah. But your reply to pushpop just lost validity.
And you might at least consider whether the person who's wrong on the Internet might in fact be you.
And you might consider whether, even if you're right, you're also being counterproductive in how you're going about trying to persuade others. When someone raises a valid point against something you say, you don't acknowledge the point. Instead, you find something - anything - that you can quibble with in what they said. This makes you look like someone who wants to win the argument at any cost, rather than someone who wants to have a reasonable conversation. This makes some of us wonder how biased your interpretation of events is. That is, your hyper-argumentativeness makes you less persuasive*, rather than more.
You too noticed pjmlp keeps regurgitating the same stuff about Go on every chance he gets?
Pretty combative and low effort content. Snarky replies with little respect to others opinions. Always posting jabs at Go about how 90's languages are better in every way yada yada. Do mind the tendency to veer into offtopic too.
Given the effort, I sometimes wonder how painful it must be for this person to see others enjoying and being productive in the language.
The "live and let live" point would be stronger if there was not a stream of people arguing that "go is so productive", as if other languages were adding wikipedia links in compiler logs to distract us.
Go is productive in specific ways. Other languages are productive in other specific ways. That’s why we have different programming languages solving different problems.
So if someone says they like Go because they’re productive in it that doesn’t mean all other languages are shit. That only means Go solves the specific kind of problems they need solving.
This is why I hate languages flame wars and why commenters like the GP exasperate me. They have different problems they need solving and talk about programming languages like there is a one size fits all. That’s not the case.
Now you can `rustup install <version>` easily with everything taken care of. Of course, the latest stable release is automatically installed already. And Rust provides automatic install scripts for Windows, Mac, and Linux. Whereas Go is more involved than is expected for any modern language.
You can just download the go tarball and go from there. Technically you don’t need to install Go, you don’t need environmental variables set etc.
But I do get your point. You are absolutely right that go doesn’t hand hold you through that process and thus a thousand different people have a thousand different methods for doing it.
I’ve not heard of that perspective before however I’m not going to discount what you’re saying because everyone’s psychology is different.
For what it’s worth, most people I know feel pride and a sense of accomplishment if they’ve found motivation to do more than they promised themselves. But as I said, everyone’s psychology is different.
This article is a garbage rewrite of the original blog[1]. It misses a boatload of detail and even gets some details wrong along the way (Like the fact .NET isn’t actually running on DOS)
+1. Thanks for the link to the actual article. Don't know why this is downvoted. Clearly more insightful than the MS advertisement spin of the article. Perhaps the original link should be replaced with it.
It's not a rewrite. Scott Hanselman is a very popular and well-liked evangelist in the .NET community. He's highlighting Michal's project to his large audience with several links to the original work throughout the post.
That's a disingenuous definition. Obviously the original is a "better" read because it's the full project being featured.
Scott's article summarized and intro'd the project to people who never saw the original, including the person who posted it here on HN. That's adding quite a lot of value.
Why are you so intent on putting down Scott's post?
I think there’s some bias going on here. Any other blog on any other subject and I’m sure you’d be the first to say “link to the original rather than the summary”. In fact people not linking to the original work is popular complaint on here. The fact this is Scott’s blog shouldn’t change anything and even you have agreed that the original is better. So why are you arguing as if it’s me who’s making this personal?
Anyway, I’m glad you got something from it. I personally didn’t, which is why I made my initial post, but I did find the original source to be really well written and thought others might prefer that too.
Its a substantially different article mostly about running on Windows 3.1; whereas the first is about shrinking the executable under 8 kilobytes (but not DOS).
I don’t think it’s possible to build a suction cup (or in fact any climbing tool) which will work 100% of the time against any countermeasure. However this design does seem a significant step forward from existing suction cups.
The reason it was “relevant” is simply because there’s more Monty Python fans on here than basketball fans. Which is fine if we’re talking purely about +votes but it doesn’t justify flagging a submission.