Sunday, 5 November 2017

Ruminations of a 40-year old Geek

Lordy, Lordy, look who's forty!

Yep, that one was plagiarized from Silicon Valley Season 4, but it seems particularly apt.

His Teochewness turns 40 today, and would like to expound on a very pertinent topic in the tech industry - aging. Or rather, aging developers. If I told you I didn't feel the effects, that would be a big fat lie. I didn't become an old fart overnight - these effects have been creeping up over the past few years.

Overall Health

For the longest time since 2008, I had not been taking sick leave. I'd been running on a heady mixture of sunlight, cigarettes and Teochew arrogance. That record was broken last year, and this year. That's two times in two years after a period of eight years. The illusion that I'm made of iron is long gone, and I feel just as fragile as every other schmuck on this planet.

My joints are stiff. My teeth feel weak. If I sit too long, my legs fall asleep and my back and neck start to whine. My cholesterol level is ambitiously scaling new heights, and my digestive system just isn't what it used to be. Come to think of it, my appetite isn't what it used to be. Buffets? Forget it, sunshine.

And I'm not even going to go into detail about the severe discomfort that occurs whenever it gets cold.

Yeah bro,
it's like that.

On the bright side, I look pretty good without my clothes on. Pretty good for a 40-year-old, that is. This ain't no Manhunt torso, but damn if it isn't finer than what the average 30-year-old has to offer. Too bad looking good is just about the only thing this aging body does well these days. Seriously, what's the point of having abs if your stomach can't digest the sinfully greasy and spicy stuff without complaining? Or having nicely toned legs if your goddamn knees creak every time you walk too fast?

Oh, you think I might be exaggerating just a wee bit? We'll talk again when you turn 40.


Fatigue

Another thing about getting to this age, is decreasing energy levels. I get tired a lot more easily than I used to, and it shows. And with this development, changes to the lifestyle are in order.

Energy levels: down.

No more late nights out. You want to spent all night drinking beer and reminiscing? Sorry buddy, you're out of luck. Don't call after 10pm, I ain't picking up. Even an wrinkled old bastard like me needs his beauty sleep.

Vastly reduced overtime in the office. I get my shit done, and leave. Around 6pm, my concentration drops off noticeably and it's all I can do to keep my eyes open. That's a stark contrast to five years ago, when I was still pulling twelve-hour workdays and getting in the office on weekends and public holidays. Now if I stay back and keep working past 7pm, the first thing I'm gonna be doing next morning is undoing all the shit code I wrote last evening. That helps no one.

No more outside projects. These used to be ways to supplement my miserable income, but lately I've been declining all offers. While anti-moonlighting clauses are a staple in almost all employment contracts, they're almost impossible to enforce with freelance projects. But freelance projects take - you guessed it - energy. Energy I don't have. The fact that my income is no longer miserable (maybe even excessive now) doesn't hurt.

And especially - no more losing my temper. Sure, I still get annoyed from time to time. But explosive bursts of angst are a thing of the past now. People say this is due to maturity. A sign of me staying above it all.

If only.

No, this is due to a dwindling supply of energy, and when you're dealing with a limited supply of anything, you tend to want to make it count. That means no more unproductive energy-sapping activities like flame wars, Internet arguments or even offline arguments. It's not even like reacting to some idiot on Social Media would make me feel tired - just thinking about reacting to some idiot on Social Media already makes me feel tired. These days, I'm more than likely to simply agree just so the other party can shut up. Hey, so somebody stays ignorant. So be it. Ain't my job to educate the world. Life's short, and for people like me, it just got a whole lot shorter.

Dude, I'm 40 and statistically, I have another 20 years left, 30 if I'm lucky. If you think I'm going to waste any of it on a pissing contest with some pimply teenage wanker on Social Media, think again.

Attitude

There was a time I felt driven to prove my worth as a professional web developer. Those days are over. It's not so much complacency; instead, it's more about acceptance. I accept that I'm not some hotshot that can walk into any tech firm and instantly land a job. In fact, I'm probably not even in the bottom 25 percentile of tech minds on this island. This isn't humility, either. Again, it's acceptance.

I'm also a lot more zen about underachieving these days. Succeed or fail, life goes on. And if you disagree, feel free to shoot yourself in the head next time you fall short. I'll help document your dramatic gesture on YouTube.


You failed? Die, loser.

