Showing posts with label Steve Jobs. Show all posts
Showing posts with label Steve Jobs. Show all posts

Monday, 13 July 2026

Hiring remote foreigners? Slow your roll, hotshot

"If I allow remote work, I'd be better off hiring programmers in Vietnam."

Sound familiar? Because that is the sound of millions of employers all over the world repeating the same old tired line. If I had a penny every time I heard some small-time Towkay-wannabe mouth off about how they'd save so much money by hiring foreign workers remotely rather than letting local talent work from home, I'd be absolutely rolling in it.

If I had a penny...

If you think this makes me sound dismissive, that's because I am. I am dismissing this line as nothing but bluster and hot air. And sit tight; I'm also about to explain why... in the Singapore context, naturally.

When it makes sense

If it's a huge MNC like, say, IBM, whose head office is in the USA and opening a regional office in Singapore, then yes, it makes total sense. Because they're already doing it. Their hiring and legal infrastructures are made for this. Even if the company is not at the scale of a large corporation, but still a respectable size, it might still make sense. It has to; plenty of these companies are doing it. The alternative is that all of them went nuts at exactly the same time... which is scarily plausible in these crazy times.

A game of expansion.

When hiring is done by the book, the host country (in this case, Singapore) and the remote country (in this case, Vietnam), both have agencies that will handle the legalities. I know because I've worked as an Agency Contractor before. These are absolutely a thing.

And of course, these agencies aren't doing it out of the goodness of their hearts. They're a business; they expect to get paid. This will eat into whatever employers think they're saving by hiring foreign workers, remote or otherwise. But that's OK - even if these tech companies don't save that much per foreign worker they hire, at scale, it tends to add up. Enormously.

When it makes less sense

A tiny tech startup trying to follow in the footsteps of a large corporation without understanding basic realities of scale, is on what I would charitably refer to as a "fool's errand". How many would such a company hire? Five programmers? Maybe ten? Whatever the company saves in wages, is nowhere what a larger company saves when hiring hundreds of these people. And if that pittance actually counts as a win, I would be deeply concerned about the finances of said company.

You sure you can
follow in those
footsteps?

I remember a time when Steve Jobs was considered the man to emulate. He was known to be a bit of an asshole, but he had undeniable talent, and thus he succeeded in spite of being hard to work for, or with. People took it to mean that in order to be as successful as Steve Jobs, one had to be an asshole. The end result was that we had quite a few Jobs-wannabes - basically talentless assholes with big dreams and even bigger mouths.

My point is, imitation may be the highest form of flattery; but for those ill-equipped to carry out said imitation, it becomes a liability quickly.

Also, consider this: any employer who isn't comfortable with employees working remotely on an island as small as Singapore, will be significantly less comfortable with employees working remotely out of Singapore.

If your employer is threatening to stop all this WFH nonsense by hiring more WFH programmers from beyond Singapore's shores, it doesn't take a genius to understand that the math does not quite add up.

When it starts being stupid

And it's at this point, where some employers will go, "Well, I'll just skip the red tape and hire direct from Vietnam, then."

Really? You're going to bypass all the legal and pertinent protections that hiring through the proper channels brings you?

How well do you know your own local employees, much less ones you hire from overseas? Do you know their residential address? And even assuming it's a verifiable genuine address, have you ever tried to navigate Vietnam using just a residential address without any understanding of the local language and conventions?

Pray tell, if the foreign software developer whom you don't know from Adam (or Minh, or Rajasamy) decides to sell your IP to the highest bidder, introduce malware into your code base or do any manner of damaging and illegal acts for profit or simply for amusement, how well do you expect to enforce your legal rights? Remember, they're not operating in Singapore, your home turf. Unlike local employees, these are foreign developers under a different jurisdiction where legal enforcement is already significantly harder - now made even more difficult because, y'know, you so cleverly bypassed the proper channels.

That's just the most extreme cases. Let's consider some less extreme but still very real considerations.

Time zones aren't that big an issue. This being Southeast Asia, assuming the employer is not adventurous (or foolhardy) enough to hire from further abroad, the time differences are off by a couple hours at most - an hour tops in the case of Vietnam. It'll need work, but it can work.

What's arguably a bigger issue, is culture. Just because you are all presumably communicating in English does not mean you speak the same language. Nuance gets lost in translation, especially if you're speaking through a computer screen. Honestly, colleagues have enough problems just communicating face-to-face, in the same culture, in the same language.

Don't cut through
this red tape.

And the most relevant question of all: Why, in the name of all that's right and holy, would anyone put themselves in this position just to save a few thousand bucks a month? Does a company that needs to save that kind of chump change so badly, really inspire confidence in you as an employee?

Anyone old enough to run a business, is too old to be this fucking dumb.

Hiring foreigners isn't foolish inherently. Hiring foreigners remotely isn't either, though significantly riskier. Hiring foreigners remotely without going through the proper channels? Reckless, and potentially illegal. Don't do it.

Conclusion and disclaimer

This is not meant to be any kind of statement against Vietnam. Vietnam absolutely does have a wealth of tech talent at affordable prices. I've worked with quite a few. I was only using Vietnam as a convenient example. I could easily have said Myanmar or India.

My point isn't that employers shouldn't hire foreigners remotely. My point is that it's not something that can just be hand-waved. Employers who have the experience and capability to carry this out, won't be talking about it because they are already - as Nike likes to say - just doing it. Or at the very least, taking cautious first steps. And the ones who are bringing it up casually as leverage during a discussion about remote work, will in all probability continue to just talk.

Your employer is not stupid. But if he's using hiring remote foreigners as a threat, he probably really hopes you are.

Tạm biệt hẹn gặp lại,
T___T

Monday, 9 June 2025

The Dark Years of COVID-19: A Software Developer's Perspective (Part 3/3)

The latter half of 2022 was when the masks came off. In August, it was announced that masking up was no longer mandatory except in medical facilities and food preparation, and on public transport.

It seemed like a small thing, but wow, the sensation of wind on my face after years of this shit was... incredible.

By February of 2024, masks were no longer required on public transport. There was a real sense that this was the last remnants of COVID-19 restrictions being lifted.

Masking no longer
required on public
transport.

Cinemas were allowed to open to full capacity. Swimming complexes and gyms no longer required users to go through a daily booking process, with penalties for no-shows. People tossed their contact tracing tokens. I kept mine around because it was cute.

Large gatherings were allowed again. With that, employers began pushing for a return to office. People started travelling again - ticket prices stopped being ridiculously expensive.

It felt like Singapore, after years of slumber, was starting to wake up once more.

2024 to now

COVID-19 didn't go away. However, it rapidly began to feel like it had become yesterday's news. COVID-19 was no longer the extinction event it had once threatened to be.

As a nation, we took cautious steps on the road to recovery. Some things were never quite the same again. Some businesses folded even after restrictions were lifted. Professionals pivoted to different careers. There was a limit, after all, to how much Government intervention could accomplish.

Mental health and depression.

And for some reason - perhaps this was just my imagination - the issue of mental health seemed to come to the forefront of societal consciousness.  Either the causes of depression predated COVID-19 and this was merely exacerbated due to social distancing and lockdowns, or the long-term effects of having contracted COVID-19 had some effect on brain chemistry.
Because it wasn't just the medical effects of COVID-19. The damage dealt to the economy was not inconsiderable.

Even now, big tech is in the process of laying off all the tech people they snapped up during the dark years of COVID-19. That bubble has burst. It seems especially bad in Silicon Valley, though Singapore is affected as well due to the simple fact that big tech also has offices in Singapore.

As a software developer, I am just profoundly glad that I never hopped on to that gravy train. Sometimes being completely mediocre is a blessing.

Final thoughts

I've said earlier that Singaporeans generally seemed to be becoming alarmingly stupid during the pandemic. Upon further reflection, the truth may have been far worse.

You see, Singaporeans are generally well-educated. We can speak and even write in a variety of languages. We are capable of rational thought. Therefore I find it hard to believe that the average Singaporean would have difficulty understanding the concepts I outlined earlier. No, what Singaporeans suffer from isn't stupidity; rather, it is Main Character Syndrome. The inability to grasp that there are things bigger than them, and that not everything is about them. The inability to get over themselves.

