Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

PHP started out as a language you could embed into otherwise static HTML via SGML processing instructions. While useful, the problem was (and still is) that embedded PHP templating operates at the string level and has absolutely no concept of HTML-awareness so can't escape the strings it injects into HTML - it's trivially easy to build a PHP app taking user input where the user sends malicious <script> tags and PHP placing it happily into generated HTML (eg. XSS attacks). PHP apps typically also build up dynamic SQL from user input by string concatenation, which has resulted in uncountable SQL injection attacks. PHP apps and frameworks like WordPress and Drupal initially have worked around these limitations by using ad-hoc measures, then grew into meta site template engines and generators themselves, resulting in code bases without much architectural oversight. These dangerous properties, and PHP's really bad standard library, in combination with PHP being used as a beginner language for web sites, have resulted in PHP's bad reputation. Since experienced developers have avoided it, PHP also has a bad presence at StackOverflow, which contains thousands of low quality answers answers to PHP questions.

On the plus side, PHP really owns managed hosting. You can install WP etc. via "panels" even without any admin experience and go from there by installing a mess of "plugins" and "themes" (which, due to lack of modularity, can do all kind of things to your site).

Node.js generally requires your own VM (there is no managed hosting) and due to it being run in a single process (or process cluster) generally requires that you know what you're doing so that a single error doesn't bring down your whole site. Its attractiveness comes from the fact that you can use JavaScript both server- and client-side (unlike PHP which runs server-side only). While Node.js has the edge in web apps, the options for content-driven sites are limited on Node.js; there's nothing like WP or Drupal for Node.js, and some say Node.js also lacks a canonical framework for rapid creation of database-driven web apps such as Rails or Django.



> While useful, the problem was (and still is) that embedded PHP templating operates at the string level and has absolutely no concept of HTML-awareness so can't escape the strings it injects into HTML - it's trivially easy to build a PHP app taking user input where the user sends malicious <script> tags and PHP placing it happily into generated HTML (eg. XSS attacks).

> PHP apps typically also build up dynamic SQL from user input by string concatenation, which has resulted in uncountable SQL injection attacks.

You can make these beginner mistakes in any language that outputs HTML to the browser, and accepts user input via the browser.

I'm not specifically defending PHP here, but I hope you're not implying that these problems don't exist in Ruby, Python, Java or even Node for that matter...

The issues you are describing are unsafe coding practices and have nothing specifically to do with how PHP works, and it's "trivially easy" to make those mistakes in almost all web programming languages.

It's also not true that PHP "can't escape the strings it injects into HTML". There are standard library functions to do this (and have been for probably 10+ years, since the late PHP 4 days), as well as many well-tested community packages to do this at the framework or application level.

Also your explanation of "plugins" and "themes" is a concept tied to applications such as Wordpress, Joomla, and other CMS products (and again are not concepts specific to PHP).

It's certainly true that PHP's low barrier to entry has led to many badly coded websites getting onto the Internet, but I think it's ignorant to claim that PHP can't be used correctly and safely to develop web applications, or that most of the problems you describe are not easily avoidable.

All languages and frameworks have their pros and cons, and their caveats, but it helps no one when people spread FUD and outdated (or straight-up false) facts about web development.

Whether you code in it or not, you should probably refresh your knowledge of the PHP language and ecosystem if you're going to make public statements about how it works and what it can and can't do.


Of course you can write safe code in PHP, it is a complete general purpose programming language. But just like one can blame C's design and standard library for many security bugs I also think it is fair to blame PHP's standard library and design.

For example PHP's PDO library makes it less convenient to supply parameters to a query the safe way than it is to do it the unsafe way. This is not necessary as can be seen from the excellent Ruby library called Sequel where it is just as easy to do things the safe way.

Another example is PHP itself being a template language, but which lack of automatic escaping makes it very dangerous to use. Since just one missing escape call in the wrong place can fuck up your day. To be fair PHP is not the only one who has fucked up here. This is also an issue with Ruby's ERB templates in the standard library, but fortunately Rails has added automatic escaping to its ERB templates.

One important thing about designing safe software is to make it easy for the end users to do things the right way, and here I think PHP has done a pretty poor job.


I would say it's unfair to compare a library to the basic PDO. If you want to compare apples to apples, try looking at Sequel versus Doctrine or some other third party SQL library.

Just like any other template language (thinking of something like ColdFusion or ASP), of course one unescaped variable is going to be a headache. But you don't have to use it that way, and probably shouldn't. While PHP started as a template language, it has clearly moved past that.


I do not think it is an unfair comparison since Sequel has both basic parts on the same level as PDO, and then implements the more advanced features on top of these basic parts. The basic parts of Sequel has superior usability and safety to PDO.

