Live data from Hacker News

How we broke PHP, hacked Pornhub and earned $20k

evonide.com

71–80 of 107 posts

Re: How we broke PHP, hacked Pornhub and earned $20k

#71
post #26

Earlier quoted context omitted.

FWIW, it places well across TechEmpower benchmarks: http://www.techempower.com/benchmarks/

Raw PHP is reasonably fast. The performance issue comes with loading source files on every request: http://talks.php.net/show/froscon08 This means that there is a conflict between performance and having a well structured object oriented framework. Demand loaded classes and byte code help a lot with that: http://www.yiiframework.com/performance/ Best would be a model where a persistent process handles multiple request…

> This means that there is a conflict between performance and having a well structured object oriented framework.

What do you need a 'well structured object oriented framework' for? You're going to build up a huge object graph in memory, to output some HTML, and then throw away all the objects at the end of the request. Nobody is going to see your beautiful object tree, so don't bother. A blog entry page should be super simple.

header, title, content, comments, recent comments, footer.

Header and footer are dead simple echos of the boilerplate, maybe replace in the html title or something. Read the title and content from disk[1]. Have another data file for all your articles for the index page.

I prefer not to have comments on my blog, but if you must, you can put them in a database; limit to something like 100 or 1000 comments per article (because really) and limit threading, and it's going to be pretty quick to query them (make sure your webserver is doing reads from a database in the same metro area, if not on the same box).

Recent comments is across all blog entries; I would probably add a index on the time in the comments table and just select 2 from there; you could union that into the earlier comments query if you don't want to make two round trips to the database.

You don't need to do this with concurrency, each page load has barely anything to wait for, so more threads doesn't help throughput. Run enough php workers (php-fpm, or apache children if you're using apache_mod_php) to keep your cpu busy, and you're golden.

[1] There's four articles on this blog -- it doesn't need a database. PS run php as a user that can't write anywhere on the disk, and push the blog entries and the summary datafile with another user.

Edit to add: If you skip comments (or outsource to disqus or some other comments w/ javascript platform), you can make the whole site just static html, and leave PHP at home. OTOH, these guys are running Wordpress, because they like frequent security updates?

Re: How we broke PHP, hacked Pornhub and earned $20k

#72
post #20

Earlier quoted context omitted.

I'm certainly positive it's faster than Ruby, Python and Java.

Ruby and python aren't exactly known to be fast. In my experience php is fast enough until you start generating lots of garbage. It seems it wasn't really designed to garbage collect at all, but to rely on the per-request cleanup.

> until you start generating lots of garbage

We should really stop pretending that the garbage collector is the problem with langauges. The collector isn't the problem, your garbage is the problem.

[Not that I'm a proponent of PHP, though it does make popping shells far more fun.]

Re: How we broke PHP, hacked Pornhub and earned $20k

#74
post #26

Earlier quoted context omitted.

FWIW, it places well across TechEmpower benchmarks: http://www.techempower.com/benchmarks/

Raw PHP is reasonably fast. The performance issue comes with loading source files on every request: http://talks.php.net/show/froscon08 This means that there is a conflict between performance and having a well structured object oriented framework. Demand loaded classes and byte code help a lot with that: http://www.yiiframework.com/performance/ Best would be a model where a persistent process handles multiple request…

> The performance issue comes with loading source files on every request

PHP ships with an opcode cache built-in (and at least on every distro I've seen, enabled by default) since PHP 5.5 that keeps the compiled bytecode in shared memory

Re: How we broke PHP, hacked Pornhub and earned $20k

#75
post #70
post #68

Earlier quoted context omitted.

It's with data as with unprotected sex: when you take data from someone, you're exchanging data not just with them, but with everyone with access to their systems and anyone they exchange data with. I'll start calling airgapped systems abstinence-only networking.

As we all know abstinence-only doesn't work, so maybe there are stronger parallels here than at first glance. ;)

Well, it works if you actually practice it...

Re: How we broke PHP, hacked Pornhub and earned $20k

#76

Earlier quoted context omitted.

Having per-table random seeds and properly designed hash function prevents remotely forced collisions. This is the typical defense against hashtable DOS. It has to be done properly, of course -- for example, a poorly designed hash function could have characteristic collisions for many different seeds.

Please be aware that many common hash functions are easy to generate collisions for independent of the seed . This includes both MurmurHash and CityHash. These aren't poorly-designed hash functions: they have excellent distribution characteristics. But the way they use their seed wasn't designed to resist this kind of attack.

Rather than "poorly-designed", I should have said "cryptographically insecure".

Most hash functions are engineered for speed and collision resistance, in that order. Trading collision resistance for speed is worthwhile for many workloads, since it barely affects the average case.

Re: How we broke PHP, hacked Pornhub and earned $20k

#77
post #75
post #70

Earlier quoted context omitted.

As we all know abstinence-only doesn't work, so maybe there are stronger parallels here than at first glance. ;)

Well, it works if you actually practice it...

In both cases, it's much easier said than done.

Re: How we broke PHP, hacked Pornhub and earned $20k

#78

Earlier quoted context omitted.

Please be aware that many common hash functions are easy to generate collisions for independent of the seed . This includes both MurmurHash and CityHash. These aren't poorly-designed hash functions: they have excellent distribution characteristics. But the way they use their seed wasn't designed to resist this kind of attack.

Rather than "poorly-designed", I should have said "cryptographically insecure". Most hash functions are engineered for speed and collision resistance, in that order. Trading collision resistance for speed is worthwhile for many workloads, since it barely affects the average case.

> Most hash functions are engineered for speed and collision resistance, in that order.

I disagree with that assessment. I think most hash functions are designed for speed and good distribution of outputs given normal inputs. But designing to resist collisions against someone trying to deliberately create them is a different thing entirely.

> Trading collision resistance for speed is worthwhile for many workloads, since it barely affects the average case.

I think that is far from established. SipHash is marketed under this premise, but from what I have heard it is significantly slower, particularly for short inputs.

Re: How we broke PHP, hacked Pornhub and earned $20k

#79
post #63
post #60

Earlier quoted context omitted.

>What does it mean? I should not accept any user input at all? No, it means you should never assume that user data is safe, or even sane. Assume, rather, that everything every user is sending you is malicious, all the time, and write your code accordingly. >. What if I have a comment form that should accept any characters? First, you probably shouldn't, because your database and HTML should be using explicit characte…

> it means you should never assume that user data is safe, or even sane I'm curious if Haskell's purity helps developers focus on this issue and therefore makes it easier to mitigate. Given that all user input/state already has to be handled carefully (for ex: with monads). It will be obvious in the codebase which parts need to be zero'd in on for possible attack vectors.

Haskell's web frameworks help, but it's nothing to do with purity. In fact any web framework can do this, you segregate user-supplied data and ensure it can never be supplied to an untrusted function without explicit cleaning.

Perl and Ruby have included this as a 'tainted' flag, many functions cannot be called with a tainted string.

Re: How we broke PHP, hacked Pornhub and earned $20k

#80

Earlier quoted context omitted.

Rather than "poorly-designed", I should have said "cryptographically insecure". Most hash functions are engineered for speed and collision resistance, in that order. Trading collision resistance for speed is worthwhile for many workloads, since it barely affects the average case.

> Most hash functions are engineered for speed and collision resistance, in that order. I disagree with that assessment. I think most hash functions are designed for speed and good distribution of outputs given normal inputs. But designing to resist collisions against someone trying to deliberately create them is a different thing entirely. > Trading collision resistance for speed is worthwhile for many workloads, si…

Yes, speed for normal inputs is what's generally desired.

A faster hash function can yield better overall performance than having fewer collisions. Here's some empirical evidence for this: https://www.strchr.com/hash_functions

The speed is correlated only weakly with the number of collisions-- and using the modern x86 CRC32 instruction yields the best results.

Post reply on HN