However, for good or ill, this was what the Singapore Government had to work with. It wasn't all bad. Some of us stepped up - some in small ways like myself, some in more substantive ways. We responded as a society, and while there might have been plenty of grumbling as we did it, it is part and parcel of the Singapore DNA. These were heartening signs in what looked like a sea of negativity. On my part, the crists had awakened some kind of social conscience within myself. I wasn't exactly rushing out to the frontlines to offer my aid. I didn't become a Safe Distancing Ambassador or help deliver supplies. I didn't help swab thousands of people a day to test for COVID-19. And I certainly did not participate in helping to write new and interesting software that could help Singapore tide over this crisis. That all said, I gained a new appreciation for how well-run Singapore generally is, and did my small part as a citizen.
Small corner stores.

I spared a few thoughts for my immediate community rather than focus on my own survival. Any money that the Singapore Government disbursed to citizens as aid during this period, I promptly donated to charity. I took pains to patronize small stores and hawkers, as these were the most vulnerable to changes in the economy.
And, despite the fact that I didn't know for sure that vaccination jabs were absolutely safe, I took them.

What does that have to do with a social conscience? You see, Singapore is in a unique situation. The size of this country, with its lack of manpower and natural resources, means that we must open our borders to foreign investment in order to survive. Had we insisted on staying closed, Singapore would have sunk just as surely as if all of us had been overrun by the coronavirus. Sure, we would have sunk slower, but we would have sunk nonetheless. Singapore required at least eighty percent of her citizens to be vaccinated before we could open our borders. There was a chance I could die if I accepted the jab. I took that chance. I will never be great. I'll never be a Bill Gates or a Steve Jobs. I will never cure cancer, create art that will transcend generations, or otherwise achieve anything monumental. But whatever small thing I could do for my country, I did. The jab was never about saving my statistically insignificant life. At the risk of sounding cliche, it was for the greater good. I do value my life... I'm just not vain enough to think it's more important than the millions of livelihoods at stake.

Epilogue

It's 2025. COVID-19 is a distant memory, but not so distant that the turmoil has not left its mark. Now and again, we see some remnant of the measures that were in place during the pandemic. The posters. The tracing tokens. Hand sanitizer. Abandoned gantries.

Remnants of those
dark years.

It's recent enough that any talk of a possible pandemic is instantly compared to COVID-19. Not the Spanish Flu. Not the Red Death, or the Bubonic Plague.

The world seems to have recovered, but the scars run deep.

COVID-19 was nothing to sneeze at, y'all!
T___T

Friday, 3 January 2025

Five Overrated Virtues in the Workplace

Nine years ago, I wrote about the three virtues of a programmer. Having spent some number of years making an honest living as a software developer, I've come across quite a number of virtues that don't make the grade. They are virtues, but only in appropriate doses. In a work setting, focusing on them for their own sake, can lead to ruin.

Be virtuous.

They say you should put yourself into your work. That's a load of baseless claptrap. At work, it pays to not apply many virtues you would to your own life. Because your office is not your home, your colleagues are not your friends, and your employer is not your dad. Unless of course, your office is literally your home, your colleagues literally your only friends and your dad literally is your boss, in which case I can offer you only my sincerest condolences... and an exhortation to make better life choices.

But enough of that! We're here to explore some virtues in the workplace that are not only outdated, but dangerously overrated.

1. Hard Work

Few employers are going to tell you that hard work is a bad thing. That's because hard work isn't a bad thing. In the absence of actual talent, hard work can be your only saving grace. Therein lies the problem; focusing too much or solely on the ability to work hard makes it look like it's your only saving grace.

It's not that being willing to work hard isn't important. It's just that being effective at your job enough that you don't have to work hard, is of significantly greater value. After all, horses and oxen can work hard, too. What separates a hard worker like yourself, from those simple creatures?

Oxen work hard too, so what?

Forget what the older generations tell you about hard work. They were fortunate to exist in a time where actual talent wasn't that big an issue and hard work could provide an honest living. Times are different now. We have automation and robots, and soon we will have AI. No amount of "hard work" is going to overcome the advantage that machines have over human beings.