Sequel's right way:

    user = db['SELECT name FROM users WHERE id = ?', id].first
Sequel's wrong way:

    user = db["SELECT name FROM users WHERE id = #{id}"].first
PDO's right way:

    $stmt = $db->prepare('SELECT name FROM users WHERE id = ?');
    $stmt->execute([$id]);
    $user = $stmt->fecth();
PDO's wrong way:

    $user = $db->query("SELECT name FROM users WHERE id = $id")->fetch();
As you can see PDO is optimized for doing things easily the unsafe way while Sequel has the safe way as the normal way of running queries which is just as easy to use as the unsafe way.

> Just like any other template language (thinking of something like ColdFusion or ASP), of course one unescaped variable is going to be a headache.

That is simply not true. Look at Twig which by default escapes everything automatically, or Rails's patched ERB which keeps track of escaped an unescaped strings based on data types and makes sure everything is automatically escaped in the end. In those template languages you need the explicitly do something unsafe to get an unescaped value. While in PHP you need to audit all places where echo can be called directly or indirectly.


Okay, so instead of Doctrine, look at another library that has the basic parts and then the advanced parts. Here is one from a different library that is safe and "easy"

    $user = $db->find('user', 'first_name = ?', ['Name']);
> As you can see PDO is optimized for doing things easily the unsafe way while Sequel has the safe way as the normal way of running queries which is just as easy to use as the unsafe way.

PDO isn't "optimized" to do them the wrong way or the right way. Yes, it's less code to do it the wrong way, but that isn't a true definition of easier.

As for the escaping, I would expect Twig to escape things, it's want it's meant for (and the reason you use it instead of just vanilla PHP). And Rails is a subset of Ruby correct? So not a true comparison again.


Compare Sequel to EasyDB then: https://github.com/paragonie/easydb


Sure, I know there are good libraries for PHP, I mentioned Twig for example, but my issue is that the standard library of PHP is shitty and contains traps for beginners.


Honest question, is Sequel a standard library for Ruby? I assumed it was something you had to install after you installed Ruby.


Most languages let you cut corners and code in a sloppy way. This is not limited to PHP.

I think anyone can show anecdotes to support "coding in [language you don't like] is bad".

Replace "unsafe" with "non-performant" and go back to early Rails days and you'll have plenty of examples where naive framework implementation led to programmers shooting themselves in the foot with the "easy way" in a different context..

Like I said, all languages and frameworks have their caveats and learning to code properly is the developer's job, and the "right way" or "best way" is often a work in progress that evolves as the community develops best practices..


> Most languages let you cut corners and code in a sloppy way. This is not limited to PHP.

Completely true, but for years PHP made it extraordinarily easy to shoot yourself in the foot right out of the box. register_globals for example...

http://php.net/manual/en/security.globals.php


Deprecated 9 years ago.


It's not what you can do, it's how hard it is.

Just try pulling data from a database and inserting it into a page on a way that is vulnerable to XSS in Django, Jinja, or Rails. You obviously can do it, but I bet you'll need to spend half an hour reading the documentation before you succeed.

The same happens for SQL injection, and session management issues, and a huge amount of other problems.


The fault in your argumentation is comparing a language (PHP) to a framework (Django, Jinja, Rails).

Your argument is valid too for any PHP framework, it's hard to do XSS in laravel, symfony or zend framework.


PHP is a web framework. It's just one that requires another framework on top to mitigate its shortcomings.


I use PHP quite a bit outside of the web.

I think tpetry was pointing out the difference between a language and a framework built on that language.

