views:

1305

answers:

9

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 [assuming predefined output-escaping function shortcuts]:

<?php
    $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.

+4  A: 

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

Alix Axel
Yeah, this ain't bad as far as it good (it's obviously not complete yet), but it's not really somewhere a beginner can start. It's correcting common errors; I want a tutorial for not-yet-PHP-coders that avoids the errors from the start.
bobince
@bobince: I think it'll be hard finding only **one** tutorial that covers all of those topics well. Seriously, maybe you should write one.
Alix Axel
+43  A: 

Hi,

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.

  1. Cross site request forgeries. (XSRF) http://shiflett.org/articles/cross-site-request-forgeries
  2. Cross Site scripting http://shiflett.org/articles/cross-site-scripting
  3. SQL Injection http://shiflett.org/articles/sql-injection
  4. His other articles, including ones on sessions, can be found here. http://shiflett.org/articles
  5. Another good article on SQL injection is here. http://simon.net.nz/articles/protecting-mysql-sql-injection-attacks-using-php/
  6. Following article discusses quotes, htmlentities() and htmlspecialchars() in detail. http://www.nyphp.org/PHundamentals/5_Storing-Data-Submitted-Form-Displaying-Database
Yogesh
Someone up-vote him please, I'm out of votes for today.
Alix Axel
Thank you Daniel and Alix. I am new to this site and learning how this whole process works. Thanks for putting all links in one place. Shall I go ahead and delete my other answers links for brevity? Thanks and Regards.
Yogesh
@Yogesh: No problem. Yes, you should. =) Otherwise a mod will.
Alix Axel
@Alix: ok. Thats helpful. I will be more careful next time around. Thanks again.
Yogesh
@Alix: Done, upvoted. But now I need somebody who'll vote for me! :)
Pekka
@Pekka: My request had a reason (see http://stackoverflow.com/revisions/2df7081c-230b-4de1-b5d1-e2ecf864774c/view-source) xD **you can stop voting now**, it's enough. :P
Alix Axel
Yeah, this seems to be decent stuff; however it is still fixing security problems up after the fact, for people who've already learned PHP but learned bad habits. I'm especially looking for a PHP tutorial that doesn't make those mistakes in the first place. @Pekka: just give me a PHP tutorial which doesn't include HTML or SQL injections and I'll happily vote for you! :-)
bobince
@bobince: I meant it differently, I was helping Alix out because he had run out of votes, but I would like to upvote this answer as well. :)
Pekka
+1  A: 

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.

Elzo Valugi
Sure, books are good. Sadly I've reviewed several PHP books including some that are aimed specifically at “security” and they've always been full of obvious holes and hopeless approaches to security, even the ones from the normally-impeccable publishers. So if you can recommend a particular good book that's very welcome! As for the PHP docs, I agree they're mostly good, but the amount of tutorial content in them is very small, not something I can easily throw at new users.
bobince
+1  A: 

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

streetparade
Unfortunately, this tutorial is an complete disaster, exhibiting pretty much every negative point I listed. SQL injection, HTML injection in absolutely every case, mixing echoed output into the middle of actions, inconsistent indentation. It has the footnote-style security chapter I was complaining about, except even then the security chapter addresses no real security issues and has full-on SQL-injection exploits. Woeful.
bobince
+3  A: 

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

Grant Palin
+2  A: 

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 :)

foxed
Should note that these are paid-for video tutorials available from Lynda.com
foxed
Are there any free materials (eg. accompanying code samples) anywhere I can have a look at? Video tutorials might be suitable though I don't so much fancy watching through them myself :-)
bobince
There is an accompanying zip which contains the Exercise Files - effectively the code he's teaching through at each step of each Chapter. Happy to send it over for you to have a browse through.
foxed
@foxed: Yes, if you can chuck a link to some examples to the address in my profile that'd be great. Thanks!
bobince
+1  A: 

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:

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

Richard Knop
It's a case of lots of little fragmented tutorials here though, that don't build on each other, which is not easy for a beginner to navigate through. The MySQL tutorial is full of the kind of HTML-injection errors mentioned in the Security tutorial (though that tutorial's approach of using `filter_var` is inadvisable); they'd be vulnerabilities if any user-input data was present. The Validation tutorial makes the exact same mistake warned about at the start of the Security tutorial!
bobince
Yes but they mention SQL injections and what to do against them at the end of article!
Richard Knop
+1  A: 

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.

samandmoore
+1  A: 

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.

Metropolis
Your practice sounds very much like the late Douglas Clifton's [Markup Toolkit](http://loadaveragezero.com/vnav/labs/PHP/markup.php#addcont)
Marcel Korpel
Kind of the same concept, but I am using classes for my markup, and I never use global variables (EVER). Plus mine is much more robust.
Metropolis