Ultimately, work is about results. As long as acceptable results are produced, it should not matter if hard work wasn't put in. In fact, the less work the better. Every innovation in the past century has been about reducing work and producing more. 

Unless you enjoy being laughed at, stop talking about hard work to programmers. Hard work is antithetical to the quintessential programmer. Our job, at its core, is to eliminate hard work by automating it.

2. Honesty

Honesty involves telling the truth. And telling the truth is commonly known as a virtue... until it starts to do harm. Remember when Jack Nicholson barked "You can't handle the truth!" to Tom Cruise's character in the thrilling climax to A Few Good Men? He might as well have been saying that to us, the audience. Not everyone can handle the whole unfiltered truth; in fact, most of us can't. Most of us look at facts through certain lenses or perspectives, in order to cope.

The late great Adrian Tan had this to say during a NTU Convocation speech in 2008
Any child can blurt out the truth, without thought to the consequences. It takes great maturity to appreciate the value of silence.


So stop treating honesty like a child would, like it's the be-all-end-all of virtues. Even the truth has context. People who insist on honesty, funnily enough, are often incapable of handling it.

While telling the truth is often a good thing, the truth is also packaged in a way to be useful. What use is the whole unvarnished truth if listeners get confused, offended or otherwise disinclined to listen, and simply discard the entire message? It is not enough to tell the truth. When, where, and how to tell it are equally important, if not more so.

The value of silence.

In effect, it's a matter of knowing when to speak, and what to say. And knowing when to STFU. Many people forget that keeping their damn mouths shut is often also an option.

But yes, to own thineself be true. One should always endeavor to be honest to oneself. To everyone else... exercise discretion.

People like to tell me that they find my frankness refreshing. That's hilarious. Do they even have any idea how much I hold back on a daily basis? If I went for full unfettered honesty every damn time, if I said exactly what I thought every single time, I would have burned every bridge available by now. If people had even an inkling of how little I think of them, they wouldn't find my frankness quite so appealing.

Honesty is one of the most overrated virtues in human history.

3. Loyalty

This next virtue is one that you'll often see employers harp on. Loyalty - the ability to stick with a company no matter how much better conditions are elsewhere. And let's get one thing crystal clear - things can always be better elsewhere and most employers worth their salt aren't unduly worried. It's only when things are often significantly better elsewhere, that's when you hear employers yammer on repeatedly about loyalty.

I say loyalty is overrated. I mean, seriously? Dogs are loyal too. If all you have to contribute is loyalty, what separates you from Man's Best Friend?

You want loyalty?
Get a dog.

While loyalty is overrated, that's not to say it's a bad thing. However, employers have a concerning habit of mistaking a lack of options, for loyalty. Back in the day, employees put their careers at the mercy of their employers and pledged their lifelong loyalty. And in many cases, they were even rewarded in the form of promotions and pensions.

Those times are gone, and they're not coming back. In a world increasingly driven by capability and competence, promoting your longest-serving employee on the basis of duration of service alone, is laughable. It's insane. And when having to restructure in order to save on costs, it would not be sensible practice to retain the longest-serving (and sometimes, also the highest paid) employees purely on sentiment. This goes against business principles. Thus, while employers still say they value loyalty, they're no longer able (or willing) to pay for it and employees should adjust accordingly.

4. Being Right

This next overrated virtue is tangentially related to honesty. And that is, always needing to be right. Not being wrong. Even for a second.

Only machines can't be wrong. If there's ever an instance where they do not produce perfect output, that's because they weren't programmed to do so, or the user did things wrongly. By definition, it's not the machines being wrong. You never, ever, want to be thought of as a machine, or to be held to a machine's standards. Because you're not a machine. That would be akin to a rabbit being held to the standards of, say, a hippo.

I may be biased, but hippos
are way more awesome.

In essence, don't get hung up about being right, or take it personally when your assertions are challenged. Maybe it's just me, but I feel like academics suffer from this an awful lot. Being wrong isn't that big a deal when the lives of millions of people don't hang in the balance over the correctness of your work. And let's face it; in most cases, it doesn't.

Being right all the time should not be the goal. Being right should be an objective to work towards, but the journey to get there should be valued more because that's where you learn the most. You don't learn anything from being right all the time; in fact, it promotes complacency and worse, it introduces fear of change. You don't ever want to try something new because it could be (gasp!) a mistake. You know how many mistakes I've made from the day I wrote my first Hello World program? Countless. Some were minor. Some were embarrassing. And some got me in serious trouble. And by the time this blogpost is published, I'll have made countless more.

Not making mistakes is great. What's even better is the ability to recover and learn from mistakes.

5. Ambition

It's admirable to be driven by a desire to do great things. Ambition has driven many amazing feats. It's given rise to innovations that will echo on through eternity. Steve Jobs is long dead, but he lives on through the iPhone.

Steve Jobs was undoubtedly a visionary, but let's be real. The creation of the iPhone is owed not only to his genius, but to the sweat and tears of thousands of anonymous workers who have their labor to the cause. Without that labor, Jobs could have taken his ideas and basically gone off to fuck himself. What are the chances of you being a Steve Jobs, rather than one of the countless anonymous workers?

The pyramids, similarly, weren't built by a handful of men with great vision and ambition, but by thousands of slaves whose only ambition was to not starve. What are the chances of you being the guy with the whip, rather than one of the many dudes hauling those stones?

Was it only ambition that
built things like these?

The problem is that these days, everyone seems to think that they're destined for some great purpose. They think about their legacy, and want their deeds to leave an echo long after their deaths. Legacy? That's just your vanity talking, buddy. Statistically speaking, you're far more likely to be a schmuck like the rest of us. And having ambition means you will never be OK with that. Which would be fine if your capabilities actually matched your ambition.

Earlier, I talked about speaking the truth. Here's an ugly truth: many think they're special and talented and that the rules don't, or shouldn't, apply to them. They are largely (and tragically) mistaken. Everyone's unique in some way, but not enough to move the needle in that regard.

The problem with wanting to be remembered long after your death, is that not everyone can be Albert Einstein and make great scientific inventions. Not everyone can perform feats of supreme athleticism like Usain Bolt. The vast majority of us are painfully average. That's how averages work. (More medians if we wanted to be pedantic about it)

But the Internet and Social Media somehow make people feel like they should be able to make themselves memorable. More often than not, they end up going through life being bitter and feeling like failures... because they couldn't reach those largely imaginary lofty heights.

All things in moderation!

There's no doubt that the five things I listed above are virtues. However, they're overrated. Some way overrated. It can't hurt to practice some (or even all) of these, but make them a selling point of your professionalism at your own peril.

Remember, programmers. Evolution is a constant in our industry. This does not just apply to tech; it applies to the virtues you display in the workplace.

Stay virtuous,
T___T

Thursday, 14 September 2023

Ten Awesome Tech Tattoos

Tattoos are a common sight in society these days. I recently saw a nice tattoo on some random middle-aged housewives, and then it hit me: it's not that housewives are suddenly finding it hip to ink their bodies. It's more like these were the rebellious teenagers from a couple decades back, now all grown up and shit. Heck, I'm no spring chicken. But that's neither here nor there.

Tech tattoos, on the other hand, should really occupy their own niche. The ones I managed to find in cyberspace are clever, quirky and just awesome.

1. Stay Hungry, Stay Foolish

We begin with a nice nod to the late great Steve Jobs. This is one of his more well-known quotes.

From IJustWanaShine.

Now I'm not a big fan and this isn't anything I would ever do. But come on, this is classy. And inspirational, to boot.

2. HTML Code

For all web devs out there, this is not just HTML code, it's a clever pun!

From Lambatest


It would actually take someone in the know to appreciate that joke; however, it's relatively easy to implement. Again, not one of those things I would totally do, but I appreciate the intent.

3. Linux Command

For those familiar with Linux, this line basically means "recursively delete all files and directories without asking for confirmation". In other words, remove everything without regret.

From louiseann93

The sentiment behind simplifying your life is one I can get behind. The fact that this dude has it inked into his forearm gave me pause. Is he saying he can remove your life with one punch?

4. Binary

This guy has his name "MIKE" tattooed in binary.


From TattooViewer

Not a bad idea, but if you had a seriously long ass name, that might present a problem.

5. 404

Nothing to see here, move along. That's the message I got.

From Pinterest

The woman in question has it on her bosom. It could be her way of saying "my eyes are up here", but it might just send a cheekier message. Like, "titsheart not found".

6. More Binary!

Ooh! Now this one is nice. Not only is it binary, it's taking the shape of one of my favorite childhood memories!

From Tattoodo

Plus, it's in monochrome. I love tats like that.

7. Paper Clip

This is another memory, albeit not quite so fond.

From
JavaScript in Plain English

If anyone ever had the misfortune of using Microsoft Word when it was featuring this annoying little mascot, they'd know what I'm talking about. It's a nice idea, but I can't see myself wanting this fella be a permanent part of me.

8. Docker

Now this is dedication. Is it a DevOps thing to ink the whale icon of Docker in their skin? That's amusing.

From Twitter

Then again, I have Liverpool FC's motto inked into my knuckles, so who am I to talk?

9. WiFi

I appreciate anyone who has the WiFi icon tattooed on them. Not that they can actually provide WiFi, but they can at least relate to its importance.

From Tattoodo

This fella has it on his middle finger. I can just imagine someone asking him for WiFi, and his response...


10. IBM

Again, dedication. This time, to a tech company. Honestly, I'm not totally behind this one. Unless you own the company in question, this just seems superfluous to me. Companies are where you work and get paid, and after you're gone from there, you're gone.

From Flickr

In addition, if I had to pick an IBM tattoo, I would not have gone for this one. I would have gone for the far cleverer rebus option. An eye, a bee and an M.

Conclusion

There you go, folks! Ten cool (and some not that cool but nevertheless thought-provoking) tech tattoos. Any strike your fancy?

I ink, therefore I am,
T___T

Saturday, 28 December 2019

Here's Why You Shouldn't Take Tech Career Advice From Your Friends

During the last Chinese New Year, I got this link in my news feed, an article from Robert Half, a recruitment agency. It caught my eye for the wrong reasons. Something about this article struck me as extremely problematic.

If you’re not sure where you want your career to go, don't be afraid to seek help. Ask friends and family over Chinese New Year for their advice.


Really? I call bullshit.


Surround yourself with friends...
but don't take their advice. Because
their advice sucks.

Friends are good things to have. They hang out with you when company is needed, they usually find the same things funny, and they listen when you need to rant. But friends are not infallible (big surprise, huh?) and when you need advice, sometimes they fall short. I don't mean they run out of advice; advice is primarily opinion-based, and if it's one thing human beings rarely run out of, it's opinions. I'm going to be really blunt here and say this - don't listen to your friends. Especially when it comes to a tech career. Your friends don't know shit. This goes for your parents and your siblings as well.

Now let's just be unambiguously clear about one thing. I'm laboring under the assumption that your friends care, and only want the best for you. They honestly are telling you what they think is the best way to go. They're not jealous of you, or trying to sabotage you. They have only the purest of intentions.

And their advice is still utter bollocks.

I have a lot of friends, and I've lost count of the number of times I've had to dismiss their freely offered opinion as well-meaning, but useless. That's because most of them are non-technical people and not of the career consultant variety. I'm honestly baffled at the number of people who have seen fit to advise me on how to build my career in my own industry without having worked a single day in it. Or people who give me marriage advice when they don't even have someone to hold hands with. Or people who tell me how to manage my money when they're the ones who are constantly in debt.

Advice is easy to give, and exceedingly few people will, when dishing out advice of any sort, pause to consider if they are qualified to dispense that particular brand of wisdom. That's not a blot on their character; merely an unfortunate facet of human nature.

But the advice is free!

Oh, dear. You know what else is free? Farts. Toe fungus. STDs. You don't have to pay a cent for them either, but do you really want those?

Advice is one of those things you should not value just because it's freely given. If it was worth anything professionally, you should have to seek it out, or better still, pay for it.

But my friend is a well-paid developer in a tech company!

Then yes, listen to him. Or her. But you should be listening because this friend is an authority in the career you want, and not because he or she is your friend. In fact, if you're in the habit of listening to people just because they're your friends, stop it. Pronto.

But they've hired techs before!