(Replace language with whatever you think it is, it's still a subset just like Ruby on Rails is a subset of Ruby)


Sure you could separate PHP the language from PHP the processing instruction and PHP the standard lib. But PHP calls itself a "hypertext preprocessor" (it's in the name) and PHP's own intro (literally on page 1, sentence 1, cf. [1]) advertises web templating as its distinguishing feature. So I think it's fair to compare PHP against other HTML generators.

[1]: http://php.net/manual/en/intro-whatis.php


So, regarding the parent, I was pointing to PHP being more of a language and less of a "web framework" which I don't believe you address at all. As for web templating and such

> PHP (recursive acronym for PHP: Hypertext Preprocessor) is a widely-used open source general-purpose scripting language that is especially suited for web development and can be embedded into HTML.

I would focus on the core statement of the sentence which is "is a widely-used open source general-purpose scripting language". Comparing PHP to other HTML generators (re re re? parent: Django, Jinja, Rails) leaves out the entire concept of "general-purpose scripting language" and only focuses on "embedded into HTML" which while a main feature isn't the whole of it.


And I'm pointing out that treating PHP as a framework is not a "flaw in argumentation". The default installation of PHP gives you a setup that parses HTTP requests and returns HTTP responses, and provides a bunch of web-centric functionality in between. ie. it's a web framework, albeit not a very good one.


> The default installation of PHP gives you a setup that parses HTTP requests and returns HTTP responses

Correct me if I am wrong, but so does Node, Ruby, Python, etc...

Sure it was built for the web, in simpler times, but everything has to start somewhere. Now days, PHP is a completely different beast.

> Just not a very good one.

An opinion if fine, but it seems like you are deriving this opinion from old experiences (or maybe the old PHP hate bandwagon)


> Correct me if I am wrong, but so does Node, Ruby, Python, etc.

I think Node is also a framework, although there seems to be some controversy about this[1]. Ruby and Python give you standard libraries from which you can build a web server or templating engine or whatever, but it would be weird to say that made them Web Frameworks. Maybe things have changed, but last I knew PHP had a command line switch that tells it to not act like a web framework, because that is its default mode of operation. But you're right that it's been a few years.

I don't think I'm jumping on a hate bandwagon, but I am succumbing to someone-is-wrong-on-the-internet syndrome, which I know to be a mistake.

Although I can't resist asking - are you saying PHP is a good web framework? How does that fit with the idea that PHP is not a web framework?

[1] https://softwareengineering.stackexchange.com/questions/2991...


> I think Node is also a framework

I think we have different definitions of frameworks. So no point in arguing over that.

> Maybe things have changed, but last I knew PHP had a command line switch that tells it to not act like a web framework

I honestly don't even know about a command line switch. I just write my script and execute it with the CLI (php test.php)

> I am succumbing to someone-is-wrong-on-the-internet syndrome

Please tell me this has a name

> Although I can't resist asking - are you saying PHP is a good web framework? How does that fit with the idea that PHP is not a web framework?

Not sure you exact intent, but as far as PHP being a good language to write a web application in, sure, it can be. IMO, it depends on the application and use of the application.


You would have a point the frameworks you provided had that kind of protection by default (or if you could at least enable it project-wide), and if PHP development were mostly done on them, instead of wordpress and drupal.

Besides, there's more to security than SQL injections and XSS. The PHP tooling is overflowing with bad practices.


Take a look again. Each of those Frameworks is using a template engine which is escaping any ouput by default. If you do not need escaping, you have to opt-out for single outputs.


Reading through it, my comment came about too much as a rant against PHP, though I actually like parts of the PHP community for their sense of practicality.

I know there are libraries for HTML escaping, but I stand behind my statement that PHP's lack of HTML escaping is a fatal and unforgivable (almost criminal) design flaw when PHP's original use case, and distinguished feature vs. other general-purpose languages is dynamic HTML templating. In my opinion, PHP has gone the "get something quick out there and fix it later to become the dominant web runtime" route (which kind of worked), but without doing the actual hard work, and as such deserves to be called out.


You're calling out problems that are common to all programming languages on the web, and I think you're just focused on PHP because it was one of the first languages to run into those problems (and to solve them as well - HTML escaping functions are part of PHP's core, it's not a library) due to it's early widespread popularity and adoption.

Trailblazers often bear the brunt of learning through trial and error, and later adopters benefit from all those lessons learned. This includes the PHP language and ecosystem of today, that looks nothing like what you describe.

Also: show me a popular web programming language that prevents the problems you called out (at the language level, not the framework level). You can output unescaped input, or create SQL injections, in any language if you don't know what you're doing, or if you're using the wrong tools.

Again if you want to keep speaking on the topic, I encourage you to refresh your knowledge on the PHP programming language (and probably also on web development in general if you think other languages don't also have the same pitfalls).

Your concerns and opinions are literally 10+ years out of date.


> show me a popular web programming language that prevents the problems you called out (at the language level, not the framework level).

Golang? https://golang.org/pkg/text/template/


PHP made it way too simple to go from a basic installation -> serving web pages, just using it's standard library. You're right -- that was it's intended use-case and while it made for a dead-easy user experience, it also planted lots of traps that users fell into in droves.

Where languages like Ruby had Rails and Python had Django, PHP was able to do things quickly without having a framework on top of it. That, coupled with clear design flaws and a standard library that lacked, well, standardization, made it an easy and deserving target for criticism. PHP was also slow to adopt objects, namespaces, package management and other things developers came to expect.


I agree! 6 years ago when I started with web, as a total newbie, decision was to use Ruby on Rails. I gave up after day or two, I didn't understand how to start with this thing. And I was pissed of. Then I wrote few lines and save it as .php, upload to hosting which I already had, and things worked. I'm still using php to this day.




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

Search: