Friday, May 25, 2012

PHP tutorial that is security-, accuracy- and maintainability-conscious?


Colleagues often ask me: “bobince”, they say*, “I want to learn PHP, but I know you're always ranting on about poor code which is full of errors and security holes. That's why I normally don't like talking to you really. But, I'm looking to learn PHP now and I'd like to be able to write good code. Where's a tutorial that will teach me how to do it properly, so my site won't get all hacked up and you won't get all cross at me?”



“Hmm...” I reply, then point and call out “Look over there! A lovely pony!”, and run away.



I do keep looking for a PHP tutorial that isn't awful, full of disastrously terrible practices, but I've yet to find anything I can recommend.



Dear reader, can you perchance help me out? Unlike previous questions, I'm not after a security-specific tutorial for people who can already code in PHP; I'm looking for a good tutorial (sites or books) for those new to the language, that happens to be solid on security and writing readable code. I want the reader to be able to learn PHP properly from the start, not to have to say “well you can learn it here ... but then afterwards you'll need to go to this other tutorial to find out about the bad habits and fundamental misunderstandings you've just picked up”.



(*: they don't say that. It is not my real name.)





I want a tutorial that:





  1. Uses HTML-escaping consistently from the start. The very first “Hello, your_inputted_name!” example should be using htmlspecialchars() correctly. This should not be introduced as an afterthought in a separate security chapter. There should be no HTML-injection hole anywhere in the given example code.





  2. Either uses SQL-escaping consistently from the start, or parameterised queries. If SQL-escaping is used it should be correct escaping such as mysql_real_escape_string() if the database is MySQL. I do not want to see addslashes() . There should be no SQL-injection hole anywhere in the given example code.





  3. More generally, the tutorial should understand the problems to do with putting a string inside another string, and treat escaping as a matter of correctness, not merely of security. That is to say there is no reason a user called N'gwale O'Reilly should be prevented from having an apostrophe in their name, or from talking about the HTML <script> tag in their message like what I'm doing now; they merely just need the right form of encoding when they're output.



    The tutorial should explain that when a string goes into a new context it needs an encoding process appropriate for that context, like htmlspecialchars() in HTML output; it should not regard less-than symbols as ‘evil’ and attempt to ‘sanitise’ them away. I don't want to see strip_tags . I absolutely don't want to see misguided ‘security’ measures like looping over the $_GET array removing punctuation characters, or blanket-applying haphazard output-stage escaping to an input stage.



    There is so much bad code and bad examples like this out there, even in learning materials that are supposed to be explicitly about security. As questions on SO have proved it is difficult to fix people's miunderstanding of how and when string escaping needs to happen once they've learned a quick hack ‘solution’ from some misconceived ‘PHP Security’ site or book.





  4. I don't want to see eval() . I don't want to see system() . Nothing good comes of having these in a tutorial!





  5. There should be proper separation of active logic and page markup. I don't mean they have to be kept religiously in different files or using a specialised templating language, but I do at least want the actions up at the top and the page down at the bottom with only display logic inside it. I don't want to see an echo or print hidden inside the guts of some program logic.





  6. Actually I don't really want to see echo / print used at all except as the only thing in an output block. PHP is a templating language, there is no reason to go about creating complex strings of HTML then echoing them. This only encourages the use of unescaped "<p>$var</p>" -style interpolation, and makes it difficult to follow. All markup should be literal markup in the PHP file, not hidden within a string.





  7. Proper use of indentation is essential, both in the HTML tag hierarchy and in the PHP code. Ideally there should be a single hierarchy, using structures like <?php if () { ?> ... <?php } ?> (or the alternative syntax) as if they were well-formed XML. The HTML should itself be in ‘well-formed’ style even if it is not actually XHTML.





  8. Some mention of XSRF would be a nice bonus.







In short, I want a tutorial that teaches one to code something like [with predefined output-escaping function shortcuts]:




<?php
function m(str) { return "'".mysql_real_escape_string(str)."'"; }
function h(str) { echo htmlspecialchars(str); }
function u(str) { echo rawurlencode(str); }

$result= mysql_query('SELECT * FROM items WHERE category='.m($_POST['category']));
?>
<table>
<?php while($row= mysql_fetch_assoc($result)) { ?>
<tr id="row-<?php h($row['id']); ?>">
<td>
<?php h($row['title']); ?>
</td>
<td class="thing">
<a href="/view.php?id=<?php u($row['id']); ?>">View</a>
</td>
</tr>
<?php } ?>
</table>



and not like:




<?php $category=$_POST["category"];
$result = mysql_query("SELECT * FROM items WHERE category=$category");
echo "<table>";
while($row=mysql_fetch_assoc($result))
{$html="<TR id=row{$row[id]}><td class=\"thing\">".$row[title];
$html.="</td><td><a href=\"/view.php?id={$row[id]}\">View</a></td></TR>";
print $html; }
print "</table>"; ?>



which is the sort of Other People's Code I'm fed up of fixing. Is there anything out there I can recommend, in the hope that when I end up looking after the code it doesn't look like this kind of mess?



I know I'm being too prescriptive and everything, but is there anything even close? So far I've yet to find a tutorial without SQL-injection in it, which is just so depressing.


Source: Tips4all

10 comments:

  1. Chris Shiflett is author of Essential PHP Security book. This is really good book on security. Check following of his blog links on various topics.


    Cross site request forgeries. (XSRF) http://shiflett.org/articles/cross-site-request-forgeries
    Cross Site scripting http://shiflett.org/articles/cross-site-scripting
    SQL Injection http://shiflett.org/articles/sql-injection
    His other articles, including ones on sessions, can be found here. http://shiflett.org/articles
    Another good article on SQL injection is here. http://simon.net.nz/articles/protecting-mysql-sql-injection-attacks-using-php/
    Following article discusses quotes, htmlentities() and htmlspecialchars() in detail. http://www.nyphp.org/PHundamentals/5_Storing-Data-Submitted-Form-Displaying-Database

    ReplyDelete
  2. A complete tutorial for beginners?

    I saw such a thing in the movie Matrix once; they were able to load a complete chopper piloting program into Trinity's brain in seconds. I think what you want is essentially the same as this. This clashes with the idea "learn a language in 10 years" without which being a proficient coder is hardly possible.

    I thought of such an idea once too. But when I started to think about what should I put there in order to make it decent (to me), my brain started to bubble, and I was not even able to plan the first chapter sanely.

    Then I realized that in order to satisfy my decency rules, I simply had to put everything I had in there, and with the same organization as in my brain. Even after that, it would be only good as what "good" meant to me at that time. Such a book would be as thick as an encyclopedia and would never be finished, since the tech advances faster than any human being can write.

    After that, I saw the value in studentship, master-apprentice system, and devoting time to learning and doing, and especially the virtually unchanged nature of this, through millennia.

    While there are many improvements that can be made to books and tutorials, not everything can be put in them. Because as Joel Spolsky pointed out, understanding many basic ingredients of coding and computing requires the essential knowledge of many layers and lower levels of the system like: cpu's, memory, packets, HTTP, etc.

    Of course, you can go write directly the most secure and nice version of the code without explaining what does the question mark in the $db->query('SELECT etc FROM tbl WHERE id = ?'); ... mean. But who would read (and even use) it then?

    Hence comes the idea of short, well defined and very specific articles and blog posts, written by people you feel far superior than you. The "tutorial" you dream about is made of years of learning the basics and even more years of such tiny bits. But I don't know whether it is writable.

    ReplyDelete
  3. The Writing Secure PHP Series by Added Bytes seems like a good place to start on security.

    EDIT: I just came across OWASP Ruby on Rails Security Guide, I know it's RoR but there's plenty of decent stuff in there that also applies to PHP. There is also the OWASP PHP Top 5 article.

    ReplyDelete
  4. There is also php|architect's Guide to PHP Security - it provides broad coverage of PHP-related security topics.

    ReplyDelete
  5. I was going to suggest Learning PHP, MySQL, and JavaScript because it is the book I used to learn the language.

    It is a very complete text that delves deep into all 3 subjects in a very readable fashion, but I think that the author's methods of avoiding SQL-injection and the like are somewhat primitive (they leave a lot to be desired, but provide a sturdy foundation).

    Thus, I have to agree with everyone else here and suggest that you spend a few days/weeks/months putting together a tutorial. I acknowledge your proclamation that you are not an expert on the subject, but the very details of your question imply that you should take on the chore yourself. Perhaps you could develop a wiki-like tutorial that you could write the bulk of and then encourage people to amend and contribute to it.

    ReplyDelete
  6. PHP 5 Objects, Patterns, and Practice is the best book I have read on PHP so far. He really does a great job of going over all aspects of good PHP practice.

    I can not tell you how well his security is in this book, but I bet it is good enough for a beginner to get a good foundation without writing crap code.

    I honestly hate seeing PHP and HTML blocks mixed in with each other. But I also hate seeing echo/prints everywhere for the HTML. Instead I created a PHP HTML class which I use to validate all of my HTML and ensure that the programmer does not write bad HTML code. This also gives me a way to update my HTML as new DOCTYPES come out, and I can escape everything from that class. By using this HTML class I also have all PHP on a page without the PHP/HTML blocks mixed in together.

    ReplyDelete
  7. About a year ago I went through Kevin Skoglunds "PHP with MySQL Essential Training" which was ok but I expect given that it was aimed at complete and utter beginners who would probably struggle with the concepts discussed here it's not what you need. I'm currently working through (slowly ...) his second series - "PHP with MySQL Beyond the Basics". So far I don't think I've seen any mention of html escaping but the database class he worked through definitely had escaping in there from day dot.

    Again, gotta bear in mind that I am a beginner - I just thought you might want to review it a bit to see what's been taught so far.

    I've been self teaching myself some Git whilst working through this so you can see the source of the project (currently at Chapter 7) here: http://github.com/Mithadriel/LyndaPHP---ImageGallery

    Otherwise - good luck in finding what sounds to me like a Holy Grail :)

    ReplyDelete
  8. I think you need books not tutorials. PHP is a complex programming language and no tutorial no matter how complex will give you all you want.

    The best tutorial for PHP is the PHP documentation itself. Is complete, with a lot of examples and with interesting user contributions.

    ReplyDelete
  9. What about PHPRO tutorials? I've always liked that website and I learned a lot there. There's also an introduction for PHP/MySQL tutorial:


    http://www.phpro.org/tutorials/Introduction-to-PHP-and-MySQL.html


    There are also couple good articles about security, for instance:


    http://www.phpro.org/tutorials/PHP-Security.html
    http://www.phpro.org/tutorials/Validating-User-Input.html

    ReplyDelete
  10. Well i think Zend Developer Zone is a good Place to Start.

    Here is a Tutorial:

    PHP For the Absolute Beginner
    http://devzone.zend.com/node/view/id/627

    ReplyDelete