Oh, wow. I guess that must really mean they know something, huh?

Hey, you know who else has hired techies? Human Resource people, who (surprise, surprise) may not actually know all that much about tech careers specifically. Clueless CEOs of small outfits who don't have the sense to leave hiring to more qualified people. Incidentally, unless you're desperate, I'd steer clear of those companies.

I'm not saying that people who have hired techies don't know shit. They could actually know shit. But if they claim to know shit and don't want to get laughed at, they should also know that "I've hired techs before", on its own, doesn't cut the fucking mustard.

Actually, scratch that last bit. They don't have to know. You do.

What about my ex-classmates from my Computer Science Degree?

That depends. Are they currently making a living in tech? Then go for it. If not, fuck 'em. What could you possibly learn about the tech industry from people who haven't written a single line of code in years? I'm sure their opinions are valuable to someone, somewhere out there. Just not to you.

Why Advice Can Be Bad

The best advice doesn't necessarily come from someone in your field, but it helps.

People who are only in it for the money, will give you advice on how to earn money in the shortest time possible. People who just want to coast along in life, will naturally recommend jobs where you can take it easy. People who equate professional success with fancy titles will point you the way to companies where you can make a name for yourself and climb the ladder.

None of that is intrinsically wrong. People want what they want. But you need to be really honest and ask yourself if this is what you want. Just because what people want for themselves isn't wrong, it doesn't follow that what they want for themselves must be right for you.

Don't follow for the
sake of following.

I'll say this again - advice is opinion-based. And opinions are skewed by perspective. If you're looking for relevant career advice regarding the tech industry, do you think you could obtain it from someone plying his or her trade in, say, healthcare? Law? Journalism? Sales and marketing? Driving a cab? Running a hipster cafe? A career soldier or civil servant?

None of the above, Junior.

The point is that the person giving you the advice should have his career goals aligned to yours. He should want the same things you do, and preferably already accomplished them. Therefore it follows that someone in the industry you want to build your career in, would give you better advice than someone out of it. If you want a tech career, be advised by a tech.

It could still be bad advice, but it would at least be relevant bad advice.

And even then, bear in mind that the advice isn't good just because the one giving it comes from the same industry. There's this guy who used to intern at a start-up I worked for. He wants to be a software architect five years down the road, and the worst thing he could do is listen to me. Why? Because I'm not the kind of guy who wants to be a software architect. I want to code. I don't want to be in the position of overseeing something and then not getting my hands dirty. Any advice I give him would not bring him anywhere close to his goal. It would only bring him close to my goal. And even then, I'm hardly the ideal person to ask - I've made several mistakes during my storied career and will likely make several more by the time this post is read.

But if I'm not convincing enough, maybe this long-dead technopreneur will be.
"Your time is limited, so don't waste it living someone else's life." - Steve Jobs

The times I didn't listen...

A couple years ago, I was in the market for a job. A few people, rather amusingly, offered me tips on my job search. Apparently, I needed to:

- refuse to provide details of my last drawn pay (to give me that edge in negotiation)
- provide some plausible bullshit for leaving my last job (because the truth would blunt my edge in negotiation)
- cover up the tattoos on my fingers. (because, even though it was 2017, these things somehow still matter)

Liverpool FC pride, baby.

You know what I did? None of that shit. I was too arrogant to lie, obfuscate or provide evasive answers. I provided excruciatingly detailed salary figures from all my previous places of employment. I stated up front that the last two companies that I worked in, tanked. And I certainly didn't cover up my goddamn fingers.

I not only landed the job, but they offered me more than what I had asked for.

Strategy? Bah humbug. You need substance, not strategy. You need to have a finely honed sense of what matters and what doesn't. Without that, no amount of "strategy" proposed by people who can't tell Java from JavaScript, will help you. Trust your instincts.

In conclusion

Be very stringent as to whom you take advice from.

Whatever advice you take, remember this. This is your career. Own it. It is your responsibility. You don't get to do something stupid and then claim that people gave you bad advice. You chose to follow it!

You're the only one with skin in the game. If you're going to give your career an honest shot, I hope to hell that whoever is advising you has something a lot more substantial than "I'm older than you, so I know better" and "I mean well".

