Hacker News new | comments | show | ask | jobs | submit login
Cryptographically Secure PHP Development (paragonie.com)
114 points by CiPHPerCoder on Feb 10, 2017 | hide | past | web | favorite | 30 comments



This Paragon shop is the only group I ever see putting out any quality code/docs in the PHP ecosystem. They're simultaneously proof that it's possible to develop good software in PHP, and that PHP is otherwise a mess, insecure, and should be pretty much avoided.


> PHP is otherwise a mess, insecure, and should be pretty much avoided

That doesn't ring true to me. Personally, I think a lot of the perception is just that PHP appeals to a broad audience, so there's a lot of unskilled people producing code.

There are some language inconsistencies so "messy" might be justified. I don't see it, though, as inherently less secure than other popular languages.

If you mean, for example, SQL injection, php does provide the correct path, and it's in their documentation. Sure, it's possible to use aribtrary strings in SQL, but it's also possible in Python, Ruby, Perl, and so forth. Similar for traps like eval().


They might be alluding to some of the specific examples in our blog post. Like, mbstring.func_overload, or chr() being a great way to leak crypto keys via cache-timing.

These sort of things aren't obvious and can very easily (and justifiably) be blamed on the language itself.

A lot of PHP crypto libraries are very cavalier about using functions without understanding their implementation details.

https://github.com/devi/Salt/blob/fde775cf52402013efce812759...

https://github.com/phpseclib/phpseclib/blob/ab1da5ac1f2fa60b...

https://github.com/zendframework/zend-crypt/blob/9b7da4a6d4d...

Fortunately, most cryptography libraries these days just wrap OpenSSL and rarely implement their own ciphers or hash functions.


Hmm. Most languages have some equivalent to chr() and ord(). And clunky unicode support isn't exclusive to php.


What you're saying is, it's unsafe to write a crypto library in PHP without being aware of PHP internals. Which I'd agree with, in general.

Thankfully the PHP community now has a group like Paragonie willing to share implementation risks. And because of that, we can help solve the problem with pull requests to those libraries.


>so there's a lot of unskilled people producing code.

It's not just that. There's also a lot of people who spent their entire careers working in the PHP ecosystem. All the bad practices common among beginners get ingrained in them as their go-to design patterns, because they never learn things like "authenticating APIs with cookies is bad", or "business logic doesn't belong in the controller". They'll even defend their bad patterns because "that's how we've always done it", never making the connection between what they've always done and the problems they've always had.


Lack of knowledge on design patterns and fat controllers are not inherently attributes of a PHP developer


You're right, it's not inherent to nor exclusive of PHP developers. It's entirely possible to write good code following good design patterns in PHP. But regardless of reason, that's not encouraged in the PHP community. A person who starts out writing PHP and stays in PHP development is, in my experience, far less likely to follow good design patterns.


I think it depends on the community you're involved in?

For example, Laravel, Slim, Symfony and Yii frameworks do encourage good design patterns (Laravel may have fallen off the wagon here though). I've seen pretty good code from October CMS, Craft CMS and even Magento 2.1 is decent.

A lot of the PHP community is modernizing very fast even if WordPress can't (or won't). I think a person who starts out writing PHP today on a modern PHP framework will be almost as likely to pick up good design patterns as someone who is starting, say, .NET Core.


Actually, those frameworks don't encourage good design patterns. Those frameworks copy design patterns from other languages, assuming that "design pattern" is a proxy for software quality. The flaw in this is that the PHP runtime is not suited to executing large amounts of "Design Patterned" code. It's cargo cult software engineering.

Symfony is by far the worst of these that I have seen. It's like they sat down and said "let's copy Dependency Injection from Spring, templates from Django, and routing from Ruby. Then we'll offer a choice between two different ORMs that are both broken, because ORMs are 'modern.' Finally, we'll slap the label 'Enterprise' on it so that people will finally take PHP seriously."

But don't take my word for it; Rasmus Lerdorf is known for saying that all PHP frameworks suck: https://www.phpclasses.org/blog/post/226-4-Reasons-Why-All-P...


By 'design patterns' I assume we're talking about following SOLID principles, which even when copied from other languages involves dependency injection, factory methods and singletons.

I agree that on some of these are a burden on PHP (mostly PSR-7), but as you mentioned that's the direction most languages/frameworks are following nowadays. It isn't necessarily good but frameworks and design patterns aren't about saving execution time, but saving development time and increasing maintainability by adhering to easy(ish) to follow concepts

On Rasmus, having met him once I'm not at all surprised that he thinks they all suck. I would disagree because I do like the Slim 3 framework although I wish it hadn't been an early adopter of PSR-7 because it feels like a heavy-handed solution to an infrequent problem. But I'm not sure we have good alternatives here. We can go back to spaghetti code or write a better framework


Here’s two alternatives:

1. Don't write object oriented PHP. Despite the promise it showed early on, history now tells us that "Object oriented" is not a guarantee for quality, nor does it prevent spaghetti code.