Try not giving a shit. It's surprisingly empowering. People are vain, hypocritical, and put a ridiculous amount of effort into projecting some kind of image to the world. This 40-year old dev has neither the time nor the inclination. Being insecure makes you open to manipulation. Fuck all of that.

Surprisingly, though, there are some things I've come to care about more, instead of less. Aging could be making me less gung-ho... or I could be mellowing. What a scary thought. At work, I'm seeing thirtysomethings just as aggressive and driven as I was years ago. And unfortunately, just as stupid about it.

Where I once only cared about getting shit done come hell or high water, getting shit done right has come to matter just as much, if not more. "But it works!" is the layperson's excuse. Guess what - I no longer work for laypeople and therefore, no longer have the luxury of that excuse. Any idiot can write working code - now I have to hold myself to higher standards.

Where I once saw office punctuality as a crutch for people who don't have anything meaningful to contribute, I now see it as a mark of reliability - as in, people can generally count on you to be available in the office by 9pm, not a minute later. Being on time now matters more than staying back in the office or working on weekends. Being reliable has become more important than being the superstar workhorse.

Where I once prided myself on the number of different languages and platforms I've done stuff in, I've come to value team skills more. Communication, usage of code repositories, writing clean readable code. I'm no longer that 30 year old cowboy cop developer, but rather, part of a unit. Besides, very few companies need a developer who's coded in ten different languages - but every company likes their devs to be good at communication and teamwork.



In a wrinkled nutshell (God, that sounds gross)

There's so much you lose as you age. Thankfully, hanging out with younger people helps realize how much I've gained, and hanging out with older people have helped me realized how much I've still got going for me. Perspective - it's underrated.

Many senior regards,
T___T

Sunday, 8 October 2017

TeochewThunder: Year Three (Part 2/2)

As with previous years, some of my posts garnered more... attention than others. The trends have been a little strange, to be honest. On the bright side, readership has gone up. Not phenomenally, but noticeably.

What can I say? Fuck yeah.

These trends!

TeochewThunder's content