Also remember that everyone has a right to their opinion, informed or otherwise. What they don't have an automatic right to, is to be taken seriously by you. That they have to earn. And if you choose to give their opinion weight simply because they're family or friends... hey, you know what they say - there's a sucker born every minute.


You've been so advised,
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

Friday, 12 May 2017

Why you should love your job

A couple weeks back, Minister Chan Chun Sing delivered a speech during my alma mater Temasek Polytechnic's graduation ceremony. This was met with a certain amount of controversy, as he addressed the career aspiratons of the graduates with these words...
"In today's world, where we have many choices, it is very easy for us to get lost among the many choices and get very distracted. We are constantly searching for that something that would give us perfection, searching for that something that would give us meaning. But we would often fail, and then we will be disappointed. But instead, if we change our perspective, and ask ourselves, can we do justice to the job we are doing, can we do justice to the relationship that we are building, can we give meaning to what we are doing, then we are in control. And if we can give, rather than just expect to take, then regardless of our station in life then I think we will find meaning because we give meaning. But to only find meaning, it will be tough to be happy."


I don't disagree (much), though much ado has been made over his follow up remarks...
"Is it more important to marry the woman you love? Or to love the woman you marry?"


Yeowtch. Just tone it down a notch there, fella.

Love what you do, or do what you love?

But however you take those words, one thing remains clear - loving your work has become more important than ever. A couple years back, I ruminated a little over Steve Jobs's infamous quote about loving one's work.

And now, I would like to add a little nuance to it.

Why should one love his job?

One of the most common answers would be - if you love your job, you naturally do it better. That's true enough, but that's merely the icing on the cake, not the cake itself. Also, does it naturally follow that someone who does not love his job will not be good at it?

I've heard it said that passion is part of professionalism.

Rubbish. Utter self-aggrandizing claptrap.

Professionalism is about delivering services to certain accepted standards regardless of whether one loves what he is doing or not... especially if he does not love what he is doing. Professionalism is about divorcing one's feelings from the quality of his work. Nobody is going to cut you any slack, for example, if you start writing rubbish code because your girlfriend just dumped you.

The only exception to the above rule would be artists - designers, photographers, actors - whose work requires them to pour a certain amount of their soul into it (yes, I'm being melodramatic here, deliberately so). And even then, if said professionals in those fields allow negative feelings to adversely affect their work, they're certainly not going to be earning any sympathy points.

When I say someone does not love his work, I don't necessarily mean he hates it. He could simply see it as a means to put food on the table, nothing more. If he could help it, he wouldn't do it at all. There's stuff he would much rather be doing. That does not mean someone who does not love what he does, is less professional. In fact, quite the opposite - someone who does not love what he does and yet manages to perform at consistently high levels, displays an astonishing amount of discipline and focus.

Enthusiasm isn't everything. I mean, look at me. I have enthusiasm in spades, but I suck.

That said...

There is a compelling reason to love what you do.

Automation is becoming the next big thing. Machines won't demand benefits. Machines will produce consistently with few errors. Machines don't need to be motivated. McDonald's has started replacing their human staff with self-service kiosks. Phone Support Hotlines are being replaced by pre-recorded messages. Web development work is being automated via scripts. And I'm not even going to go into factory production lines.

If you don't love your job, the danger isn't that you won't perform as well in it. Even if you are the consummate professional, the fact is that you are tolerating your job to perform as required.

Guess what will always do better than you, at tolerating your job?

Desire is irrelevant.

Remember this quote from the God-awful Terminator 3: Rise of the Machines?
John Connor: You don't want to do this!
Terminator: Desire is irrelevant. I am a machine.

Machines don't have to tolerate their job at all because machines are incapable of disliking their job. But there is a saving grace to this. Machines, by the same token, are incapable of loving their job. If you can love your job and perform better due to that love, you've just afforded yourself some immunity to the effects of automation.

Because love cannot be automated. Emotions cannot be automated. That is also why artistic industries are largely proofed against the dreaded A-word. Not because actors, musicians and sculptors are more professional. But because their output cannot be easily replicated via automation. Yet.

This blogpost was not automated.
T___T