Blog

  • OWASP Top 10 2010 – Cheat Sheet

    Here is a two page cheat sheet for the OWASP Top 10 2010.

    OWASP Top 10 2010 Cheat Sheet (100 kb PDF)

    Double side to create a single piece of paper and hand it out to all your developers for free – it’s licensed under a Creative Commons Sharealike with attribution license. Once I’ve had a bit of feedback and I’ve tweaked it a bit, I’ll donate it to OWASP.

    This cheat sheet is an unapologetically developer centric list of things to do right.

    I’ve made it as simple as possible by only including things that I personally know will work with the least amount of (re-)work. Therefore, I have purposely left out all the different alternatives. You can (and probably will) have differing views as how to do it better.

    The cheat sheet assumes the reader knows how to program, use a search engine and thus find OWASP. I might have to change these assumptions.

    I’d love to hear feedback. Comments or e-mail will work fine.

  • Advanced Persistent Threat – risk management by a new name

    I am so sick of APT this and APT that. Advanced Persistent Threats, essentially state sponsored intelligence gathering, are no different to the age old espionage between EADS and Boeing – something that CANNOT be prevented by coining yet another new FUD term like APT. Espionage is at least the second oldest profession in the world, and moaning about whatever APT is called this week is not going to change that. If your CFO wants to leak information to a competitor, there is NO information security system ever built that has or can prevent that level of misconduct.

    Look behind who is promoting APT this time around. Companies that have IT security services and products to sell. I have worked in that industry for over 12 years now. We have enough work without ambulance chasing as part of our marketing plan.

    Remember SOX? Lots of FUD then just like APT today. Lots of “security” (and even non-security) programs designed to bring in so-called SOX compliance – and for what? There were more breaches and losses post SOX compliance than before and its getting worse! Lots of money was wasted on useless programs, and hundreds of millions if not billions of dollars went down the drain for no business return.

    If you ever wondered why business folks are rebelling against PCI DSS (which is actually fairly good), fear factor is to blame. We lose respect every time we yell “fire!” when there’s not even a match’s worth of smoke, and when asked for a solution, we want to bring in a DC-10 water bomber. It’s even worse when we come with a reasonable, cost effective, and long term solution and we can’t do it because of the reasonable expectation it’s just another false alarm.

    Stop doing it! We have plenty of good reasons to do security (properly), and APT is simply not one of them. If you’re going to yell “APT APT APT!” have the courage to talk about solutions and make them workable, effective, financially responsible, and not to just rabbit on about security theatre solutions to sophomoric movie plot threats. I am not diminishing those organizations like the oil and steel industry who are responding properly where they have a real expectation that industrial or state based espionage will occur or has occurred in the past, but responding to APT for 99% of organizations is just a complete WAFTAM.

    I hate APT and all the FUD surrounding it. Scaring the punters is chicken little or crying wolf. Get with the “do something” program. If you’re a news org, instead of talking about folks who got pwned, let’s talk about folks who through good management and effective IT Security programs have survived such “advanced persistent threats”.

    What would I suggest we do about APT? Let’s take it back a step – what would I suggest EVERY firm of more than about 10-20 employees should do. Let’s start at the beginning with:

    IT Security Management 101

    AS/NZS 4360 Standard for Risk Management (1999) and ISO 17799 (now 27000 family) is a great starting point. This stuff is simply not rocket science, any organization no matter what business (charity, big oil, health, military, government, financial, etc) can and should look at what they have today, and start implementing them if they have nothing.

    1. ISMS – Create an Information Security Management System. This requires an effective CSO or a CIO who are a force for change with a mandate to take the opportunity cost out of the equation. Spending money on IT security seems a cost for most orgs, but if you see it has an opportunity to do better, you will succeed. Security is a business enabler and indicator of growth. CIO / CSO’s that choose the negative “no” speed hump path simply don’t get it and should be replaced. However, in all cases, it’s important that the CSO or CIO can force business owners to do the right thing or make the business owners accept the responsibilities and risks of poor security decisions. Most orgs do not have an ISMS, and rarely do CIO’s / CSO’s sit on the board or are effective in any fashion. If the CIO / CSO has responsibility and accountability, but no budget and no power to improve things, resign. There’s no way you can effect substantial change when all software is insecure.
    2. Create and maintain IT security policies, procedures and allocate (and enforce) responsibilities. Someone has to have the power to say “turn that off”. Someone has to know when it’s time to “turn that off”. Someone should have known before hand that certain systems are more likely to end up in the “turn that off” category and have the power and responsibility to do something about it. The best IT security policy I ever saw* was 10 pages long, had less than 500 words (none of which were “don’t”) and 20+ images in it. Staff knew what they had to do and they did it as it worked with human nature rather than just saying “no” or “don’t do this” or “you’ll get the sack”. If your IT Security policies would make Stalin proud, occupies three massive binders, and is gathering dust in a cupboard, you’re doing it wrong.
    3. Create and maintain a global risk register. Start with an Excel spreadsheet if you have to, but most of you should probably go out and acquire one of the many excellent products out there that satisfy the ITIL marketplace.
    4. Create a catalog of all your assets (particularly DATA and the systems that handle that data!) and make sure it’s kept up to date. ITIL related products are your friend here – there’s heaps of asset register products out there, but make sure you register data assets as most are all about physical boxes. Assign all assets a classification and make sure folks know how things with that classification are to be dealt with. I prefer a simple three tiered classification system (public, internal, restricted), but whatever floats your boat. 90%+ of all orgs I deal with do not have any idea of what they are running nor the value of their assets or how they should treat them. I know of one org whose HR system was running on a desktop in a cupboard. Unacceptable. But if you don’t know it, you’re negligent, pure and simple.
    5. Perform a risk assessment of all assets, particularly critical ones. Risk assessments used to be popular, but I haven’t seen any done for a while now. This is a huge mistake. Put the risk assessments and any findings from reviews in there. Track, assign responsibilities and dates, and …
    6. Fix – Assign – Accept. Remediate what you can where it makes sense to do so. This doesn’t mean fix everything, just the things that matter. Insure (risk assign) the truly catastophic outcomes. Accept what’s left.
    7. Security is an enabler! Be treated how you’d like to be treated! Train the business folks and developers in secure requirements and coding. Adopt a SDLC and do it. Get and use a defect tracker. Get and use code control. If you’re doing agile, make sure security is a key deliverable of every single user story / sprint / milestone. Make sure your testers test for abuse cases as well as business cases. Think outside the box and think about your customers when you do your security. Security that doesn’t work is wrong. Security theatre is wrong. A multitude of security features doesn’t mean you’re secure. Do security well, and you’ll win because your customers / clients / users will love you and appreciate the efforts you made to make security transparent, easy and effective.
    8. Expect to keep up with the Joneses. You don’t need to be bleeding edge, but anyone running Lotus Notes from 2001 or IE 6 should put money aside to deal with the cleanup of any lame attack from the last X years. Just because you’re not paying out on cap ex this year doesn’t make you a good manager. Long term, you’re gonna pay. Even out the expenses and roll out new stuff all the time and retire old stuff all the time. Don’t be afraid to run XP, Vista, Linux, Windows 7, and Macs all side by side. You shouldn’t require everyone to use the same XP image from 2003 on modern hardware – that’s just stupid. Keeping up is the cost of using IT and those who update regularly pay less than those who wait. And wait. And then get attacked. Plant and equipment is tax deductible in most tax regimes, so there’s no excuse not to depreciate and retire old crap. It does mean you’ll need to cope with patching and scalable roll outs of new hardware and software. You need this anyway for those zero days.
    9. Get rid of crap that costs a lot to operate. Systems that need patching all the time are doing it wrong. Systems that are attacked all the time because they are insecure should be retired. These systems are not worth supporting. Make the ISVs realize that you only pay for secure software that requires little maintenance. Wean off any supplier who refuses to understand this most basic of requirements. They’ll go out of business, and you’ll save money. Ensure when you buy customized software or have it developed for you that the contract states that the ISV has to fix all security bugs for free and they are responsible for paying for the code reviews and penetration tests to prove that they are secure. That’ll keep the ISVs in line.
    10. Monitor and escalate. No system is perfect. Put in procedures to cope with the horse bolting, but try not to have your entire herd and all their tackle gallop out the stables.
    11. Don’t be a cowboy – do it all the time. A good ISMS is not a “fire once and you’re done”. You can’t buy a product that does it for you. This is a commitment like GAAP is a commitment to financial standards to use the same systems year in year out. Those that forgot this lesson are now paying for APT. I’m not going to justify why you need to do this stuff, it should be obvious.

    This stuff is simply not rocket science. It’s not new. Most well governed orgs already have this in place and have been doing it for a decade or more. The problem is that few orgs are well governed or have any particular driver to do IT Security well. Most CIO’s are untrained in security as they’re often accountants who are brought in to rein in costs – which is a mistake. Most CSO’s lack board presence and have no authority other than to be a speed hump. This has to change. Orgs who grew up overnight (like Google) will get hit –  and hard – by APT.

    I don’t want to hear about APT unless you have a solution to whatever you’re bleating about. If you’re going on about how the script kiddies have all grown up and now do exactly what they did before, but are now bank rolled by intelligence agencies, my question to you is “so what?” If you’re doing IT security and governance right, APT is just so much hot air.

  • GaiaBB: Dog food coming soon

    It’s been a slow haul working on converting all the database access to PDO. There’s just so MUCH crap in there.

    So to keep things moving, I’m going to move www.gaiabb.com to run on the donated OLPCs at my home.

    More details here.

  • Parameter Pollution with JSON

    I’ve been playing around with JSON recently, and I’ve discovered that most JSON implementations allow parameter pollution. This might be obvious to JavaScript experts, it’s not immediately obvious to most folks as JSON is just so much line noise.

    {“varName”:value,”varName”:value2,”varName”:value3}

    In the systems I’ve tried injecting, value3 is the one taken. Now if you have a hand crafted JSON decoder and coupled with a simple validator that only checks the first value, say a simple regex, you’re going to get past validation fairly easily. All the other caveats regarding parameter pollution apply.

    Give it a try the next time you’re doing a gig and see if you can bypass validation and other rules. YMMV.

  • How to migrate to PDO without it hurting… much

    As we saw in the previous article, conversion to MySQLi is an awful lot of work. So let’s move to PDO.

    Step 0. Get PDO working with your database server

    Somewhere along the line, the PHP and MySQL folks decided to not be friends, so even though 99.99% of all PHP scripts require MySQL, in most cases, PDO doesn’t have MySQL support enabled.

    Check that PHP doesn’t already have PDO for MySQL ready to go:

    % php -i | grep -i pdo
    Configure Command =>  '[...snip...]'
    PDO
    PDO support => enabled
    PDO drivers => mysql, sqlite, sqlite2
    pdo_mysql
    PDO Driver for MySQL => enabled
    pdo_mysql.cache_size => 2000 => 2000
    pdo_mysql.default_socket => /tmp/mysql.sock => /tmp/mysql.sock
    pdo_sqlite
    PDO Driver for SQLite 3.x => enabled
    The default socket location is fine for a development workstation, but not so good for a production host. Change php.ini and my.cnf to make it safer, such as /var/run/mysql/mysql.sock
    If your PHP installation doesn’t show the above, whip out the compiler – there’s plenty of articles on the Interweb on how to get PDO and MySQL going. For now, let’s assume PDO and MySQL are good to go.
    Step 1. Conversion
    As in our previous article, it’s very tempting to just go through each file and make a 1:1 change from MySQL to PDO. That is actually a losing scenario.
    1. My non-trivial app has 1853 SQL queries littered through the code. At about 15 minutes to 30 minutes per query, with no test case, that’s about a year’s work with no change to the overall complexity of the app nor any improvements to the overall data architecture. Changing from one to the other is sure to introduce bugs.
    2. GaiaBB only has 13 tables. Using a DAO approach, with a list and search helper method for each (i.e forum list, search forum), that’s 6 * 13 = 78 properly written, tested DAO methods that need to be written from scratch. This is a saving of over 10 months work compared to just getting in there and getting my hands dirty.
    3. I can add security business requirements once to the DAO, such as fine grained access control, input validation, audit, and dirty output sanitization, thus fixing all my access control issues and dirty data issues in the same small piece of code. So each file that is converted to DAO gets more secure with no additional coding

    You’re probably wondering about “dirty output sanitization”. Sanitization is for the weak minded! No seriously, my database is 7 years old. There’s crud in there – I can’t trust it to be safe or good. There’s some nice tools out there like Arshan’s Scrubbr to scan and clean a database, but Scrubbr is not going to be able to decode BBCode and check to see if there’s a nasty [color] based XSS or CSRF attack in there. Additionally, some versions of my software and some buggy versions of MySQL == binary blob crappiness. Blobs coming out sometimes (but not always) need to be stripslashed(). Additionally, some versions of XMB used client side checks to prevent files of the wrong type to be uploaded. I’ve found a JavaScript malicious file in my production database. So it’s worth adding checks so that I don’t serve bad things to folks. You can’t do this if you have 100+ attachment related SELECT statements alone, not without lots of bugs and lots of code. Going the DAO way, means I can do it once, for every single use of the attachment sub-system.

    There’s gotta be a downside.

    It’s not all sunshine and roses. You should not open both a PDO and old style connection to the database for busy servers like mine – it more than doubles the time to serve the average script, the poor little database server gets whacked, and performance will drop.

    In GaiaBB, there’s a significant 7240 lines of shared code read in every single time a script does anything – header.php, functions.php, db.php, validation.php, constants.php, config.php, cache.php, english.lang.php, mail.class.php. So to only open ONE database connection requires these files to be ported to PDO first. But if I convert these files, every remaining single file totalling about 80,000 lines of PHP will also need to be converted.

    So my solution for GaiaBB is to create a side-by-side approach, using kernel.php for converted files instead of header.php. kernel.php includes PDO ready files rather than the old files. This temporarily makes GaiaBB approach the 90,000 line mark, but in the long run, it will allow me to make many of the scripts smaller and more object orientated. Once converted to DAO, I can simply eliminate many security checks within the code of each page, as the DAO will simply throw an exception if you’re not privileged to do something with the data you’re trying to work with.

    So my main piece of advice for you contemplating converting to PDO is to consider your data architecture. The old MySQL way is awful, buggy and insecure. Let’s exterminate it, but instead of standing still for months at a time, add in freebies like access control, audit, input validation and output sanity checking.

  • Converting your PHP app to MySQLi prepared statements

    Okay, you’ve got like a zillion SQL queries in your PHP app, and probably 95% of them have a WHERE clause, and you need to make them safe so people will still download and use your app. Because if you don’t fix your injection issues, I will rain fire on your ass.

    These are the steps you need to take to convert to prepared statements.

    Step 0. PHP 4 is dead. Upgrade to PHP 5

    All of the code in these samples is PHP 5 only. I will be using SPL and MySQLi, which are installed primarily on PHP 5.2.x installations. PHP 4 cannot be made safe, so it’s time to upgrade. This is non-negotiable in my view.

    If you’re using register_globals, you have to stop. Do not use a function to register them for you in PHP 5, it’s time to do proper input validation. This will actually take you longer than converting all your queries to prepared statements.

    To get a handle on this issue, what you need to do is:

    1. Turn on error_reporting(E_ALL | E_STRICT);

    2. Find all isset() and empty() and unless they are actually testing for a variable you’ve set, get rid of them. isset() and empty() are not validation mechanisms, they just hide tainted globals from view

    3. Go to php.ini, and turn register_globals off. It should already be off

    4. If your code has a construct like extract($GLOBALS) or some other mechanism to register globals, get rid of it

    5. php -l file.php. This will give you a first pass which you will need to clean up

    6. Use PHP Eclipse or PDT in Eclipse or the Zend IDE in Eclipse. This will give you warnings if you have uninitialized variables. Go to the properties, and make this into an error. Clean up all uninitialized variables

    7. Start each script like this:

    // Canonocalize
    $dirty_variable = canonicalize($_POST['variable']);
    // Validate
    $variable = validate($dirty_variable);
    // Use the variable
    $stmt = $db->prepare("SELECT * FROM table WHERE id = ?");
    $stmt->prepare("i", $variable);
    $stmt->execute();
    // and finally, if you need to output that sucker:
    echo htmlescape($variable, $locale, $encoding); // $locale is probably 'en', and $encoding is probably UTF-8 or ISO 8859-1

    Obviously, you need to canonicalize – that is make it the simplest possible form. If you have no idea about this extremely important topic, please consult the OWASP Developer Guide. Validation is essential. This replaces isset() and empty() and other mechanisms, with actual validation requirements. If you’re expecting an array of integers, make sure it’s an array of integers! If they have to be in a certain range, make it so. If the validation fails, put up an error message and do not proceed! This stuff is CS101, so please make sure you do this reliably for all variables without exception.

    Step 1. Make sure your hoster has MySQLi

    If your hoster is still running PHP 4, you need to see if they have the ability to run PHP 5. Most likely, your PHP 4 installation will not have ANY prepared statement compatible interface, like MySQLi or PDO. Of course, PDO is PHP 5 only… and it has a cool interesting feature – it emulates prepared statements for those databases that do not have support for it. But that’s for another post.

    How do you check? Use phpinfo(). Create this small file somewhere with a random file name and upload it to your host:

    <?php phpinfo(); ?>

    Run the file, and note if you have the MySQLi interface. If you don’t, you can’t upgrade to prepared statements. It’s time to wage holy war on your hoster to make sure they install PHP 5.2.7 with MySQLi and PDO with MySQL 5 client libs for you … and all your other shared hosting friends.

    Changing over to MySQLi

    The simplest part of this process is to move to MySQLi from MySQL:

    Instead of

    $db = mysql_connect($db…

    You have two choices: stay with functional MySQLi, or move to OO MySQLi. I think the latter is better, but that will be another post.

    $db = mysqli_connect($db..

    Now, this is where it’s important! You MUST check the value of $db for errors before continuing. You probably have this code today, but it’s important to realize that if $db == false, you didn’t get a connection.

    if ( $db == false ) {

    // Print up an error and stop

    }

    Simple Conversion

    You may be tempted to just use the MySQLi extension, and move all your queries to place holder versions. That’s okay, but it can be a lot of work. Trust me, I’ve tried.

    Although it seems like the easiest possible choice, converting MySQL queries to MySQLi’s prepared statements has a couple of issues.

    Gotchya: There’s no easy way to bind lots of results when you use select *

    With MySQL query, fetch_array will simply bind the current result set row to an associative array, and you can access it trivially. Most PHP apps use this data access pattern extensively, like this:

    while ( $row = mysql_fetch_array($query) ) {

    // do some work with $row

    $blah = $row[‘column’];

    }

    Which brings us to the next gotchya:

    Gotchya: There’s no fetch_array()

    I don’t know why MySQLi does not have this most common of all the data access patterns, but it’s a right pain to fix. So let’s get a function to emulate fetch_array, including using anonymous field names as per above.

    Okay, so we’ve decided that MySQLi sucks the proverbials… so in the next article, let’s talk about migrating non-trivial PHP apps to PDO.

  • Howard Schmidt appointed US cyber czar

    Howard Schmidt has been appointed as the US’s cyber czar. The position has been open for months, which is … interesting … considering how vital IT is to the world’s economy and safety.

    Mr Schmidt, if you read this blog entry, please consider the following:

    • Web Application Security is the most pressing need for change. It’s the key to nearly all attacks today, and the least well funded. Help OWASP and others to improve developer education, get the message out to CIOs to apportion their training budgets and remediation efforts accordingly.
    • Be positive not negative. The attackers really don’t care if you “keep your computer up to date”. Let’s work mostly on things that can stop the issue in the first place. The horses have already bolted. Let’s make a better stable and fences so they can’t get out again.
    • Push for real security, not security theatre. Listen to Bruce Schneier, and not the profits of doom that want to sell you useless widgets for billions that do nothing but annoy folks.
    • If you can do any change, the first change has to be removal of indemnity for negligence with software development from licenses and sales. If an ISV doesn’t have a security development lifecycle, doesn’t include secure business requirements, and doesn’t require its developers to be trained in security coding practices, it IS negligent, and must be open to lawsuits. What we have today is not working and must be changed.
  • Web App Sec Predictions for 2010

    Normally at this time of the year, I would talk about the industry’s achievements over the last year.

    None. Zilch. Nada.

    We’re seeing more SQL injection used in real world attacks than ever before. XSS is still with us, and one of the biggest offenders – PHP – has made zero moves to include proper encoding or encoding by default for echo and print, or including a safe by default generic SQL layer that is enabled by default and works with the three or four most common databases (e.g. MySQL). The adoption of PCI seems to have made little difference in the amount or severity of breaches.

    Things like ESAPI, App Sensor and ESAPI WAF are the only true breakthroughs in 2009. But outside of OWASP DC, there’s no love for defences. Hats off to Jeff Williams and the entire ESAPI for * team, Michael Coates, and Arshan for the only true web app security efforts this year.

    So let’s forget about 2009 and move on to 2010.

    • Full disclosure / responsible disclosure / etc has failed (again) to improve security as it always has. We should stop doing it. Nearly every app has at least one or more of the OWASP Top 10 2007 / 2010 issues. It’s like shooting fish in a barrel or using dynamite to fish. Stop wasting time on it and come research how to put in safety by default in every language and framework, starting with woefully insecure frameworks and languages like PHP.
    • Conference presentations about attacks are still getting all the sexy girls and media! Conferences and the media have to stop promoting attacks – it’s irresponsible and wasteful. Let’s start talking about defences instead.
    • No more penetration tests! We have to stop doing penetration tests. They suck at predicting the safety of a system, particularly insider risks. Pen tests have value at mature clients who have done the hard work – an SDLC, secure requirements, secure development, peer reviews, code reviews, and extensive testing. They are a validation of the other security benefits, not as a “my X is bigger than yours” exercise and certainly not absolute proof of security.
    • SDLC’s are still rare in the clients I visit. We need to encourage the adoption of SDLC, and require secure requirements.
    • Agile still needs a lot of security as yet. User Stories still have no space for a security outcome in most environments. It’s hard to code review every milestone let alone every sprint. We as a security community need to do a lot more work here to fit in with the modern development methods in use.
    • Developer training is still in the nascent stage and is the only workable method of producing secure apps by default. I donated my full two day deck to OWASP at the beginning of 2009, but as far as I can tell, it hasn’t been updated or given any love. I hope that can change over the year. Please go here and help make this deck the de facto developer training deck!
    • We have to encourage or even mandate folks who outsource / out task / buy off the shelf software to only allow the acquisition of secure software, with the burden of insecurity firmly on the developer. Laws and licenses that prevent this must be changed as insecure software is not fit for purpose and thus defective. Obviously, there’s a huge difference between accidentally insecure and deliberately insecure software. If you don’t have an SDLC and a security program, an ISV is deliberately insecure and must face the costs of their negligence.
    • Over-reliance on silver bullets (WAFs and so on) is harming the effort to fix the problem. Silver bullets don’t always work, and eventually, you’ll have to do the right thing. I don’t know what we can do here but yell at the sky as the marketing dollars for these things overwhelm that simple message.

    Let’s not waste another year. Let’s get moving on secure defenses, SDLC, R&D in agile technologies, and developer education.

  • Inbox Zero

    It’s Inbox Zero time again. Every year, I do the Inbox Zero thing and archive all my mail (read and unread) on January 1 from the year just gone. I also tell myself it’s time to start following the IZ rules, but … they somehow always fall to the wayside.

    I get a lot more personally addressed e-mail than most folks do, and I don’t have a chance to action every item that needs it. I know I have missed replying to at least 20% of my mail – my bad. To make amends, I will work on replying to the last three months of outstanding mail by the end of the year. But I bet there will be mail that still needs actioning that will be archived.

    Action Required: If you e-mailed me, and not had a reply from me by January 1, please re-send your mail to me after January 1, and mark it REPLY NEEDED in the subject. I have an e-mail rule that flags such messages and I will reply to you.

  • Black Day For Australia

    Today, the Labor Government, pandering to a tiny minority of voters who will NEVER vote for them, will proceed with censoring our Internet.

    Many of these hard right wing “Christian” (who obviously missed the entire point of the New Testament) “voters” (Exclusive Bretheren, etc) do not have computers let alone TV’s or newspapers to be offended by the Internet. Worse still the Bretheren are some of the only people in Australia who are allowed not to vote. And for their vital electoral “support”, we all get censored. WTF!?!

    FUCK NO!

    Today, I start censoring the Internet for Australian Government departments. If your DNS name ends in “.gov.au”, there’s a pretty good chance you’ll not be able to see this site and the other sites I run. E-Mail from .gov.au sites will be delivered to /dev/null. In future works I create, I will make an explicit disallowance preventing Australian Government public servants and contractors from using my materials until the censorship mechanism comes down. I will encourage everyone I know to put up mandatory “.gov.au” filtering. See how you like it when the Internet is useless to you and you have to use personal Internet connections to get anything done.

    I will fight this censorship scheme in every way I can. I will publish mechanisms on how to bypass it. I will encourage people to defeat it, even if they don’t have to. I will campaign against my local ALP member. You’ve made a political activist out of someone who used to just rant about politics around the water cooler. I am not the only one. Labor is doomed for a generation or more by this one heinous act.

    Labor – shame shame shame. I’ve voted for you – stupidly it turns out – for my entire adult life. I’m sorry, but I’ll vote for Donald Duck before I grace your lice ridden corpse with the “1” mark ever again.

    Conroy – he who shall not be named from here on – you have are the Internet’s Public Enemy #1. You have cost Labor the next election, even with the Liberals in complete disarray. Labor cannot ever trusted to govern ever again.