2. Write framework-compliant object oriented code in another language/runtime more suited to executing it (basically anything that doesn't try to live directly inside the Apache request/response cycle).

You might not consider them "good" alternatives, but I think they are the choices a lot of people eventually end up choosing between.

I generally agree that frameworks are good to use for saving developement time, but execution time matters. The performance penalty paid for some of these frameworks on PHP compared to the two alternatives above is large enough to negate the benefit for all but trivial cases.


That's fair. I've been stuck dealing with CodeIgniter people for the last year, and that's a shitshow and a half. It's likely colouring my perceptions, especially coming from the Rails community. God, I miss Rspec.


I came from Rails into WordPress and the stink that I've picked up from having this on my resume has definitely hurt my career prospects...not like I'd rather be working on Rails right now anyway.

I've resigned myself to digging deeper into Elixir and Erlang and using my Ruby background to get the next gig.

I interviewed with some folks recently who are primarily CodeIgniter and transitioning to Laravel -- wasn't a fun interview. They just couldn't see the benefits of a functional style anywhere in PHP.


Surely it hasn't hurt your career, PHP is still the most common language of the web. It's never a bad thing to have PHP experience on your resume imo.


I guess. The last year and a half I've done nothing but heavy WordPress backend and plugin development and large ETL projects in Ruby. Right now I'm working on a Jekyll with WordPress-as-CMS backend architecture for a high-traffic site.

I think I'm building really cool stuff but when I talk to the kinds of companies I want to work for here in NY, most people seem to just tune me out the second I mention WordPress.

I'd have an easier time if I spent a lot more time working with Node and React, but for the work that I do here those are the wrong tools.


That's likely true for any language old enough to have supported the old CGI model. Inertia...


Personally, I think a lot of the perception is just that PHP appeals to a broad audience, so there's a lot of unskilled people producing code.

All the more reason for the language to be opinionated and force developers do things securely. The path of least resistance should be to write good code; let developers abuse the language if they really want to, but make them have to work hard to do that.


Sure. That's basically "PHP is a terrible language for beginners working on their own", which I don't disagree with. On the other hand, for example, SQL injection isn't any more or less likely with PHP vs say Python, Perl, or Ruby. All four encourage you to use prepared statements, placeholders, etc. But all four allow random strings too.


> That's basically "PHP is a terrible language for beginners working on their own", which I don't disagree with.

I think the problem is that it's a very easy language for getting your feet wet and learning the basics. "Just mix this for loop in with your HTML! Stick it in along side your static .html files! Dynamic content!" Plus there are literally decades of documentation and examples online. The trouble IMO is that up until PHP 7, very little original cruft was ever actually removed from the language. mysql_escape_string was deprecated in v4.3 (2002!!) and still exists on the default v5.X package installs available for Debian, CentOS, etc. It's really hard even for experienced programmers coming from other languages to know what's actually currently the best way of solving a problem. You have to be a well-versed expert to know all the quirks/pitfalls and how to handle them properly.


Originally php and the MySQL/postgresql libraries had no way to use placeholders so you had to use patterns that made it pretty hard to avoid sql injection. Which is why they had kludges like magic escaping, of course.


Its a well known fact PHP powers a ridiculous number of very high traffic sites. It's also a well known fact that HN favourites like ruby struggle.

PHP is extremely easy to set up and use. Ruby is a quagmire of dependencies and build environments.

This makes php bashing on HN tedious and disconnected from reality. There is a clear preference here for tech that pays more and but let's not try to pass it off as a technical preference.


Agreed, I've pentested php apps and some are very hardened and difficult to breach and I've tested Python django apps where I completely compromised the server. Language has only a weak correlation to security for web applications.


Nice to see this work being shared with others.


Is there an analysis out there which evaluate some of the largest PGP projects regarding these cryptographically best practices?


I'm assuming that's a typo (s/PGP/PHP/).

There isn't such an analysis yet, but I intend to do one in the near future. We have a similar analysis for out-of-box security features of popular open source CMS: https://paragonie.com/blog/2016/08/on-insecurity-popular-ope...

Our security page has some of the audits we've done (at least, the ones we were permitted to publish) as well as our security advisories. https://paragonie.com/security

I'm pretty active in the PHP community and get looped into a lot of pull request discussions (e.g. https://github.com/facebook/php-graph-sdk/pull/552#issuecomm... for Facebook's SDK), but it's possible I've missed a few.


I'm curious why you submit CVEs for development repositories of code that is not supposed to be run in production?

SMF 2.1 for instance is purely development releases that are _not_ supposed to be used in production.

http://www.simplemachines.org/community/index.php?topic=5354...

> As always, keep in mind that Beta Releases are NOT recommended for production sites.

It is just the first time I've ever seen someone create a CVE for what is essentially a do-not-run-this-in-production code branch for an open source project. I'm used to people waiting until at least a Release Candidate version before doing that.


In the case of SMF, the same vulnerabilities were present in the production versions.

Do you have any other instances you'd like to inquire about?


> In the case of SMF, the same vulnerabilities were present in the production versions.

I'm just curious which production version you are talking about now since 2.1.X has 0 of those?

It doesn't really impact me one way or the other, so feel free to ignore me if you prefer. Its just odd.


The vulnerability is also present in the v2.0.x branch.

The development 2.1.x branch (which is what was on Github) had the vulnerability, and that's where I reported it, but it's not only in the new code.

I think maybe you're confused somewhere?




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

Search: