<?xml version="1.0" encoding="UTF-8" ?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
			<title>Tagged with "tips"</title>
			<link>http://www.addedbytes.com/feeds/tag-feed/</link>
			<description></description>
			<language>en</language>
			<copyright>Web Development in Brighton - Added Bytes 2006</copyright>
			<ttl>120</ttl>
			<item>
				<title>Basic Linux Command Line Tips</title>
				<link>http://www.addedbytes.com/blog/basic-linux-command-line-tips/</link>
				<description><![CDATA[ Learning your way around the command line is essential if you are developing with PHP (or Python, or a myriad of other languages most at home on Linux) and interacting with your server(s) with anything other than FTP and basic control panels. Here are some tips and tricks I've found useful. <div style="margin: 0 0 1.5em 0; padding: 20px; background: #333; color: #fff; border-radius: 3px;">
    <p style="margin: 0; float: left; width: 48%;"><a class="imagelink" href="http://www.cheatography.com/davechild/cheat-sheets/linux-command-line/"><img src="http://www.cheatography.com/images/cheatography_logo.png" alt="Cheatography"></a><br>A companion Linux Command Line Cheat Sheet is available for free at <a style="color: #fff; border-color: #fff;" href="http://www.cheatography.com/davechild/cheat-sheets/linux-command-line/">Cheatography</a>!</p>
    <ul style="margin: 0; float: right; width: 38%; border-radius: 3px;" class="cheat_sheet_downloads"><li>&bull; <a href="http://www.cheatography.com/davechild/cheat-sheets/linux-command-line/">HTML (online version)</a></li><li>&bull; <a href="http://www.cheatography.com/davechild/cheat-sheets/linux-command-line/pdf/">PDF</a></li></ul>
    <div class="clear"></div>
</div>

<p>The last year has seen me take on the management of a few Linux servers, and ditch my Windows PCs for Linux too. There's been a lot to learn, and it's not all been fun - sometimes it has been intensely frustrating. However, overall it has been extremely positive. On the rare occasions I have to return to Windows now, I wonder how I ever coped without grep, stdin, stdout, pipes, multiple workspaces ... the list is long.</p>

<p>I'm getting to the stage where I'm comfortable on the command line. I have a vast amount yet to learn, but I can do most of the things I need to do now without looking up commands or file locations. I've also started to explore more tools, and think it would be useful to start to share some of the things I'm finding helpful.</p>

<p>Apologies to those of you with strong command-fu who were expecting cutting edge tricks - this may be too basic for you. I've been using largely Ubuntu, Ubuntu server and Centos 5, though most of these commands should be available (or easily installable) on most modern distros.</p>

<p>Commands to be executed on the command line are prefixed with $. Commands without $ are to be run within applications.</p>

<p>Corrections, improvements and suggestions are all very welcome in the comments below!</p>

<h3>screen</h3>

<p><a href="http://www.linux.com/learn/tutorials/285795-taking-command-of-the-terminal-with-gnu-screen-">screen</a> is a command-line tool to allow multiplexing of terminal windows. In layman's terms, it means you can have multiple terminal "windows" open at once and switch between them. Most importantly, screen allows you to resume a session later, so if you are disconnected from a remote machine, no problem - you reconnect, resume your screen session, and it's like nothing happened. Perfect.</p>

<ul><li><em>$ screen</em> - start a screen session.</li>
<li><em>$ screen -r</em> - resume a screen session.</li>
<li><em>$ screen -list</em> - show your current screen sessions.</li>
<li><em>CTRL-A</em> - This key activates commands for screen. Once in screen, you'll need to use this to tell screen to do anything.</li>
<li><em>CTRL-A c</em> - create a new instance of terminal.</li>
<li><em>CTRL-A n</em> - go to the next instance of terminal.</li>
<li><em>CTRL-A p</em> - go to the previous instance of terminal.</li>
<li><em>CTRL-A "</em> - show current instances of terminals.</li>
<li><em>CTRL-A A</em> (the case matters) - rename the current instance of terminal.</li></ul>

<h3>man</h3>

<p>I'm including this here not because it's a particularly obscure trick, but because it is so useful and I use it so often. It is invaluable. Simple type "man" then a command to see information about that command.</p>

<ul><li><em>$ man grep</em> - Show information about the "grep" command.</li></ul>

<h3>tail</h3>

<p>Another command which along with its partner <em>head</em> is well known and widely used, but that I find invaluable. tail shows the last 10 lines of any file (and head the first 10). But where it gets good is with the -f argument, which tells tail to "follow" the file. It will then dutifully continue to output anything written to the file until it is stopped. This is very handy for debugging.</p>

<ul><li><em>$ tail -f error_log</em> - Show the last 10 lines of error_log and continue to output any new data added to the end of the file.</li></ul>

<h3>grep, awk and sed</h3>

<p>There three commands, together with the pipe, are the workhorses of the Linux command line. They allow you to manipulate streams of data, like directory lists, log files, test files and other command outputs. They are often used in combination with other commands.</p>

<p>grep is first, and the most-used (at least, for me). It is a text search utility, which searches lines from the input it is given for a pattern and then outputs those lines. awk is a programming language, though personally I've not used it for much more than splitting lines of text into their constituent parts. sed is another text utility which parse input and performs a search and replace on it, before outputting it.</p>

<ul><li><em>$ grep -iR "superted" /home/bananaman/</em> - search Bananaman's home folder recursively and case-insensitively for all files containing "superted".</li>
<li><em>$ grep "Panthro" Skeletor.txt</em> - search the file Skeletor.txt for lines containing "Panthro" (case-sensitive).</li>
<li><em>$ grep -v "Dogtanian" Muskehounds.txt</em> - an inverted search - search the file Muskehounds.txt for lines NOT containing "Dogtanian" (case-sensitive).</li>
<li><em>$ sed 's/Superman/Batman/g' SuperheroLeagueTable.csv</em> - replace all instances of "Superman" with "Batman" in SuperheroLeagueTable.csv and output.</li>
<li><em>$ sed -i'.bak' 's/KITT/KARR/g' Stock.txt</em> - Make a backup of Stock.txt as Stock.txt.bak, then replace all instances of "KITT" in Stock.txt with "KARR".</li><li><em>$ awk 'NR==15' BabyGotBack.txt</em> - Output the 15th line of BabyGotBack.txt.</li></ul>

<p>Where these three have their greatest utility is in combination, using pipes. A pipe - with the symbol | - tells Linux to use the output from the first command as the input to the second. For example:</p>

<ul><li><em>$ ls | grep "Penfold"</em> - list files in a folder whose name contains "Penfold".</li>
<li><em>$ tail -f error_log | grep "badscript.php"</em> - show any of the last 10 lines of error_log with "badscript.php" in them, and watch the file for new lines with "badscript.php" in them.</li>
<li><em>$ ls -al | awk '{print $5}'</em> - List just the sizes of all files in a folder.</li>
<li><em>$ ls | sed 's/123/456/g'</em> - list files in a folder and replace "123" with "456" in their names.</li></ul>

<p>And you can use multiple pipes in a single line:</p>

<ul><li><em>$ df | grep "/dev/sda1" | awk '{print $4}'</em> - show free space on the /dev/sda1 drive.</li>
<li><em>$ vmstat | awk 'NR==3' | awk '{print $3}'</em> - output the third item on the third line of vmstat (the amount of virtual memory in use).</li>
<li><em>$ ls -al | awk '{print $8}' | grep "Holiday" | sed 's/^[^.]*\.//g'</em> - list all files in a directory with their attributes, reduce that list to just their names, filter for just those containing "Holiday" and, for those, just show their file extensions (yes, a hugely contrived example).</li></ul>

<h3>Shortcuts</h3>

<p>And finally, Linux has a remarkable number of shortcuts for things, especially where related to the history of commands run, and the ability, with the <em>alias</em> command, to add even more. Here are a few of the ones I find myself using regularly (and there are plenty more on this <a href="http://beerpla.net/2008/12/22/mastering-the-linux-shell-bash-shortcuts-explained/">cheat sheet for bash shortcuts</a>):</p>

<ul><li><em>$ sudo !!</em> - run the previous command with superuser privileges.</li>
<li><em>$ cd !$</em> - the "!$" is a shortcut for the argument used in the last command. So if you create a directory in one like using mkdir, you can type this command to change to that directory without needing to type out the whole directory name. Handy!</li>
<li><em>$ ALT-.</em> - (that's ALT Period) in bash and zsh. This works as above, with the added bonus that it will cycle through recent arguments if you press it again, and you can see what the substituted argument is! Thanks to <a href="/blog/basic-linux-command-line-tips/#comment3">Josh Dick</a> and <a href="/blog/basic-linux-command-line-tips/#comment4">RandomDude</a> for adding this in the comments.</li>
<li><em>$ !cd</em> - re-run the most recent command starting with "cd".</li>
<li><em>$ ^save^dave^</em> - re-run the previous command, replacing the first instance of "save" with "dave".</li>
<li><em>$ CTRL-r</em> - search backwards through your commands (great for re-running a recent command).</li></ul>

<div style="margin: 0 0 1.5em 0; padding: 20px; background: #333; color: #fff; border-radius: 3px;">
    <p style="margin: 0; float: left; width: 48%;"><a class="imagelink" href="http://www.cheatography.com/davechild/cheat-sheets/linux-command-line/"><img src="http://www.cheatography.com/images/cheatography_logo.png" alt="Cheatography"></a><br>A companion Linux Command Line Cheat Sheet is available for free at <a style="color: #fff; border-color: #fff;" href="http://www.cheatography.com/davechild/cheat-sheets/linux-command-line/">Cheatography</a>!</p>
    <ul style="margin: 0; float: right; width: 38%; border-radius: 3px;" class="cheat_sheet_downloads"><li>&bull; <a href="http://www.cheatography.com/davechild/cheat-sheets/linux-command-line/">HTML (online version)</a></li><li>&bull; <a href="http://www.cheatography.com/davechild/cheat-sheets/linux-command-line/pdf/">PDF</a></li></ul>
    <div class="clear"></div>
</div> <br><br>]]></description>
				<pubDate>Fri, 18 Mar 2011 11:31:15 +0000</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/blog/basic-linux-command-line-tips/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=linux&amp;start=0" class="ditto_tag" rel="tag">linux</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>
			</item>

			<item>
				<title>6 Dropbox Tips for Developers</title>
				<link>http://www.addedbytes.com/blog/6-dropbox-tips-for-developers/</link>
				<description><![CDATA[ <img src="http://www.addedbytes.com//images/dropbox-icon.png" style="float: left; margin: 0 20px 20px 0;">Dropbox is an excellent cross-platform freemium file synchronisation and online storage application. If that doesn't have you salivating already, it has a few more tricks up its sleeve. <p>Most developers (in my limited experience) work on several different computers and often a variety of different operating systems. Keeping everything up to date across the board can be a pain and takes time that could be better spent elsewhere. It's frustrating when you have to interrupt your work flow because the FTP details for one client are out of date, especially when you then have to update those details on several machines.</p>

<p>Enter <a href="http://db.tt/1PkfAwV">Dropbox</a>, a freemium (2 gig for free, paid plans have more space), cross platform file synchronisation / cloud storage app from the <a href="http://ycombinator.com/">Y Combinator</a> stable. Drop a file into Dropbox and it will appear within moments on all computers you have running the app.</p>

<p>That by itself is hugely useful, allowing you to send files between work and home without needing to touch your firewall. It has the ability to make files public, too, allowing you to send files to colleagues or clients from within your file manager, without using FTP or online file sending services. You can even share folders with other people.</p>

<p>But for the developer, Dropbox has a few extra tricks up its sleeve:</p>

<h3>1. Instant Automatic Offsite Backup</h3>

<p>First, and most importantly, any file saved to Dropbox is immediately sent outside of the building. Dropbox retain copies of deleted files for 30 days for free accounts and indefinitely for paid accounts. This makes it an instant, automatic, off-site backup tool. This is especially useful when ...</p>

<h3>2. Synchronising Your SVN (or whatever) Working Copy</h3>

<p>That's right, you can put your entire working copy into Dropbox and have it synchonised between your computers, allowing you to work on something in multiple locations before you're ready to commit it. Dropbox will also handle the synchronisation of files you don't want to commit to your repository, such as images or binary files.</p>

<p>Some people have reported problems with this system - Dropbox can have problems handling large numbers of concurrent file changes - but I've found it useful.</p>

<h3>3. Storing SSH Keys</h3>

<p>SSH keys can be a pain to manage, but <a href="http://zanshin.net/2009/10/09/managing-ssh-keys/">storing them in your Dropbox</a> can make life that bit simpler.</p>

<h3>4. Log File Synchonisation</h3>

<p>If you use a chat client, you may or may not be aware that it logs your chats for you, so you can go back to earlier conversations and dig out passwords, URLs or other useful information. Logs are stored on a per-computer basis, unfortunately. However, you can work around this with Dropbox.</p>

<p>I use the mighty Pidgin, and copied my logs directory from ~/.purple to my Dropbox, then created a softlink from ~/.purple/logs to the copied directory. Now, when I view the history for a single person, I see the history on all computers, not just the single one I'm using at the time.</p>

<p>The same principle should work just as well with any applications that write to log files (for example, system monitors or build and test logs from a CI server, etc).</p>

<h3>5. Automatic Remote Torrent Starting</h3>

<p>Sometimes you want to start a download in one place when you're somewhere else. Fortunately, most torrent clients have the facility to watch a folder for new torrent files. Set up your torrent client to watch a folder in your dropbox, and voila - you can start a download from anywhere.</p>

<h3>6. Configuration File Synchronisation</h3>

<p>Finally, and perhaps most usefully, you can use Dropbox to maintain config files across multiple systems. This is trickier if you're using multiple OSes, but not impossible.</p>

<p>You can use Dropbox to maintain a single <a href="http://www.code-zen.net/2009/syncing-filezilla-sites-across-computers-with-dropbox/">Filezilla sitemanager.xml</a> file, for example. The same technique can be used with saved PuTTY sessions, and even saved remote desktop connection files.</p>

<h3>Bonus: Extra Space Free!</h3>

<p>Although Dropbox will give you 2 gig for free, you can increase that space with an excellent referral system. In fact, if you sign up by following someone else's referral link - <a href="http://db.tt/1PkfAwV">like this one</a> - you will get some bonus space as well! With a few referrals of your own, you can have as much as 10 gig of storage for free.</p>/p <br><br>]]></description>
				<pubDate>Mon, 14 Jun 2010 14:22:39 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/blog/6-dropbox-tips-for-developers/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=development&amp;start=0" class="ditto_tag" rel="tag">development</a>,<a href="/feeds/tag-feed/?tags=dropbox&amp;start=0" class="ditto_tag" rel="tag">dropbox</a>,<a href="/feeds/tag-feed/?tags=hacks&amp;start=0" class="ditto_tag" rel="tag">hacks</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>
			</item>

			<item>
				<title>Writing Secure PHP, Part 4</title>
				<link>http://www.addedbytes.com/articles/writing-secure-php/writing-secure-php-4/</link>
				<description><![CDATA[ The fourth part of the <a href="http://www.addedbytes.com/articles/writing-secure-php/">Writing Secure PHP</a> series, covering cross-site scripting, cross-site request forgery and character encoding security issues. <p>In <a href="http://www.addedbytes.com/php/writing-secure-php/">Writing Secure PHP</a>, <a href="http://www.addedbytes.com/security/writing-secure-php-2/">Writing Secure PHP, Part 2</a> and <a href="http://www.addedbytes.com/security/writing-secure-php-3/">Writing Secure PHP, Part 3</a> I covered many of the common mistakes PHP developers make, and how to avoid some potential security problems. This article covers some of the more advanced security problems common to PHP on the web.</p>

<h3>Cross-Site Scripting (XSS)</h3>

<p>Cross-site scripting (often abbreviated to XSS) is a form of injection, where an attacker finds a way to have the target site display code they control. In its most basic form, this can be as simple as a site that allows HTML characters in usernames, where someone can specify a username like:</p>

<pre class="php">DaveChild&lt;script type="text/javascript" src="http://www.example.com/my_script.js"&gt;&lt;/script&gt;</pre>

<p>Now, whenever someone sees my username on the target site, the script I've added to my username will run. I could potentially use this to grab the person's login information, log their keystrokes - any number of nefarious activities.</p>

<p>As a developer, you can combat this type of attack by encoding or removing HTML characters (watch out for character encoding issues, as outlined next). Even better than stripping out unwanted characters is to allow a whitelist of safe characters in usernames and other fields. Be especially careful with e-commerce sites where you are listing orders in a CMS - an XSS vulnerability may allow an attacker to gain administrative access to your CMS. It is also important to turn off TRACE and TRACK support on the server, as if there is a vulnerability (and always assume that despite your best efforts there will be) these potentially allow an attacker to steal a user's cookie.</p>

<p>As a user you are also vulnerable to this sort of attack, and it is very difficult, at the moment, to make yourself safe against it. Vigilance is key, and to that end I have released a <a href="http://www.addedbytes.com/tools/xss-alarm-userscript/">userscript that warns you about third party scripts</a> (for users of GreaseMonkey, Opera or Chrome).</p>

<h3>Cross-Site Request Forgery (CSRF)</h3>

<p>Despite the similar name, CSRF is unconnected to XSS. CSRF is a form of attack where an authenticated user performs an action on a site without knowing it.</p>

<p>Let's assume that Jack is logged in to his bank, and has a cookie stored on his computer. Each time he sends an HTTP request to the bank (i.e., views a page or an image on a page) his browser sends the cookie along with the request so that the bank knows that it's him making the request.</p>

<p>Jill, meanwhile, runs a different website and has managed to get Jack to visit it. One of the items on the page is in fact loaded from the bank, for example in an iframe. The URL of the iframe or request contains instructions to the bank to transfer money from Jack's account to Jill's. Because the request is coming from Jack's computer, and includes his cookie, the bank assumes it is a legitimate request and the money is transferred.</p>

<p>This type of attack is extremely dangerous and virtually untracable. As a developer, your job is to protect against it, and the best way to do that is to remember <a href="http://www.addedbytes.com/php/writing-secure-php/">Rule Number One: Never, Ever Trust Your Users</a>. No matter how authenticated they are, do not assume every request was intended.</p>

<p>In practical PHP terms, you can combat CSRF with several relatively simple coding habits. Never let the user do anything with a GET request - always use POST. Confirm actions before performing them with a confirmation dialog on a separate page - and make sure <em>both</em> the original action button or link <em>and</em> the confirmation were clicked. Even better, have the user enter information like letters from their password on the confirmation page.</p>

<p>Add a randomly generated token to forms and verify its presence when a request is made. Use <a href="http://javascript.internet.com/page-details/break-frames.html">frame-breaking JavaScript</a>. Time-out sessions with a short timespan (think minutes, not hours). Encourage the user to log out when they've finished. Check the HTTP_REFERER header (it can be hidden, but is still worth checking as if it is a different domain to that expected it is definitely a CSRF request).</p>

<h3>Character Encoding</h3>

<p>Character encoding in PHP and associated database systems is worthy of its own series. In any one request, there may be more different character encodings in use than you might think.</p>

<p>For example, a single request and response (uploading a file to a server and writing information to a database) may involve all of the following differently items with different character encodings: the HTTP request headers, post data, PHP's default encoding, the PHP MySQL module, MySQL's default set, the set of each table being used, a file being opened and read, a new file being created and written, the response headers and the response body.</p>

<p>English-speaking developers generally don't have much cause to get embroiled in character encoding issues, and that results in a lot of developers with a serious lack of understanding of how character encodings work and fit together. For those that do have a reason to look at character encodings, usually that interest ends with the setting of the response's character set.</p>

<p>However, character sets are a fundamental part of all web development. English alone can exist in any one of a wide variety of sets, and developers are usually familiar with the most common two: ISO-8859-1 and UTF-8. Fewer are familiar with UCS-2, UTF-16 or windows-1252. Still fewer are familiar with commonly used alternative language sets (e.g, GB2312 for Chinese).</p>

<p>Which, in a very roundabout way, brings me on to the security pitfalls of character encodings. Where data is processed by PHP using one character set, but a database server uses a different character set, a character (or series of characters) deemed safe by PHP may in fact allow SQL injection against the database.</p>

<p>PHP security expert Chris Shiflett <a href="http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string">has written about this issue</a> and included an example of how it can be exploited to allow SQL injection even where input is sanitized using addslashes().</p>

<p>The solution is to always <em>always</em> use mysql_real_escape_string() rather than addslashes() (or use prepared statements / stored procedures), and to explicitly state character sets at all stages of interaction. Ideally, use the same character set throughout your system (UTF-8 is recommended) and where PHP allows you to specify a character encoding for a function (e.g., htmlspecialchars() or htmlentities()), make use of it.</p>

<p>It's not just SQL that's vulnerable as a result of character encoding bugs. Cross-site scripting is possible even where HTML characters are escaped if character sets are not handled properly. Fortunately, once again that is simple to avoid by properly setting character encodings at all stages of the process and specifying character encoding for functions where possible.</p> <br><br>]]></description>
				<pubDate>Thu, 11 Sep 2008 13:11:14 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/articles/writing-secure-php/writing-secure-php-4/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=code&amp;start=0" class="ditto_tag" rel="tag">code</a>,<a href="/feeds/tag-feed/?tags=coding&amp;start=0" class="ditto_tag" rel="tag">coding</a>,<a href="/feeds/tag-feed/?tags=development&amp;start=0" class="ditto_tag" rel="tag">development</a>,<a href="/feeds/tag-feed/?tags=mysql&amp;start=0" class="ditto_tag" rel="tag">mysql</a>,<a href="/feeds/tag-feed/?tags=php&amp;start=0" class="ditto_tag" rel="tag">php</a>,<a href="/feeds/tag-feed/?tags=programming&amp;start=0" class="ditto_tag" rel="tag">programming</a>,<a href="/feeds/tag-feed/?tags=security&amp;start=0" class="ditto_tag" rel="tag">security</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>,<a href="/feeds/tag-feed/?tags=tutorial&amp;start=0" class="ditto_tag" rel="tag">tutorial</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>,<a href="/feeds/tag-feed/?tags=webdev&amp;start=0" class="ditto_tag" rel="tag">webdev</a>
			</item>

			<item>
				<title>What Makes a Great Developer?</title>
				<link>http://www.addedbytes.com/blog/what-makes-a-great-developer/</link>
				<description><![CDATA[ What makes a truly great developer? Some might say a positive attitude. Some might say a high-sugar, high-caffeine, high-bacon diet. Some might say an absence of sunlight and as many monitors as a desk can support. I say pessimism and laziness are high up the list. <p>What makes a truly great developer? Some might say a positive attitude. Some might say a high-sugar, high-caffeine, high-bacon diet. Some might say an absence of sunlight and as many monitors as a desk can support.</p>

<p>Certainly, everyone has anecdotes about developers they've worked with who they thought were brilliant. Unfortunately, most of the time that judgement is made not based on code quality, or hitting of deadlines, but on less relevant criteria, like whether or not the developer knew the names of their colleagues, how many lines of code they output or how confident they sounded when talking about their work.</p>

<p>Unfortunately, the best developers don't always come across positively. While this list may not be applicable to every development environment, here are a few of the traits to look out for to spot a great developer.</p>

<h3>Pessimistic</h3>

<p>Great developers are almost always pessimistic with regard to their work. That doesn't mean they're not upbeat, lively or even cheerful - just that they will always be thinking about what can go wrong and how it can be dealt with.</p>

<p>They'll assume that at some point they'll need to undo work already completed, that hardware will fail, that all security will be compromised, and that your office will burn to the ground. The really brilliant ones will assume that will all happen on the same day. And they won't be happy until there is a specific, actionable, testable - and fully tested - plan for dealing with these sorts of issues. Even then they won't be completely happy.</p>

<p>Pessimistic developers will be the ones that find constant flaws in ideas, and the important thing to remember when working with them is that they're not doing that to tear down other people's ideas - they're doing it to ensure that the ideas that turn into projects are properly thought through and that as many problems as possible have been anticipated in advance. That neurotic, paranoid, pessimistic attitude is exactly what you should be looking for if what you want from your developers is robust, secure, reliable code.</p>

<p>By contrast, an optimistic developer will be more likely to simply assume code will work, or that it is secure, or give a deadline for a project without considering all the potential pitfalls.</p>

<p>Likely to be heard saying: <strong>"And what happens when that goes wrong?"</strong></p>

<h3>Lazy</h3>

<p>Laziness is not usually viewed as a desirable trait, and in this case I don't mean turns-up-late-and-pretends-to-work laziness or just-move-that-logic-to-the-view laziness - both entirely unwanted. I mean a desire to not do tasks that are repetitive, or to waste time doing things a machine can do for you, or even to avoid future work by writing better code now. A lazy developer is one that builds a reusable code library, or wants a fully automated build process rather than a manual copy-and-paste one, or wants comprehensive automated unit testing, or writes code to be scalable even though that wasn't a requirement (rather than revisit it later).</p>

<p>As a bonus, a lazy developer is also usually one who will try and keep a project focussed on its core goals, rather than try and cram more work into the same time, providing a buffer against feature creep.</p>

<p>For example, when writing a category structure, a lazy developer might be likely to assume a many-to-many relationship between parent and child categories, even though the project specification says it will be a one-to-many relationship. Why? Because it might be needed one day and it would be better to write it that way from the start than to revisit it later.</p>

<p>Likely to be heard saying: <strong>"We could automate that."</strong></p>

<h3>Curious</h3>

<p>Good developers are often rather like <a href="http://en.wikipedia.org/wiki/House_md">Gregory House</a>. They're very easily bored by repetitive work (see laziness) and spend most of their time ploughing through it looking for an interesting and challenging (and hopefully new) problem to solve. The less time they can spend on the repetitive, the higher the frequency of the challenges.</p>

<p>Curious developers will be constantly looking for new problems to solve, and better ways to solve previous problems. They'll be the ones encouraging new ways to work and constantly tweaking and trying to improve existing systems. They'll also be the ones most conscious of existing problems in the current working environment, and trying to correct those problems. Curious developers will usually have a wide breadth of knowledge, not just of their primary language(s), but of supportive, associated and alternative technologies.</p>

<p>Curious (or easily-bored) developers are often the least stuck in their ways - the most open to change. They may well need convincing of why a new way of working is better (and that's no bad thing) but as long as it's an improvement, and likely to release more time to spend on the interesting problems, they'll embrace it with a minimum of resistance.</p>

<p>Curiosity also breeds creativity, another highly desirable trait in any developer. A strong desire to work out what has caused a problem and how to solve it is highly likely to motivate someone to continue once obvious avenues are exhausted. It is that sort of mentality that fosters "outside the box" thinking and creative coding.</p>

<p>Possibly the most useful attribute of a curious developer is that desire to find and cure a problem rather than just paper over the crack.</p>

<p>Likely to be heard saying: <strong>"Maybe there's another way to do this."</strong></p>

<h3>Meticulous</h3>

<p>Many great developers are sticklers for detail. They will demand consistency in their work and the work of their team (they're likely to care about common code standards and naming conventions, for example). They'll want unit testing and peer review of code. They'll want everyone in their team to comment on and document code. They are likely to be fussy about version control log messages.</p>

<p>They'll also be fussy about details in communication, and happy to ask what might seem like obvious questions, simply to be sure they have properly understood. This is especially true of things like bug reports. While they may not be terribly motivational communicators, they will usually be able to explain concepts clearly and effectively. That clarity is a tremendous advantage in any development environment, especially if teaching and learning are encouraged.</p>

<p>Likely to be heard saying: <strong>"I just have a couple of questions ..."</strong></p>

<!-- ckey="6C8199DB" -->

<h3>Translations</h3>

<ul><li><a href="http://translated.by/you/what-makes-a-great-developer/" hreflang="ru">Russian / &#1056;&#1091;&#1089;&#1089;&#1082;&#1080;&#1081;</a></li></ul> <br><br>]]></description>
				<pubDate>Thu, 17 Apr 2008 13:03:00 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/blog/what-makes-a-great-developer/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=blog&amp;start=0" class="ditto_tag" rel="tag">blog</a>,<a href="/feeds/tag-feed/?tags=career&amp;start=0" class="ditto_tag" rel="tag">career</a>,<a href="/feeds/tag-feed/?tags=developer&amp;start=0" class="ditto_tag" rel="tag">developer</a>,<a href="/feeds/tag-feed/?tags=development&amp;start=0" class="ditto_tag" rel="tag">development</a>,<a href="/feeds/tag-feed/?tags=job&amp;start=0" class="ditto_tag" rel="tag">job</a>,<a href="/feeds/tag-feed/?tags=philosophy&amp;start=0" class="ditto_tag" rel="tag">philosophy</a>,<a href="/feeds/tag-feed/?tags=programming&amp;start=0" class="ditto_tag" rel="tag">programming</a>,<a href="/feeds/tag-feed/?tags=software&amp;start=0" class="ditto_tag" rel="tag">software</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>
			</item>

			<item>
				<title>PHP Querystring Functions</title>
				<link>http://www.addedbytes.com/blog/code/php-querystring-functions/</link>
				<description><![CDATA[ <p>Adding and removing variables to and from URLs using PHP can be a relatively simple process admittedly, but I have a couple of functions I use often to make the process even less time-consuming.</p><br />
<br />
<h3>Add Querystring Variable</h3><br />
<br />
<p>A PHP function that will add the querystring variable $key with a value $value to $ur</p> <p>Adding and removing variables to and from URLs using PHP can be a relatively simple process admittedly, but I have a couple of functions I use often to make the process even less time-consuming.</p>

<h3>Add Querystring Variable</h3>

<p>A PHP function that will add the querystring variable $key with a value $value to $url. If $key is already specified within $url, it will replace it.</p>

<pre class="php">function add_querystring_var($url, $key, $value) {
    $url = preg_replace('/(.*)(?|&amp;)' . $key . '=[^&amp;]+?(&amp;)(.*)/i', '$1$2$4', $url . '&amp;');
    $url = substr($url, 0, -1);
    if (strpos($url, '?') === false) {
        return ($url . '?' . $key . '=' . $value);
    } else {
        return ($url . '&amp;' . $key . '=' . $value);
    }
}</pre>

<h3>Remove Querystring Variable</h3>

<p>A PHP function that will remove the variable $key and its value from the given $url.</p>

<pre class="php">function remove_querystring_var($url, $key) {
    $url = preg_replace('/(.*)(?|&amp;)' . $key . '=[^&amp;]+?(&amp;)(.*)/i', '$1$2$4', $url . '&amp;');
    $url = substr($url, 0, -1);
    return ($url);
}</pre> <br><br>]]></description>
				<pubDate>Tue, 05 Dec 2006 15:41:30 +0000</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/blog/code/php-querystring-functions/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=code&amp;start=0" class="ditto_tag" rel="tag">code</a>,<a href="/feeds/tag-feed/?tags=development&amp;start=0" class="ditto_tag" rel="tag">development</a>,<a href="/feeds/tag-feed/?tags=functions&amp;start=0" class="ditto_tag" rel="tag">functions</a>,<a href="/feeds/tag-feed/?tags=links&amp;start=0" class="ditto_tag" rel="tag">links</a>,<a href="/feeds/tag-feed/?tags=php&amp;start=0" class="ditto_tag" rel="tag">php</a>,<a href="/feeds/tag-feed/?tags=programming&amp;start=0" class="ditto_tag" rel="tag">programming</a>,<a href="/feeds/tag-feed/?tags=querystring&amp;start=0" class="ditto_tag" rel="tag">querystring</a>,<a href="/feeds/tag-feed/?tags=reference&amp;start=0" class="ditto_tag" rel="tag">reference</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>,<a href="/feeds/tag-feed/?tags=url&amp;start=0" class="ditto_tag" rel="tag">url</a>,<a href="/feeds/tag-feed/?tags=variable&amp;start=0" class="ditto_tag" rel="tag">variable</a>
			</item>

			<item>
				<title>Three Bloglines Tips</title>
				<link>http://www.addedbytes.com/blog/three-bloglines-tips/</link>
				<description><![CDATA[ <p>Use <a href="http://www.bloglines.com">Bloglines</a>? You're not alone. Have a huge list of feeds in your sidebar, and never read anything because it takes too long? Once again, you're very much not alone. Find keeping up with Bloglines is taking up all of your time? You're one of millions. However, all is not lost.</p> <p>Use <a href="http://www.bloglines.com">Bloglines</a>? You're not alone. Have a huge list of feeds in your sidebar, and never read anything because it takes too long? Once again, you're very much not alone. Find keeping up with Bloglines is taking up all of your time? You're one of millions. However, all is not lost. A few simple tricks will make your subscriptions easier to manage and less of a burden.</p>

<h3>Folders</h3>

<p>Bloglines supports folders, into which you can delicately place your various feeds, grouping them together by topic. If when you look at Bloglines all you see is a massive, unmanagable list of feeds, folders should be your first stop. However, when you create your folders, put some thought into how you set them up - once they're set up, changing them later is going to take time, and most people don't want to have to go through the process again. Also, don't name them just "Topic" - name them "01. Topic" instead - give each folder a number at the start and you'll be able to order your folders any way you like, ensuring similar topics are always grouped.</p>

<p>Folders also allow you to spend less time on Bloglines. Keep your personal feeds (yes, including comics) separate from your work ones. You can view the work ones at the office, without being distracted by Dilbert, and keep up to date with friends and pictures of cats when you've got the time. Keep your important folders at the top of your folders list and the task becomes even easier, as you'll avoid having a tempting folder in the middle of the more serious work-related ones.</p>

<h3>Re-Name Feeds</h3>

<p>Website feeds are listed automatically using the name given by the website owner for the feed. For some this may be a problem. For example, I am subscribed to a feed from an <a href="http://feather.planetapache.org/">Apache blog</a>, and the default name for this is simply "feather". While that might be what their blog is called, it's no use to me - a few months after I've subscribed, I'm going to have no idea what "feather" actually is, and will end up ignoring it. However, I've renamed it "Apache Feather Blog" - far more helpful to me.</p>

<h3>Only Show Updated Feeds</h3>

<p>Once you've got all of your feeds organised, you may find that Bloglines loads rather slowly. When you've got several hundred subscriptions, that can be a real problem. Fortunately, Bloglines gives you the option to only show feeds with new items - updated feeds. You can enable this under <a href="http://www.bloglines.com/profile?mode=3">Feed Options</a> in your Bloglines account settings.</p> <br><br>]]></description>
				<pubDate>Wed, 20 Sep 2006 14:54:05 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/blog/three-bloglines-tips/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=feeds&amp;start=0" class="ditto_tag" rel="tag">feeds</a>,<a href="/feeds/tag-feed/?tags=hacks&amp;start=0" class="ditto_tag" rel="tag">hacks</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>
			</item>

			<item>
				<title>Ten Ways To Improve Your Website Conversion Rate</title>
				<link>http://www.addedbytes.com/articles/online-marketing/ten-ways-to-improve-your-website-conversion-rate/</link>
				<description><![CDATA[ Why worry about getting twice as many people to visit your site, when it can be far easier to double the number of sales from the people already visiting? Here are 10 ways to improve your website conversion rate. <h3>What is a Conversion Rate?</h3>

<p>Your conversion rate is a measure of the number of potential customers that go on to buy. In the context of a website, it is usually the percentage of visitors that make a purchase. Many websites concentrate solely on increasing the number of visitors they have, when often they have fairly simple problems with their site that, if solved, would have a huge effect on their conversion rate and improve their site's bottom line at minimal expense.</p>

<p>Improving a website conversion rate can be relatively simple. Here are 10 techniques for doing just that:</p>

<h3>10. Make The User's Life Easy</h3>

<p>Let's start with something that sounds simple, but apparently is too complex for many companies to get right. The more difficult you make your web site to use, the less people will buy from you.</p>

<p>A well designed website should aim to <em>prevent nobody from buying</em> - to allow 100% of the people who want to buy to do so. So where do they go wrong?</p>

<ul><li><strong>Accessibility</strong><br />Making a site accessible is a legal obligation in many countries. Despite that, inaccessible websites are still being created. That can affect your sales, depending on how inaccessible you are, as visitors find the site impossible to use and go elsewhere (and end up recommending one of your competitors to their friends as well). A fairly typical inaccessible site could be losing 5% of potential sales because of this. (A <em>really</em> inaccessible website could even prevent search engines indexing it, giving a far higher amount of potential lost sales.)
&nbsp;</li><li><strong>Browsers</strong><br />Many designers only pay attention to Internet Explorer. The justification for this is usually that 99% of the site's users use IE. It never seems to occur to the designers that perhaps the reason they have so few visitors with other browsers is that their site is fundamentally broken - it doesn't work in anything else. Percentages of people not using IE varies from site to site - over 60% of visitors to this site use an alternative browser, for example. The number most often quoted though, is that 80-85% of web users are using IE on Windows, which means that an average site that doesn't work in anything else could easily be losing 15-20% of sales.
&nbsp;</li><li><strong>Be Bold!</strong><br />What happens when a user decides to buy a product? They add it to a shopping basket. How do they add it? They click a button or link (usually a button). What happens when they can't see the button? They go elsewhere. There are some users who are <em>still</em> uncomfortable scrolling. Having things above the fold is still important. And yet there are still plenty of sites out there with buttons that are too subtle, or don't say the right thing, or are hidden away at the bottom of the page. "Add" is rubbish button text. "Buy" is ok. "Add xxx To Your Basket" is great. "Add xxx to Your Basket" in big letters on a big, bright button, near the top of the page, is even better. Calls to action, like this, don't have to be gaudy or tasteless, but they do have to be obvious and clear. Sites I have worked on where just the call to action was changed have reported anything from a 1% to 30% increase in sales as a result.
&nbsp;</li><li><strong>Usability</strong><br />If your potential customers want to find out more before they buy, can they? Is it obvious to the user where to go to find the technical specs on your products? Are they online at all? Are they in PDF format? Can users even find your products in the first place? This is probably the most common mistake I see on any website - a complete failure to think of what the user wants and needs, and how they might use a site. Plenty of sites have product pages with a photo and some sales patter - and nothing else. Anything from 1% to 99% of potential sales can be lost through poor usability.</li></ul>

<p>When you combine all of the problems above, it becomes fairly clear how easy it is to have a site perform poorly. Make your site accessible, make sure it is usable, make sure it works in common browsers, and make your calls to action clear and unambiguous, and you should be in a position to start converting the people who want to buy.</p>

<h3>9. Be Clear, Open and Honest</h3>

<p>If you have a product out of stock, say so. Few things annoy users as much as reading all about a product they are after, adding it to a cart, and starting the checkout process - only to find out the product isn't actually available.</p>

<p>The same applies to pricing - a user might spend $100 on a product, but when they find out the shipping is $100 on top of that, they are unlikely to continue the sale. Showing delivery pricing is tricky business, but not impossible. An <a href="http://ip-to-country.webhosting.info/node/view/6">Ip to Country</a> database will allow you to work out where a user is from and show them a likely delivery cost, for example. If you can't do that, show delivery prices for the countries most appropriate to you - where your products are most often delivered, or for major world regions.</p>

<h3>8. Don't Waste Time</h3>

<p>One of the biggest mistakes sites make is asking for too much information. Your conversion process may be sale, or it may be a request for information. Either way, don't waste the user's time asking for things you don't need to know. This is, of course, doubly important when it comes to asking for information the user deems private, and that they don't want to give out without good reason.</p>

<p>You don't need to demand the user's email address before letting them download a PDF. You don't need their phone number when they fill out an email enquiry form. A user may not want to buy from you twice - so why make them create an account so they can buy again later before processing their first order? You can give the user the option to do all of these things by all means, but make sure it's not compulsory.</p>

<h3>7. Help The User Trust You</h3>

<p>Most people are still cautious when buying online, and rightly so. There are plenty of people you really shouldn't give your credit card information to! It's important to give the potential customer every reason to trust you.</p>

<p>An address - bricks and mortar, not a P.O. Box - is a good start. A phone number, with people answering the phone, also helps. Showing a privacy policy and explaining shipping procedures clearly can also help the user to trust you. If you have a SSL certificate, show the "VeriSign Secured" logo to the user.</p>

<p>Design and content also play a part in trust. A poor design gives off an unprofessional feeling. If a company can't afford a decent website, or won't spend the money on it, how can a user be sure their order will be treated with the importance it deserves? If content is inaccurate or badly written, the same applies - show that you take pride in what you do.</p>

<h3>6. Have a Clear Returns Policy</h3>

<p>Returns on the web are, and are likely to remain, a major issue for consumers. With a bricks and mortar shop, the customer knows where the shop is and that to return the product they simply have to go back there and explain the problem. With the web, this is more of an issue. This is especially true for clothing (where people cannot try things on before buying).</p>

<p>Users are impressed with sites with a good returns policy and are more likely to buy from them. Have people phone for returns - they can then explain the problem to a real person, which is always a good first step. Free return shipping is usually a good option, if commercially viable. People don't like to pay to return things, especially if it is a mistake by the retailer. Finally, give the user plenty of time to return things. 28 days is fairly common, but if it takes you that long to deliver a product, what use is the return policy? 28 days from the date of delivery is better.</p>

<h3>5. Keep the User Informed</h3>

<p>When somebody buys something online, they want to know when it's going to arrive at their door. People are impatient, after all. Giving them an estimated delivery date during the checkout process is a good start. Emailing them when their product is dispatched is great. Giving them a tracking number if using a delivery service that supports online tracking is even better. Keep the user informed at every step of the process, before and after sale, about as much as you can.</p>

<p>How will this improve your conversion rate? Leaving the customer happy once they have made a sale means they are more likely to speak favourably about you later. They may even recommend you to their friends and within online communities. They are also far more likely to buy from you again.</p>

<p>Think about it like this - if a salesman is doing their absolute best to help you, and to make your life easy, and answering your questions, you might buy what they were selling. If they completely ignored you after you'd bought from them, how would you feel about them? They might well have undone all the good work they put in, because once you'd completed your purchase they see no immediate value in you. A company that shows it cares about their customers, even after they've finished shopping, will make a user far happier and far more likely to return.</p>

<h3>4. Offer Different Payment Options</h3>

<p>It might sound obvious, but you should offer the user a reasonable selection of methods of payment. Not everybody has a credit card, and those that do don't always want to use them. You don't have to accept cheques, but when deciding on payment methods, consider alternatives to the usual methods. Make the user's life easy and give them what they want.</p>

<h3>3. Improve the Value of Visitors</h3>

<p>People that buy from you are doing so because they like what it is they see. If a user adds a product to a basket, show them other things they might like as well. If they are viewing a product, the same applies - show them similar items. While they might not buy the product they first saw, other similar ones may not have issues that put them off the first. Upselling and cross-selling are tried and tested sales techniques, and there is no reason not to use them on the web.</p>

<h3>2. Be Memorable</h3>

<p>A good site will include information. A poor one is just an online catalogue. Information (articles, advice, reviews and so on) all help the user early in their buying process. Users start with research online, just as they do offline. If you can make contact with the user at that stage of their process, and give a favourable impression, there is a good chance that they will come back and buy from you when they finally decide to make a purchase.</p>

<p>Being memorable, and making sure you stick in the user's mind, is dependant on a lot of factors. You must have a USP (see the next point), and branding is important (no good if your visitors remember why you are great but don't remember your name), as well as the quality of your site and information.</p>

<h3>1. Know Your USP</h3>

<p>Finally, the most important point of all - your Unique Selling Point (USP). Your USP is what sets you apart from your competition. If a visitor goes to several sites looking for a product, why would they decide to buy from you instead of somewhere else?</p>

<p>Many companies do not know their USP. Almost all companies have one, but not all of them are aware of it. If you are a family run business, that's a potential USP. Great customer service, low prices, products that can't be bought elsewhere, free delivery, great support - all of these are USPs. Tell your users what yours is. Shout it from the proverbial rooftops.</p>

<h3>Part 2</h3>

<p>In March 2009, part 2 of this series was added: <a href="http://www.addedbytes.com/online-marketing/nine-more-ways-to-improve-your-website-conversion-rate/">Nine More Tips for Improving Your Website Conversion Rate</a>.</p>

<h3>Bonus!</h3>

<p>One excellent (and practical) way to increase your website conversion rate is to add consumer reviews to your store. They are a proven way to increase sales, and they have an excellent positive effect on your search engine optimisation work. A service like <a href="http://www.feedbackfair.com">FeedbackFair</a> will give your reviews extra credibility.</p> <br><br>]]></description>
				<pubDate>Mon, 12 Jun 2006 13:00:04 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/articles/online-marketing/ten-ways-to-improve-your-website-conversion-rate/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=business&amp;start=0" class="ditto_tag" rel="tag">business</a>,<a href="/feeds/tag-feed/?tags=conversion&amp;start=0" class="ditto_tag" rel="tag">conversion</a>,<a href="/feeds/tag-feed/?tags=design&amp;start=0" class="ditto_tag" rel="tag">design</a>,<a href="/feeds/tag-feed/?tags=ecommerce&amp;start=0" class="ditto_tag" rel="tag">ecommerce</a>,<a href="/feeds/tag-feed/?tags=howto&amp;start=0" class="ditto_tag" rel="tag">howto</a>,<a href="/feeds/tag-feed/?tags=marketing&amp;start=0" class="ditto_tag" rel="tag">marketing</a>,<a href="/feeds/tag-feed/?tags=online+marketing&amp;start=0" class="ditto_tag" rel="tag">online marketing</a>,<a href="/feeds/tag-feed/?tags=seo&amp;start=0" class="ditto_tag" rel="tag">seo</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>,<a href="/feeds/tag-feed/?tags=tutorials&amp;start=0" class="ditto_tag" rel="tag">tutorials</a>,<a href="/feeds/tag-feed/?tags=usability&amp;start=0" class="ditto_tag" rel="tag">usability</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>
			</item>

			<item>
				<title>My Site's Dropped!</title>
				<link>http://www.addedbytes.com/articles/online-marketing/my-site-has-dropped/</link>
				<description><![CDATA[ Why sites usually drop in the SERPs and what to do if it happens to you. <p>Visit any one of the excellent internet marketing forums on the web and you will see a host of threads dedicated to the same topic: <strong>My Site Has Dropped</strong>. Google, Yahoo, MSN, Ask and the other engines are constantly in a state of flux, so to a degree this is to be expected, but sometimes major shifts in rankings and resultant traffic are seen and sometimes sites are penalised. Consequently, on any given day there are plenty of webmasters who wake up to discover their traffic has vanished into this air.</p>

<p>For hobby webmasters, this is generally not a problem. For anyone making money online, though, it can be extremely nervewracking. For those whose livlihoods depend on their websites, losing all search engine traffic can be a devastating blow.</p>

<p>Unfortunately, a great deal of the threads and dicussions on this topic often result in a large amount of misinformation. For example, as a result of one recent Google update, many sites had lost significant rankings. Some forums were claiming that the specific industries had specifically been targetted and sites in that industry had been penalised in some way. Some claimed that Google had "lost" a serious amount of data, or had re-added old data, and that was what caused the change. There are as many explanations for loss of traffic as there are sites that have dropped out there.</p>

<p>Unfortunately, with all of the wild ideas and crazy theories being bandied around, the average site owner has a very hard time working out first what has happened, and second what to do about it.</p>

<p>The very first thing to consider when looking at the effect of a shift in algorithms is that a change rarely affects all ranking criteria at once. They rarely, if ever, target a specific industry, even though the effect of a change on a specific market may be far greater than in others (this is especially true in ultra-competitive arenas, such as real estate, finance and the adult industry, where those at the top are often precariously balanced, and a tiny change in algorithms can mean major changes to the SERPs).</p>

<h3>Fixing The Problem</h3>

<p>Before anything else, it is important to make sure there actually is a problem. The forums usually first fill with these types of posts during an update. However, while the update is going on the SERPs are in a state of flux. Sites can appear all over the place during an update, so save the panic until the update is over. Updates can last days, and it is a good idea to watch a few of the SEO forums to find out when an update has finished.</p>

<p>If the update has finished and a site has definitely dropped, it is rare that it will be able to regain the exact same (or better) traffic within a short space of time. If an algorithm change has caused a site to be dropped, the chances are that one specific thing that was making that site rank well (for example, rented links) has been devalued. If the only thing that was making a site rank well has become less important, there are probably no quick fixes.</p>

<h3>Is It a Penalty?</h3>

<p>The first thought to cross most peoples' minds when sites lose traffic and drop down the SERPs is that there must be a penalty applied to their site. Penalties are very real, yes, but there is no reason to suspect you have had a penalty applied unless one of the following is true:</p>

<ul><li>You have been doing bad things. If you've been using cloaking, hidden text, doorway pages, keyword stuffing or link farms etc, expect to be penalised.</li><li><p>You can't find your site - at all - in the search engine you suspect has penalised you. In the case of Google, search for "site:addedbytes.com" (replacing addedbytes.com with your domain name, of course). If no results are returned, Google will show you something like this:</p>

<p>Your Search - <strong>site:addedbytes.com</strong> - did not match any documents.</p>

<p>Suggestions:<ul><li>Make sure all words are spelled correctly.</li><li>Try different keywords.</li><li>Try more general keywords.</li></ul></p></li></ul>

<p>If you have been penalised, then you'll get no sympathy from me - be more careful in future! SEO is not about getting top rankings for two weeks before vanishing forever from results, it's about a sustained and long-term effort to get top spots. It's not a sprint, it's a marathon. It's not worth taking the kind of risks that will get you penalised unless you have no choice. (&lt;/lecture&gt;)</p>

<p>To come back from a penalty is not a quick process, but it is relatively simple. First, remove all remotely-fishy stuff from your site. Before a site is reincluded, the chances are it will be checked, and if you've not corrected what you were doing wrong, you will not be reincluded. Be over-cautious at this stage - better to remove absolutely anything that a search engine might dislike than remove the obvious things and be refused reinclusion because you've assumed that the search engine penalised you for something specific and that fixing that alone is enough. Once you are certain there is nothing left <em>on your domain</em> that can be considered dodgy by the whitest of white hats, then file a reinclusion request with the engine you are having trouble with.</p>

<p>Then wait - and it may be many months before you are reincluded, if at all. Don't pressure the engine and don't file the request every day or week. File it once and wait. You're the kid in the corner with the large hat with a D on it. THe search engine doesn't like you - you tried to manipulate it (even if it wasn't your work, it's your site and your responsibility). Have patience and work on building links to your site and building content - at least then when you are reincluded you should have better traffic.</p>

<h3>What Next?</h3>

<p>If you've not been penalised, then you should look at why you have dropped. Actually, let me rephrase - you should look at why your competitors have risen up the SERPs - that is a more accurate way to look at it. Check out the top sites in your field - what are they getting traffic for? What do their sites have that yours doesn't? Link quantity? Link quality? Content? Meta tags? A title in a specific shade of blue? Look for themes in the top ranking sites - if you can find out why they are top now, and you are not, you know what to work on.</p>

<p>The chances are that if you're not been penalised and your site is not performing as well, you need to look at improving or updating your online marketing tactics.</p>

<p>If your site is lacking in normal, organic links for example (you have previously paid for all of your links), then start adding things to your site people will want to link to to add to your normal organic links. Add a blog and post controversial or funny (but always unique) items on there. The web is a conversation, and you are not as prominent as you once were because the search engines are getting better - to get yourself noticed, you need to be talked about. [The same applies in all area - if the people doing better than you all have very content-heavy sites, hire some copywriters and get them writing some interesting and engaging content; if the people doing better than you have sites built with good quality, semantic markup, and you don't, have your site rebuilt.]</p>

<p>The most important thing is to treat a perceived drop in rankings for what it is: a temporary glitch in your grand plan. Put in a bit of hard work and a little investment in your online marketing and you should see improvements. You were ranking well before, so the chances are good that you will rank well again.</p> <br><br>]]></description>
				<pubDate>Wed, 04 Jan 2006 12:24:00 +0000</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/articles/online-marketing/my-site-has-dropped/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=google&amp;start=0" class="ditto_tag" rel="tag">google</a>,<a href="/feeds/tag-feed/?tags=howto&amp;start=0" class="ditto_tag" rel="tag">howto</a>,<a href="/feeds/tag-feed/?tags=marketing&amp;start=0" class="ditto_tag" rel="tag">marketing</a>,<a href="/feeds/tag-feed/?tags=online+marketing&amp;start=0" class="ditto_tag" rel="tag">online marketing</a>,<a href="/feeds/tag-feed/?tags=optimization&amp;start=0" class="ditto_tag" rel="tag">optimization</a>,<a href="/feeds/tag-feed/?tags=seo&amp;start=0" class="ditto_tag" rel="tag">seo</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>
			</item>

			<item>
				<title>Writing Secure PHP, Part 3</title>
				<link>http://www.addedbytes.com/articles/writing-secure-php/writing-secure-php-3/</link>
				<description><![CDATA[ The third part of the Writing Secure PHP series, covering weak passwords, clients and more advanced topics. <p>In <a href="http://www.addedbytes.com/php/writing-secure-php/">Writing Secure PHP</a> and <a href="http://www.addedbytes.com/security/writing-secure-php-2/">Writing Secure PHP, Part 2</a> I covered many of the basic mistakes PHP developers make, and how to avoid common security problems. It is time to get a little deeper into security though, and begin to tackle some more advanced issues.</p>

<p>[Writing Secure PHP is a series. <a href="http://www.addedbytes.com/php/writing-secure-php/">Part 1</a>, <a href="http://www.addedbytes.com/php/writing-secure-php-2/">Part 2</a> and <a href="http://www.addedbytes.com/php/writing-secure-php-4/">Part 4</a> are currently also available.]</p>

<h3>Context</h3>

<p>Before I start, it is worth mentioning at this point in this series that much of what is to come is highly dependant on context. If you are running a small personal site and are regularly backing it up, the chances are that there is no real benefit to you spending weeks on advanced security issues. If an attacker can gain nothing (and cause no harm) by compromising your site, and it would only take you ten minutes to restore it, should something go wrong, then it would be a waste to spend too long on security concerns. At the other end of the scale, if you are managing an ecommerce site that processes thousands of credit cards a day, then it is negligent not to spend a lot of time researching and improving your site's security.</p>

<h3>Database Field Lengths</h3>

<p>Database (we're going to talk about <a href="http://www.mysql.com">MySQL</a> here, but this is applicable to any database) fields are always of a specific type, and every type has its limits. You can as well, in MySQL, limit field lengths further than they are already limited by their types.</p>

<p>However, to the inexperienced developer, this can present problems. If you are allowing users to post an article on your site, and adding that to a database field with type "blob", then the longest article you can store in the database is 65,535 characters. For most articles that will be fine, but what is going to happen when a user posts an article of 100,000 characters? At best, if you have set up your site so errors are not displayed, their article will simply vanish without being added to the site.</p>

<p>Remember that for an attacker to be able to compromise your system, they need information about it. They need to find weaknesses. Error messages are a very powerful part of that and if you are displaying errors, then an attacker can make use of this to find out information about your database.</p>

<p>To fix this, simply check the lengths of data input through forms and querystrings and ensure that before you launch a site you check forms will not cause errors to be displayed when too many characters are entered.</p>

<h3>Weak Passwords</h3>

<p>Dictionaries are a useful tool for an attacker. If you have a site with a login system and your database were compromised (and there is no harm in assuming that at some point it will be), an attacker can grab a list of hashed passwords. It is difficult (practically impossible) to directly translate a hash back into a password.</p>

<p>However, most attackers will have databases containing lists of words and their matching hashes in common formats (eg a database with all words in English and their MD5 hashes). It is fairly easy, should someone gain access to your database, for them to compare a hashed password to this list of pre-hashed passwords. If a match is found in the list, the attacker then knows what the un-hashed password is.</p>

<p>There are ways to avoid this problem, and the best of those is to ensure that only strong passwords are ever used. Some people find guaging the strength of passwords tricky, but the general rule of thumb is: a password like "password", "admin", "god", "sex", "qwerty", "123456" or similar (i.e. easily guessable) is extremely weak; a password made up only of a word in the dictionary is weak; a password made of letters, numbers and making use of upper and lower case is strong (there is a strong usability case to be made for not using case-sensitive passwords - if you wish to use case-insensitve ones, simply perform checks to ensure people do not pick passwords like "password12345").</p>

<h3>Clients</h3>

<p>Clients are a huge security risk, believe it or not. Some will hire a cheaper developer to make small changes six months after you're finished. Some will give out FTP details to anyone who phones and asks for them. [Out of curiosity, I decided to see how easy it is to get FTP details over the phone. I visited the site of a local company (who shall remain nameless) and found the name of their design company (who shall also remain nameless). I then phoned the local company and told them I was with the design company and needed them to send me the site's FTP details. They agreed without question or hesitation. Scary. (I told them what I was doing before they sent any sensitive data to me and they are now better educated and suitably paranoid about people asking for details over the phone).]</p>

<p>Some will ignore emails from people pointing out security problems (in the process of writing the previous article in this series, I found a large selection of sites with publically available database connection scripts. I emailed the owners explaining why they are at risk, and only one has replied and had the problem fixed at the time of writing). Admitedly, many of the emails and calls they receive will be misinformation or sales pitches, but it is still worth them having someone check this out - they do not know enough to distinguish a genuine problem from the rest.</p>

<p>Unfortunately, this is one security problem that cannot be solved with code. This one requires education. For this reason, I have created an unbranded copy of the sheet I give to my clients, with a selection of security tips on. When we launch the site, I sit down with them and tell them how they need to treat their site, and what to consider when making decisions regarding it.</p>

<p><a href="content/writing-secure-php-3/client_security.png">Client Security Handout</a> (PNG, 74KB)</p>

<h3>Code Injection (a.k.a. "Cross-Site Scripting")</h3>

<p>Unlike SQL Injection, which relies on the use of delimiters in user-input text to take control of database queries, code injection relies on mistakes in the treatment of text before it is output. Or, to put it in simpler terms, code injection is where a malicious user uses a text box to add HTML that they've written to your webpage.</p>

<p>Let's say you have a system that allows users to register as members to your site and that they are allowed to create their own username. They fill out a form, and you insert the data they enter, once you've made it safe to use in a SQL query, into a database. Your members listing page fetches all the usernames from the database and lists them, outputting exactly what is in the database to anyone that views that page.</p>

<p>Now, let's say you've not added a limit to username lengths. Someone could, if they wanted, create a user with the following username:</p>

<pre class="php">Username&lt;script type="text/javascript" src="http://www.website.com/malicious.js"&gt;&lt;/script&gt;</pre>

<p>Anyone that then views a page with that username on it will see a normal username, but a JavaScript has been loaded from another site invisibly to the user.</p>

<p>There are plenty of uses for this. First and foremost, it allows attackers to add keyloggers, tracking scripts or porn banners on your site, or just stop your site working altogether. There are several ways to ensure this doesn't happen. First, you could encode HTML in usernames. If you wanted to allow people to use greater-then and less-than signs in their usernames, that is. If not, you can strip these characters out, or strip out HTML tags altogether.</p>

<p>Another, better way to approach this is to limit the character set that can be used in usernames. If you only allow letters and numbers, for example, you could simply use a regular expression in the signup process to validate the username and force the user to pick another if they have disallowed characters in their username. Obviously the problem is not just applicable to usernames - however, as with most other security concerns, being quite paranoid will ensure that you always check data coming from a user before outputting it, and sanitising it in an appropriate way.</p>

<h3>Aftermath</h3>

<p>Part of a good security strategy is the assumption that at some point everything (and I mean everything) will be deleted or destroyed. It is wise to assume that at some point any security measure you have in place will be compromised. All data may be taken (which is one reason why it is important to encrypt things like passwords and credit card numbers in databases), all files deleted and so on.</p>

<p>One part of PHP development, though perhaps not directly about PHP security, is ensuring that after a catastrophic failure a site can be brought back online quickly. While downtime of four hours maybe acceptable with a low-traffic point-of-presence site, any ecommerce retailer is going to erupt with fury at the thought of that much lost revenue.</p>

<p>Dealing with the client under these circumstances is the first step. Often, your first inkling of a problem with a site may actually come from the client. They may have phoned you and could be angry, worried, or a myriad of other emotions. At moments like this, you would be very glad to have a clear contigency plan in place. Many developers panic when the client phones saying their front page has been defaced. Stick to your action plan and to your client you will seem confident and unphased. That will relax them. The plan will also allow you to resolve the problem far faster.</p>

<p>First, find out what happened. Are you dealing with a security breach or has someone at the host company tripped over a power lead? Was the database compromised, or deleted, as a result of an attack or was your server simply unable to cope with too much traffic? You need to know what has happened in order to deal with it - a site going offline could be down to too many factors to just assume it is a security problem.</p>

<p>Assuming this is a security problem, the next step is to reassure the client. Let them know what has happened. If someone got into the database, no problem - all sensitive data is encrypted. If they've uploaded files to your server (quite possible), you'll have to delete all files and restore from a backup.</p>

<p>You've got to find out how the attacker broke into your system. Check log files, if you have access to them. Also, have a look at hacker and cracker web sites - many of them will list successful attacks against servers by various groups (these are often what are sometimes known as "script kiddies" - not hackers as such, but usually exploiting vulnerabilities found by others). You may well find your site listed and that listing will give you invaluable information. Look at other sites brought down by the same group at around the same time - you will often spot a theme (e.g. all sites that have been attacked were running the same version of <a href="http://www.microsoft.com/WindowsServer2003/iis/default.mspx">IIS</a> or <a href="http://www.apache.org">Apache</a>, were all running <a href="http://www.phpbb.com">phpBB</a>, or all are file repositories running on <a href="http://www.macromedia.com/v1/cfdocs/cfml_language_reference/contents.htm">CFML</a>).</p>

<p>If you are running any third party software on the site, check the distribution site and if necessary get in touch with them, especially if other sites running the same software appear to have been compromised.</p>

<p>It is very important that you fix any hole there may be before you restore the site. It would be wise to add a "We are currently undergoing essential maintenance" page, but do not fully restore the site before you have found out and fixed whatever the problem was - you'll be wasting your time.</p>

<h3>Shared Hosting</h3>

<p>Shared hosting is much cheaper than dedicated hosting, and is where several sites are all hosted on the same server. Most sites are hosted this way, and this brings with it its own set of security issues.</p>

<p>First and foremost, the security of your site is, in these circumstances, almost entirely out of your hands. It is dependant on the hosting company you are with. They may be excellent, or they may be crooks. Check reviews of a company before you select them, as they will have access to all the data you store with them. There is no harm in being automatically suspicious of your hosting company.</p>

<p>If they are completely above board (and most are), you are still not necessarily secure with shared hosting. The security measures they put in place are generally pretty simple. Shared hosting servers should always use PHP's safe mode (which disables many of the more advanced and dangerous features of PHP). That is what it is there for. However, many don't.</p>

<p>Vulnerabilities associated with shared hosting are, for the most part, out of your hands. A badly set up server will allow any site on that server to access files like /etc/passwd and httpd.conf, often giving them access to all other sites on the same server. It is possible to secure yourself to some degree against the effects of this vulnerability. Storing information in a database is recommended. Of course, if you then store your database login in a file, an attacked could access this information. In order to make this inaccessible to others on the same server, you could set database login information within the httpd.conf file, using environmental variables (you will need to ask your host company to add the lines to the httpd.conf file).</p>

<p>Better yet is to ensure that your host, if shared, uses safe mode. While this is still not 100% secure (nothing is), it does help make these attacks more difficult. A dedicated server is another, far better, option, but the expense may be prohibitive.</p>

<p><em>Ready for more? Try <a href="http://www.addedbytes.com/security/writing-secure-php-4/">Writing Secure PHP, Part 4</a>.</em></p> <br><br>]]></description>
				<pubDate>Wed, 27 Jul 2005 09:58:00 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/articles/writing-secure-php/writing-secure-php-3/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=guide&amp;start=0" class="ditto_tag" rel="tag">guide</a>,<a href="/feeds/tag-feed/?tags=php&amp;start=0" class="ditto_tag" rel="tag">php</a>,<a href="/feeds/tag-feed/?tags=programming&amp;start=0" class="ditto_tag" rel="tag">programming</a>,<a href="/feeds/tag-feed/?tags=security&amp;start=0" class="ditto_tag" rel="tag">security</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdev&amp;start=0" class="ditto_tag" rel="tag">webdev</a>,<a href="/feeds/tag-feed/?tags=work&amp;start=0" class="ditto_tag" rel="tag">work</a>
			</item>

			<item>
				<title>Writing Secure PHP, Part 1</title>
				<link>http://www.addedbytes.com/articles/writing-secure-php/writing-secure-php-1/</link>
				<description><![CDATA[ Learn how to avoid some of the most common mistakes in PHP, and so make your sites more secure. <p><a href="http://www.php.net">PHP</a> is a very easy language to learn, and many people without any sort of background in programming learn it as a way to add interactivity to their web sites. Unfortunately, that often means PHP programmers, especially those newer to web development, are unaware of the potential security risks their web applications can contain. Here are a few of the more common security problems and how to avoid them.</p>

<p>[Writing Secure PHP is a series. <a href="http://www.addedbytes.com/php/writing-secure-php-2/">Part 2</a>, <a href="http://www.addedbytes.com/php/writing-secure-php-3/">Part 3</a> and <a href="http://www.addedbytes.com/php/writing-secure-php-4/">Part 4</a> are currently also available.]</p>

<h3>Rule Number One: Never, Ever, Trust Your Users</h3>

<p>It can never be said enough times, you should never, ever, ever trust your users to send you the data you expect. I have heard many people respond to that with something like "Oh, nobody malicious would be interested in my site". Leaving aside that that could not be more wrong, it is not always a malicious user who can exploit a security hole - problems can just as easily arise because of a user unintentionally doing something wrong.</p>

<p>So the cardinal rule of all web development, and I can't stress it enough, is: <strong>Never, Ever, Trust Your Users</strong>. Assume every single piece of data your site collects from a user contains malicious code. Always. That includes data you think you have checked with client-side validation, for example using JavaScript. If you can manage that, you'll be off to a good start. If PHP security is important to you, this single point is the most important to learn. Personally, I have a "PHP Security" sheet next to my desk with major points on, and this is in large bold text, right at the top.</p>

<h3>Global Variables</h3>

<p>In many languages you must explicitly create a variable in order to use it. In PHP, there is an option, "register_globals", that you can set in php.ini that allows you to use global variables, ones you do not need to explicitly create. </p>

<p>Consider the following code:</p>

<pre class="php">if ($password == "my_password") {
    $authorized = 1;
}

if ($authorized == 1) {
    echo "Lots of important stuff.";
}</pre>

<p>To many that may look fine, and in fact this exact type of code is in use all over the web. However, if a server has "register_globals" set to on, then simply adding "?authorized=1" to the URL will give anyone free access to exactly what you do not want everyone to see. This is one of the most common PHP security problems.</p>

<p>Fortunately, this has a couple of possible simple solutions. The first, and perhaps the best, is to set "register_globals" to off. The second is to ensure that you only use variables that you have explicitly set yourself. In the above example, that would mean adding "$authorized = 0;" at the beginning of the script:</p>

<pre class="php">$authorized = 0;
if ($password == "my_password") {
    $authorized = 1;
}

if ($authorized == 1) {
    echo "Lots of important stuff.";
}</pre>

<h3>Error Messages</h3>

<p>Errors are a very useful tool for both programmer and hacker. A developer needs them in order to fix bugs. A hacker can use them to find out all sorts of information about a site, from the directory structure of the server to database login information. If possible, it is best to turn off all error reporting in a live application. PHP can be told to do this through .htaccess or php.ini, by setting "error_reporting" to "0". If you have a development environment, you can set a different error reporting level for that.</p>

<h3>SQL Injection</h3>

<p>One of PHP's greatest strengths is the ease with which it can communicate with databases, most notably <a href="http://www.mysql.com">MySQL</a>. Many people make extensive use of this, and a great many sites, including this one, rely on databases to function.</p>

<p>However, as you would expect, with that much power there are potentially huge security problems you can face. Fortunately, there are plenty of solutions. The most common security hazard faced when interacting with a database is that of SQL Injection - when a user uses a security glitch to run SQL queries on your database.</p>

<p>Let's use a common example. Many login systems feature a line that looks a lot like this when checking the username and password entered into a form by a user against a database of valid username and password combinations, for example to control access to an administration area:</p>

<pre class="php">$check = mysql_query("SELECT Username, Password, UserLevel FROM Users WHERE Username = '".$_POST['username']."' and Password = '".$_POST['password']."'");</pre>

<p>Look familiar? It may well do. And on the face of it, the above does not look like it could do much damage. But let's say for a moment that I enter the following into the "username" input box in the form and submit it:</p>

<pre class="php">' OR 1=1 #</pre>

<p>The query that is going to be executed will now look like this:</p>

<pre class="sql">SELECT Username, Password FROM Users WHERE Username = '' OR 1=1 #' and Password = ''</pre>

<p>The hash symbol (#) tells MySQL that everything following it is a comment and to ignore it. So it will actually only execute the SQL up to that point. As 1 always equals 1, the SQL will return all of the usernames and passwords from the database. And as the first username and password combination in most user login databases is the admin user, the person who simply entered a few symbols in a username box is now logged in as your website administrator, with the same powers they would have if they actually knew the username and password.</p>

<p>With a little creativity, the above can be exploited further, allowing a user to create their own login account, read credit card numbers or even wipe a database clean.</p>

<p>Fortunately, this type of vulnerability is easy enough to work around. By checking for apostrophes in the items we enter into the database, and removing or neutralising them, we can prevent anyone from running their own SQL code on our database. The function below would do the trick:</p>

<pre class="php">function make_safe($variable) {
    $variable = mysql_real_escape_string(trim($variable));
    return $variable;
}</pre>

<p>Now, to modify our query. Instead of using _POST variables as in the query above, we now run all user data through the make_safe function, resulting in the following code:</p>

<pre class="php">$username = make_safe($_POST['username']);
$password = make_safe($_POST['password']);
$check = mysql_query("SELECT Username, Password, UserLevel FROM Users WHERE Username = '".$username."' and Password = '".$password."'");</pre>

<p>Now, if a user entered the malicious data above, the query will look like the following, which is perfectly harmless. The following query will select from a database where the username is equal to "\' OR 1=1 #".</p>

<pre class="sql">SELECT Username, Password, UserLevel FROM Users WHERE Username = '\' OR 1=1 #' and Password = ''</pre>

<p>Now, unless you happen to have a user with a very unusual username and a blank password, your malicious attacker will not be able to do any damage at all. It is important to check all data passed to your database like this, however secure you think it is. HTTP Headers sent from the user can be faked. Their referral address can be faked. Their browsers User Agent string can be faked. Do not trust a single piece of data sent by the user, though, and you will be fine.</p>

<h3>File Manipulation</h3>

<p>Some sites currently running on the web today have URLs that look like this:</p>

<pre class="php">index.php?page=contactus.html</pre>

<p>The "index.php" file then simply includes the "contactus.html" file, and the site appears to work. However, the user can very easily change the "contactus.html" bit to anything they like. For example, if you are using <a href="http://www.apache.org/">Apache</a>'s mod_auth to protect files and have saved your password in a file named ".htpasswd" (the conventional name), then if a user were to visit the following address, the script would output your username and password:</p>

<pre class="php">index.php?page=.htpasswd</pre>

<p>By changing the URL, on some systems, to reference a file on another server, they could even run PHP that they have written on your site. Scared? You should be. Fortunately, again, this is reasonably easy to protect against. First, make sure you have correctly set "open_basedir" in your php.ini file, and have set "allow_url_fopen" to "off". That will prevent most of these kinds of attacks by preventing the inclusion of remote files and system files. Next, if you can, check the file requested against a list of valid files. If you limit the files that can be accessed using this script, you will save yourself a lot of aggravation later.</p>

<h3>Using Defaults</h3>

<p>When MySQL is installed, it uses a default username of "root" and blank password. SQL Server uses "sa" as the default user with a blank password. If someone finds the address of your database server and wants to try to log in, these are the first combinations they will try. If you have not set a different password (and ideally username as well) than the default, then you may well wake up one morning to find your database has been wiped and all your customers' credit card numbers stolen. The same applies to all software you use - if software comes with default username or password, change them.</p>

<h3>Leaving Installation Files Online</h3>

<p>Many PHP programs come with installation files. Many of these are self-deleting once run, and many applications will refuse to run until you delete the installation files. Many however, will not pay the blindest bit of attention if the install files are still online. If they are still online, they may still be usable, and someone may be able to use them to overwrite your entire site.</p>

<h3>Predictability</h3>

<p>Let us imagine for a second that your site has attracted the attention of a Bad Person. This Bad Person wants to break in to your administration area, and change all of your product descriptions to "This Product Sucks". I would hazard a guess that their first step will be to go to http://www.yoursite.com/admin/ - just in case it exists. Placing your sensitive files and folders somewhere predictable like that makes life for potential hackers that little bit easier.</p>

<p>With this in mind, make sure you name your sensitive files and folders so that they are tough to guess. Placing your admin area at http://www.yoursite.com/jsfh8sfsifuhsi8392/ might make it harder to just type in quickly, but it adds an extra layer of security to your site. Pick something memorable by all means if you need an address you can remember quickly, but don't pick "admin" or "administration" (or your username or password). Pick something unusual.</p>

<p>The same applies to usernames and passwords. If you have an admin area, do not use "admin" as the username and "password" as the password. Pick something unusual, ideally with both letters and numbers (some hackers use something called a "dictionary attack", trying every word in a dictionary as a password until they find a word that works - adding a couple of digits to the end of a password renders this type of attack useless). It is also wise to change your password fairly regularly (every month or two).</p>

<p>Finally, make sure that your error messages give nothing away. If your admin area gives an error message saying "Unknown Username" when a bad username is entered and "Wrong Password" when the wrong password is entered, a malicious user will know when they've managed to guess a valid username. Using a generic "Login Error" error message for both of the above means that a malicious user will have no idea if it is the username or password he has entered that is wrong.</p>

<h3>Finally, Be Completely and Utterly Paranoid</h3>

<p>If you assume your site will never come under attack, or face any problems of any sort, then when something eventually does go wrong, you will be in massive amounts of trouble. If, on the other hand, you assume every single visitor to your site is out to get you and you are permanently at war, you will help yourself to keep your site secure, and be prepared in case things should go wrong.</p>

<p><em>Ready for more? Try <a href="http://www.addedbytes.com/security/writing-secure-php-2/">Writing Secure PHP, Part 2</a>.</em></p> <br><br>]]></description>
				<pubDate>Fri, 16 Jul 2004 10:07:15 +0100</pubDate>
				<guid isPermaLink="false">http://www.addedbytes.com/articles/writing-secure-php/writing-secure-php-1/</guid>
				<dc:creator>Dave Child</dc:creator>
				<a href="/feeds/tag-feed/?tags=code&amp;start=0" class="ditto_tag" rel="tag">code</a>,<a href="/feeds/tag-feed/?tags=coding&amp;start=0" class="ditto_tag" rel="tag">coding</a>,<a href="/feeds/tag-feed/?tags=development&amp;start=0" class="ditto_tag" rel="tag">development</a>,<a href="/feeds/tag-feed/?tags=mysql&amp;start=0" class="ditto_tag" rel="tag">mysql</a>,<a href="/feeds/tag-feed/?tags=php&amp;start=0" class="ditto_tag" rel="tag">php</a>,<a href="/feeds/tag-feed/?tags=programming&amp;start=0" class="ditto_tag" rel="tag">programming</a>,<a href="/feeds/tag-feed/?tags=security&amp;start=0" class="ditto_tag" rel="tag">security</a>,<a href="/feeds/tag-feed/?tags=tips&amp;start=0" class="ditto_tag" rel="tag">tips</a>,<a href="/feeds/tag-feed/?tags=tutorial&amp;start=0" class="ditto_tag" rel="tag">tutorial</a>,<a href="/feeds/tag-feed/?tags=web&amp;start=0" class="ditto_tag" rel="tag">web</a>,<a href="/feeds/tag-feed/?tags=webdesign&amp;start=0" class="ditto_tag" rel="tag">webdesign</a>,<a href="/feeds/tag-feed/?tags=webdev&amp;start=0" class="ditto_tag" rel="tag">webdev</a>
			</item>
	</channel>
</rss>