Tech News - 2017 has been undeniably the Year of the Trump. The politics of USA be damned, the ramifications of his Presidency has shaken the world - all the way to the tech industry, which in principle, should be free of such things. But no, the ongoing war between the Left and the Right has been fought on many levels, much of it on Social Media. Consequently, it's spawned a few posts ruminating on this phenomenon, such as The Misinformation Age, Shopify Stands Steady and more recently, James and the Giant Echo Chamber and A Storm Without A Cloud. Even posts that don't have anything to directly to do with US politics, have references to it peppered here and there. Everywhere I go, there's no escape from Trump, his critics and US politics. Even in tech forums, where I visit to obtain some illumination on code issues, there are the assclowns apologizing for having inflicted Trump on the world. It's bad enough that I have to contend with posts tirelessly raging about Trump or Clinton on my Facebook or Quora feed (thank God I don't have a Twitter account... yet) but on tech forums? Come on, you idiots. Find a safe space and park your buttery asses there. Don't bring that shit into tech!

Ironically, one of the pieces that got the most views was not about the US, but about Singapore. I'm not sure what made Singapore's cyber-defense initiative so interesting, but there you go. Coming a close second was No-show Nodevember, in which I provided my thoughts on Douglas Crockford's exclusion from Nodevember. Again, I'm not sure I understand why this particular piece would hold so much more interest to my readers. Food for thought, eh?

Reviews - This year was also a year of many firsts, at least where Reviews are concerned. The first ever Fiction Review. The first ever non-gaming App Review. The first multi-part review of any kind, namely a Fiction Review and Film Review of The Millennium Series. My repertoire is expanding!

In fact, this year has been pretty heavy on the reviews. Hope no one's complaining!

Web Tutorials - Compared to last year's offerings, this year's web tutorials are a lot less complex, and more varied in nature. Less of the HTML/CSS/JavaScript special effects jazz and more on other platforms, security, and so on. Because variety is the spice of life, and I do like to play with new stuff. It keeps things fun. Also, even the average web developer does not need to know only HTML/CSS and JavaScript. A whole lot of separate components goes into the building of a website or web application. And knowledge of these things, if not expertise, is key.

I like to think the quality of my JavaScript has improved somewhat. Not that most people would notice because traditionally, to my chagrin, web tutorials don't get as many eyeballs as the rest. I work pretty hard on those, dammit!

Miscellaneous content - A fluff piece I wrote on my friend's wedding in the Apple Store was an instant hit despite it basically being rehashed information from a variety of news sites. Other than that, it's mostly very technical stuff that keeps me riveted but bores the living shit out of everyone else.

Some stuff, like Cracking the QBasic Color Code, is not exactly current. I wrote that post ages ago, but never found the time to release it until now. That's also because I have a certain limit I like to observe in blog posts - maximum nine per month. And even that is pushing it. Sometimes tech news gets in the way, and takes priority. So that blog post kept getting pushed into my backlog until last month. Hey, it's not like anybody cares - it's QBasic!

One standout though, is this piece which I wrote last month, a few thoughts on my experience in Singapore Polytechnic. I didn't think it was all that impressive, but someone shared it and the hits started coming. At the time of this writing, it's my most-viewed blogpost to date. I kid you not.


All this writing is hard work.

General writing style

Call it fatigue, but I think the quality of my signature puns has deteriorated. Some days it feels like I'm trying just a little too hard.

I'm also trying to write fewer words. Communicate more with less. It's an ongoing struggle with me because I really tend to pile it on when trying to bring the point across.

Thankfully, my practice of publishing content at least a week after writing it, has worked favorably. There are times when I get carried away trying to present all sides of an issue, or adequately express how strongly I feel about any given issue, and the words chosen are less than ideal. Taking a week to review said content goes a long way in increasing the clarity of the message, reducing clutter and getting the focus just right. Hopefully, I've done better since last year.

That's it!

This concludes the year end report for TeochewThunder. See you again next October. There will be a break for the rest of this month, and posting will resume in November.

Word, yo.
T___T

Thursday, 5 October 2017

TeochewThunder: Year Three (Part 1/2)

Three years.

Three years from the day I finally stopped farting around and just did it - started this blog, set up my website, put myself out there. And every time I put up an anniversary post, I have to thank, of course, Catherine Ling of Caremburu, who got me started on this path. It was then or never. No point waiting till I had enough tech cred. That was how I got tech cred.

Take the plunge!

I wish I could declare it's succeeded beyond my wildest dreams, but let's be real here. This is one tech blog out of millions of tech blogs out there, and it's not even a particularly good one. I'm nobody. Nothing. Zilch. Nada. And that's a good thing because that means nobody cares about what I have to say. In this day and age, caring leads to witch hunts and the end of your private life as you know it.

No, success takes many forms, and in my case, this blog succeeded not once, but twice.

The first time was back in 2016, when the owner of a software startup hired me - after viewing my posts, GitHub account and other things I had shared online.

The second time was earlier this year, when a major tech company interviewed me and commented on my blog during the interview. And then hired me.

In both cases, one could argue that I'd passed the technical interview and was therefore qualified, and my crappy little blog had nothing to do with it at all. Anyone who says that obviously does not understand the industry. Passing a technical interview is the minimum requirement. What a hiring manager looks for is that little extra. Love for your craft. Enthusiasm. And for a web developer, nothing screams enthusiasm like a tech blog, buying your own domain name and a lovingly maintained repository filled with all the code you write after work hours.

Coding after hours.

You see, when hiring a developer at my level, what an employer looks for is return on investment. Let's define quality of a developer as the knowledge he possesses (x) against the entirety of technical knowledge that exists out there right now (y). Someone who loves his work is only going to get better, no matter how much he sucked when you first hired him. Conversely, if you hire someone who checks all the right boxes but fails to convince you that he loves his work enough to keep improving, his value will inevitably go down the moment you hire him. x will be at a standstill, while y is only going to increase.

Also, one could say that in this day and age, not having an online presence is weird. That goes doubly if you're a tech. Triply if you're a web tech.

It's not about the quality of the content. My posts don't boast any stunning insights about the web industry or tech news. They do, however, tell the prospective employer that I bother to keep myself informed. I think about the things I read, and I care enough to formulate an opinion and put it out there. Same for my code. It's not the greatest code in the world. You could take a look and declare that your dog could write better code. Again, it's not about the quality. It's about the amount of love you put into it.

No, I put myself out there, and in an industry where many developers can't even be bothered, that puts me ahead of the pack - a pack that includes developers three times more experienced and proficient than I am. I could be drinking myself silly at a pub after hours. I could be binge-watching TV. Engaging in internet flame wars. Or any other enjoyable but arguably time-wasting activity. Instead, I'm doing this.

Well, that goes for my yearly exercise in defending the existence of this blog...

Next

Let's analyze the greatest hits of 2017!

Thursday, 28 September 2017

War of the Programming Languages

What's the best language for the web?

Is it Java, the Android OS platform's poster boy?

Is it C#, currently Microsoft's darling?

Is it PHP, Python or Ruby? JavaScript, even?

Your guess is as good as mine. Proponents of any language have, and are still, engaging in vigorous debate (I'm trying to be kind here) as to why their language of choice trumps all other languages. On the web, there are ongoing bitter flame wars between fans of Java and C#. C# vs VB. Python vs PHP. And then there's the whole Object-Oriented Programming vs Functional Programming debate. Open-source vs Proprietory. List goes on forever.

This ought to put to rest the myth that techies are ruled by cold, hard logic. Now, if these were some rabid non-techie fanboys screaming about how superior iOS is to Android, that would be infinitely more forgivable. But these are tech people. Why are techies behaving like children, or worse - laypeople?

Watch any of these debaters. They'll bring out all the flaws of other languages, compare it to the amazing awesomeness of their chosen language, and fanboys of all stripes will have a field day - or a hissy fit. And when that happens, I don't see seasoned professionals. I see a bunch of woefully insecure nerds trying to obtain validation in their choices. Heaping disdain on those who choose to do things differently. Scorn. Hostility, even.

To what end? Does this shit make you guys feel clever, or something? Do techies making choices different from yours, somehow threaten you? Has choice of a programming language or platform suddenly become some kind of religion?

There are no blanket solutions

I've repeated this often, because this bears repeating: There are no blanket solutions. Not in many industries, and certainly not in the web industry. As a developer, the greatest disservice you can do to yourself is to willfully and deliberately close your eyes to the possibilities that other platforms and languages bring to the table, and the power they add to your arsenal. There is no programming or scripting language in the world without flaws. Sure, it's good to know the ins and outs of your tools, especially the environments in which they thrive most. But, using it as a justification to use one language to the exclusion of all else, is an exercise in futility. Especially on the web.

At the end of the day, languages are merely tools. Use the correct tool for the correct occasion. Because, as with the Law of the Instrument, when you only know how to use a hammer, pretty soon everything starts looking like a nail. Don't be that kind of developer.

Everything is a nail.

Everyone has invested time, sweat and tears honing their craft. No one wants to feel like they wasted all that effort on learning to use tools that aren't relevant. But no matter how much we'd love to believe in a tech meritocracy where the most objectively superior platform should be dominant, the fact is that things aren't as cut-and-dry as all that.

Some languages, like JavaScript and PHP, came to prominence back then because there weren't many other options, and they've filled their respective niches so well that uprooting them at this point would be more trouble than they're worth. You can't possibly tell people that your chosen language is absolutely superior and expect them not to snigger. There is no absolutely superior language. No such animal exists. Superiority is completely context-dependant.

Also, bear in mind that at the heart of every programming language, is a philosophy. Certain languages enforce certain practices. Certain languages make it a point not to enforce a damn thing. The kind of person you are determines the kind of languages you gravitate towards. There is nothing wrong with any of that. You like what you like. Your choice is perfectly valid, and let nobody tell you different.

It doesn't matter what you know...

Here's another line I'm fond of repeating: It doesn't matter what you know. What matters is what you can do with what you know. It is not your choice of language which you should be obsessing over.

Take PHP, for example. PHP is the go-to whipping boy of nerds who consider themselves "proper" programmers. PHP to scripting languages, is what Donald Trump is to the Presidency of the United States of America. Want to look enlightened? Want to appear clever? Pick on PHP! It's the perfect target. Point out all its flaws, and bemoan the fact that it's even still in use today. Sure, PHP is a badly designed language. Sure, PHP does object orientation poorly. Sure, PHP is a hodge-podge of features that feel tacked on. And yep, PHP enforces bad programming practices through its laxness.

So what?

You know what uses PHP? Flickr, for one. Yahoo! is another. Wikipedia. Goddamn Facebook!

Yes, I know C#, Java and Python have done pretty well too, but this isn't about what others have done using those tools. It's about what you have done using your chosen tools. Using the language of your choice, what have you created that's even half the significance of Flickr, Yahoo!, Wikipedia and Facebook?

Drawing a blank? You've done nothing to champion your chosen language other than talk about it endlessly on the Internet? Hey, this is just a suggestion, but maybe, just maybe, it would be far more productive to STFU, roll up those sleeves and get cracking!

Time to work.

Bjarne Stroustrup said this in his book The C++ Programming Language, and I think it's particularly apt even today.
"There are only two kinds of languages: the ones people complain about and the ones nobody uses."

Or, how about, say, COBOL? What, you've never heard of it and therefore it must not be important? Junior, COBOL has been around since the 1960s, and at the time of this writing, it's still kicking ass in the banking industry. It does more in a day than you've probably ever done in your hipster kiddy-script writing life, and this is not hyperbole.

All I'm saying is, show some respect. The languages you love to rag on, have earned it.

Enough is enough

Dear developers, you're part of an honored tradition that harkens back to the days of Ada Lovelace and the first algorithm. Passion is fine and all, but this empty one-upmanship is beneath you. Stop arguing. Go forth and create.

guys.chillout();
T___T

Thursday, 21 September 2017

Web Tutorial: The Anti-CSRF Token

Today's web tutorial is security-based, and it's one of the most elementary things you should know about when developing web applications.

I will be demonstrating a very simple Cross Site Request Forgery (CSRF) attack, and detailing how to foil it. Most frameworks already include this protection, but I would not recommend relying exclusively upon this protection without at least a rudimentary understanding of how it works.

A CSRF occurs when one party outside of your web application's domain makes a request to your web application, mimicking all the necessary data needed for the request to be processed. If that sounded like gibberish to you, maybe the diagram below will help.

CSRF attack diagram


And if that still doesn't help, no sweat. I'll be walking you through an example.

Take this PHP code. I'm not going to explain every line because that's not the purpose of this tutorial. Basically, this code makes a request to tx.php to return some data.
index.php
<!DOCTYPE html>
<html>
    <head>
        <title>CSRF Test</title>
    </head>
    <body>
        <form method="POST" action="tx.php">
            Show transactions with:
            <select name="ddlTxWith">
                <option value="0">Sundar Pichai</option>
                <option value="1">Mark Zuckerberg</option>
                <option value="2">Steve Jobs</option>
            </select>
            <input type="submit" value="Go">
        </form>
    </body>
</html>


This is what you should see when your server runs it. Here, I'm assuming that the intended user is already logged in. You have a drop-down list with three big names, and clicking the "Go" button will reveal all the transactions you've had with the selected person.


Now, this code defines a multi-dimensional array, simulating some data from a database. It takes the value of the drop-down list submitted, and uses it to grab the required data.
tx.php
<?php
$TxWith = -1;
$TxObj = array();

$Tx = array();
$Tx[0][0] = array("Date"=>"20 May 2010", "Amount"=> 200, "Comments" => "10-course dinner");
$Tx[0][1] = array("Date"=>"5 July 2016", "Amount"=> 10500, "Comments" => "Website fees for Google domain");
$Tx[0][2] = array("Date"=>"18 June 2011", "Amount"=> 50, "Comments" => "Monthy Gmail fee");

$Tx[1][0] = array("Date"=>"10 July 2011", "Amount"=> 660, "Comments" => "Facebook ad registration");
$Tx[1][1] = array("Date"=>"10 September 2011", "Amount"=> 2, "Comments" => "Starbucks coffee");

$Tx[2][0] = array("Date"=>"10 June 2010", "Amount"=> 2500, "Comments" => "Apple design");
$Tx[2][1] = array("Date"=>"12 June 2012", "Amount"=> 1200, "Comments" => "iOS Seminar Booth");
$Tx[2][2] = array("Date"=>"5 August 2015", "Amount"=> 2000, "Comments" => "iPad");

if (isset($_POST["ddlTxWith"]))
{
        $TxWith = intval($_POST["ddlTxWith"]);
        $TxObj = $Tx[$TxWith];
}

?>

<!DOCTYPE html>
<html>
    <head>
        <title>CSRF Test</title>
    </head>
    <body>
        <?php
        if (sizeof($TxObj)>0)
        {
            for ($i = 0; $i< sizeof($TxObj); $i++)
            {
                echo "Date: " . $TxObj[$i]["Date"] . "<br />";
                echo "Amount:  $" . $TxObj[$i]["Amount"] . "<br />";
                echo "Comments: " . $TxObj[$i]["Comments"] . "<br />";
                echo "<br />";
            }
        }
        ?>
    </body>
</html>


So, for example, if you select "Steve Jobs" and click "Go", this is what you get. Yes, I know in the real world, Steve Jobs is not going to pay me $2000 for an iPad (besides, the dude is dead), but I can dream, right?


Here comes the attack!

Now, on a separate folder, which we'll call csrf_attack, let's create index.html. That's right, you don't even need sever-side code to do a CSRF. Scary, huh?
index.html
<!DOCTYPE html>
<html>
    <head>
        <title>CSRF Attack</title>
    </head>
    <body>

    </body>
</html>


OK, there's a blank HTML template right there. How do we know what variables to send? Well, assuming you had an account for that web application in csrf_test, you could view the source and get this...



That's just one way out of a multitude of rather more sophisticated (and automated) methods. I'm just using the most obvious way.

So after that, we use the code! Note that in the action parameter of the form tag, we've set it to submit the request to the site we're attacking. In this case, it's localhost/csrf_test/tx.php.
index.html
<!DOCTYPE html>
<html>
    <head>
        <title>CSRF Attack</title>
    </head>
    <body>
        <form method="POST" action="http://localhost/csrf_test/tx.php">
            <select name="ddlTxWith">
                <option value="0">Sundar Pichai</option>
                <option value="1">Mark Zuckerberg</option>
                <option value="2">Steve Jobs</option>
            </select>
            <input type="submit" value="Go">
        </form>

    </body>
</html>


Open this up in another browser. I'm using Chrome for csrf_test, so let's go with Firefox for csrf_attack.


Now click Go, and you have all the transactions with Sundar Pichai! That's data that you, as an attacker, have no right to. Viewing unauthorized data is damaging enough; imagine if your request actually involved editing, adding or deleting data. Or, if this page actually allowed a user to perform transactions, an attacker could use this to send money from the victim to himself.


Foiling the attack

The recommended way is to use an anti-CSRF token, one that the attacker cannot replicate. You could use a randomly-generated token... or you could use one that has already been provided by you, via PHP's session token.

So do this. It begins a PHP session. Ordinarily, you would already have this code, if the page handled user logins.
index.php
<?php
session_start();
?>


<!DOCTYPE html>
<html>
    <head>
        <title>CSRF Test</title>
    </head>
    <body>
        <form method="POST" action="tx.php">
            Show transactions with:
            <select name="ddlTxWith">
                <option value="0">Sundar Pichai</option>
                <option value="1">Mark Zuckerberg</option>
                <option value="2">Steve Jobs</option>
            </select>
            <input type="submit" value="Go">
        </form>
    </body>
</html>


Add this to the HTML portion. It's a hidden field, with the session id embedded. For extra security, we'll hash it with MD5 encryption.
index.php
<?php
session_start();
?>

<!DOCTYPE html>
<html>
    <head>
        <title>CSRF Test</title>
    </head>
    <body>
        <form method="POST" action="tx.php">
            Show transactions with:
            <select name="ddlTxWith">
                <option value="0">Sundar Pichai</option>
                <option value="1">Mark Zuckerberg</option>
                <option value="2">Steve Jobs</option>
            </select>
            <input type="submit" value="Go">
            <input type="hidden" name="hidCSRF" value="<?php echo md5(session_id()); ?>">
        </form>
    </body>
</html>


View your source. See that hidden field with "f7c6332b0ec5529210f7959a0d304521"in there? That's the MD5 hash of your unique session id.


Now, in tx.php, we'll start a session as well.
tx.php
<?php
session_start();

$TxWith = -1;
$TxObj = array();

$Tx = array();
$Tx[0][0] = array("Date"=>"20 May 2010", "Amount"=> 200, "Comments" => "10-course dinner");
$Tx[0][1] = array("Date"=>"5 July 2016", "Amount"=> 10500, "Comments" => "Website fees for Google domain");
$Tx[0][2] = array("Date"=>"18 June 2011", "Amount"=> 50, "Comments" => "Monthy Gmail fee");

$Tx[1][0] = array("Date"=>"10 July 2011", "Amount"=> 660, "Comments" => "Facebook ad registration");
$Tx[1][1] = array("Date"=>"10 September 2011", "Amount"=> 2, "Comments" => "Starbucks coffee");

$Tx[2][0] = array("Date"=>"10 June 2010", "Amount"=> 2500, "Comments" => "Apple design");
$Tx[2][1] = array("Date"=>"12 June 2012", "Amount"=> 1200, "Comments" => "iOS Seminar Booth");
$Tx[2][2] = array("Date"=>"5 August 2015", "Amount"=> 2000, "Comments" => "iPad");

if (isset($_POST["ddlTxWith"]))
{
        $TxWith = intval($_POST["ddlTxWith"]);
        $TxObj = $Tx[$TxWith];
}

?>

<!DOCTYPE html>
<html>
    <head>
        <title>CSRF Test</title>
    </head>
    <body>
        <?php
        if (sizeof($TxObj)>0)
        {
            for ($i = 0; $i< sizeof($TxObj); $i++)
            {
                echo "Date: " . $TxObj[$i]["Date"] . "<br />";
                echo "Amount:  $" . $TxObj[$i]["Amount"] . "<br />";
                echo "Comments: " . $TxObj[$i]["Comments"] . "<br />";
                echo "<br />";
            }
        }
        ?>
    </body>
</html>


And then we'll add an If conditional block to check if the MD5 hash of your current session id matches the one you sent in the form!
tx.php
<?php
session_start();

$TxWith = -1;
$TxObj = array();

$Tx = array();
$Tx[0][0] = array("Date"=>"20 May 2010", "Amount"=> 200, "Comments" => "10-course dinner");
$Tx[0][1] = array("Date"=>"5 July 2016", "Amount"=> 10500, "Comments" => "Website fees for Google domain");
$Tx[0][2] = array("Date"=>"18 June 2011", "Amount"=> 50, "Comments" => "Monthy Gmail fee");

$Tx[1][0] = array("Date"=>"10 July 2011", "Amount"=> 660, "Comments" => "Facebook ad registration");
$Tx[1][1] = array("Date"=>"10 September 2011", "Amount"=> 2, "Comments" => "Starbucks coffee");

$Tx[2][0] = array("Date"=>"10 June 2010", "Amount"=> 2500, "Comments" => "Apple design");
$Tx[2][1] = array("Date"=>"12 June 2012", "Amount"=> 1200, "Comments" => "iOS Seminar Booth");
$Tx[2][2] = array("Date"=>"5 August 2015", "Amount"=> 2000, "Comments" => "iPad");

if (isset($_POST["ddlTxWith"]))
{
    if (md5(session_id()) == $_POST["hidCSRF"])
    {

        $TxWith = intval($_POST["ddlTxWith"]);
        $TxObj = $Tx[$TxWith];
    }
    else
    {
        echo "You are not authorized to view this data.";
    }

}

?>

<!DOCTYPE html>
<html>
    <head>
        <title>CSRF Test</title>
    </head>
    <body>
        <?php
        if (sizeof($TxObj)>0)
        {
            for ($i = 0; $i< sizeof($TxObj); $i++)
            {
                echo "Date: " . $TxObj[$i]["Date"] . "<br />";
                echo "Amount:  $" . $TxObj[$i]["Amount"] . "<br />";
                echo "Comments: " . $TxObj[$i]["Comments"] . "<br />";
                echo "<br />";
            }
        }
        ?>
    </body>
</html>


Try your code again. See if you can still get all of the transactions with, say, Mark Zuckerberg? There should be no change to the results. It should all be transparent to the user.


Now let's attack again!

Let's grab the code and add it to your index.html. Yes, even the hidden field.
index.html
<!DOCTYPE html>
<html>
    <head>
        <title>CSRF Attack</title>
    </head>
    <body>
        <form method="POST" action="http://localhost/csrf_test/tx.php">
            <select name="ddlTxWith">
                <option value="0">Sundar Pichai</option>
                <option value="1">Mark Zuckerberg</option>
                <option value="2">Steve Jobs</option>
            </select>
            <input type="hidden" name="hidCSRF" value="f7c6332b0ec5529210f7959a0d304521">
            <input type="submit" value="Go">
        </form>

    </body>
</html>


Run it. Then try to get all transactions with Steve Jobs. Bingo! The attacker gets nothing, because tx.php's unique session id for the attacker did not match the one sent in the form!


What if the attacker could get hold of the actual session id that a user is currently using?

Good thinking!

But let's consider this - a useful session id needs to not yet have expired, which means the user in question must still be in an active session. The window to act is pretty small. If the attacker could get that, there would be no need to resort to a CSRF. He'd probably have a far more direct means of attack at his disposal.

So this method is fool-proof?

Nothing's ever 100% fool-proof. But, for that threat level, this is probably adequate.

That's all for today. Good Job(s)!
T___T