Information Disclosure Vulnerability in WordPress REST API

WordPress is insanely popular. Around 43% of websites on the internet use WordPress. I don’t know how it’s come to this, as WordPress is not that great. But, aside from being a relatively easy writing platform for hobbyist bloggers like me, it’s also very prevalent among digital marketing companies, who build their own websites and those of their customers on WordPress.

As a result, bugs and security flaws in WordPress are not to be taken lightly, no matter how small.

Listing Users

I came across the following in the book Hacking APIs: Breaking Web Application Programming Interfaces by Corey J. Ball:

“Sensitive data can include any information that attackers can leverage to their advantage. For example, a site that is using the WordPress API may unknowingly be sharing user information with anyone who navigates to the API path /wp-json/wp/v2/users, which returns all the WordPress usernames, or “slugs”.”

— Hacking APIs: Breaking Web Application Programming Interfaces by Corey J. Ball (2022), page 54

Indeed, I was able to simply append /wp-json/wp/v2/users to the URL of several WordPress sites and see a list of users. For instance, this is from a fresh WordPress install:

A list of users shown in a fresh install of WordPress.

The following, on the other hand, is a list I got from a company website:

A list of users from a company website, obfuscated to protect their identity. You can also see they use the Yoast SEO plugin.

The following is from another company website, which has been protected with a plugin, but reveals the name of the plugin used:

The list of users from this other website is restricted by the iThemes Security plugin.

We’ll discuss in the next section why revealing the names of plugins you use, like Yoast SEO or iThemes Security, is probably not a good idea.

Meanwhile, as we have seen, it is very easy to get a list of users, including their full name and username, for a WordPress website. Unfortunately, the WordPress REST API, of which wp-json is the top-level endpoint, is enabled by default.

To be fair, it’s also possible to find out the users of a WordPress site by just checking its blog posts and taking note of the author. The link to an author exposes the username, instead of using something more generic like an id.

Either way, once an attacker knows the usernames pertaining to a website, all that’s left is to figure out a password. They could brute force a password for one of the users or else attempt a set of weaker passwords for several users and see if any fit (a technique known as password spraying). It also doesn’t help that it’s universally known that WordPress sites have their login page at /wp-admin. Having strong passwords is more important than ever.

Listing Plugins

There is also a wp-json/wp/v2/plugins endpoint, which presumably could give us a list of plugins, but it does seem protected by default:

The plugins endpoint doesn’t tell us anything.

However, we can still get a lot of information about plugins by just expanding routes at the top-level wp-json endpoint. For instance, the screenshot below shows that this website uses Elementor, Gravity Forms, and Google Site Kit among other things. It is also possible to find out plugin names from other places, as shown in the previous section.

Expanding routes exposes the names of many plugins used by a WordPress website.

Knowing the plugins used in a website, an attacker could look up known vulnerabilities, e.g. on WPScan, and attempt to exploit them.

Disabling the REST API

Just because an attacker knows your users’ usernames or plugins, it doesn’t mean they will manage to compromise your website, or that they couldn’t do it without that knowledge anyway. But it’s conventional wisdom in IT security that we can sleep more comfortably at night if we don’t make it easy for bad actors to destroy what we worked so hard to build.

An easy way to stop sharing all this information is to disable the REST API altogether. As with everything else in WordPress, this can be done with a plugin.

The Disable REST API plugin.

Simply find, install and activate the Disable REST API plugin. This will protect the REST API:

With the REST API disabled, we can’t see the list of users any more.

Some notes:

  • This protects the entire API, not just the users endpoint shown above.
  • In the plugin’s settings, you can configure any endpoints you want to remain accessible.
  • “DRA” does expose the name of the plugin. It’s not perfect but reduces risk considerably.
  • You should test this from an incognito browser window. If you access the API from a browser where you’re logged into WordPress, you’ll likely see the regular API response simply because you’re authorised.
  • There’s another way to disable the REST API using the WPCode plugin instead.

Conclusion

Given how much information the REST API provides to basically everyone, it’s a little shocking that it’s enabled by default. By disabling it, we can make attackers’ lives a little harder and reduce the security risk of our WordPress websites.

Contactless Check-In: A Security Nightmare

IT security is always a big deal. We’ve heard of a lot of data breaches, and all sorts of different attacks (e.g. phishing, ransomware, etc) over the years. A security incident can cost a company its reputation and threaten its survival. But how much worse is it when IT security puts the very safety of your home at risk?

Contactless Check-In: Intro

Over the past year or so, I’ve stayed at some apartments and hotels in the DACH region that were “contactless”. They had no reception; they send you a code and you let yourself in. I’m not sure whether this practice was popularised by the COVID19 pandemic or was already well in force earlier, but I do understand the appeal:

  • It minimises the risk of catching contagious virus for both staff and guests
  • It reduces expenses for the company by not needing to pay reception staff

However, it also has some serious flaws:

  • If there’s any problem with the accommodation, it’s a huge hassle to get someone to fix it.
  • Even worse, if the entry code doesn’t work for whatever reason, you’re basically screwed.
  • Still worse, having an entry code sitting in your mailbox is a security accident waiting to happen.

Let’s talk a bit more about that third point.

Don’t Send Passwords via Email

If you work in IT or have at least a basic understanding of the internet, it should be common knowledge at this point that sending passwords via email is a bad idea. Email is not a secure channel; each email message can go through a number of devices and servers, unencrypted by default, and can be compromised at any point during that journey.

That’s why every bank seems to invent its own secure messaging mechanism. They have to deal with enough fraud and security incidents already, and email is a relatively easy attack vector. And yet, I’ve written about cases of passwords being sent by email in the past, e.g. “The Shameful Web of April 2017 (Part 1)“, “The Pitiful State of the Web in May 2017 (Part 2)“.

Beyond the danger of being intercepted in transit, a bigger problem with email is that it can stick around for a long time. So if you have an email that contains a password, someone could obtain illegal access to your email on a server or on one of your own devices at some point in the future and, unless you’ve been diligently changing your passwords regularly, would still be able to use that password nefariously.

Nowadays, when you sign up for a new account, the best practice is for the service to send you a limited-time activation link that then lets you choose your own password via their web interface (securely over HTTPS, of course). It’s still risky, but there is a limited time window so an attacker would have to gain access to that email in the short time before the link either is consumed or expires. Using multi-factor authentication further reduces the risk considerably.

Contactless Check-In: Codes

If it’s so risky to send a password via email, how much worse is it to send a code that gives access to your hotel room or apartment?

There are a couple of places I’ve been to that send you a code for either the apartment or a key box that is valid for the first day. When you arrive, you use that code and get a key, which you then have to use for the remainder of your stay. This is similar to sending an activation link via email, so there’s a limited time window for an attacker. But I’d argue that the risk of someone getting into your room or apartment and robbing you is much higher than some prankster setting your Facebook profile picture to that of a horse, so I don’t think this approach is acceptable.

It gets worse. Vision Apartments send you a code that remains active for the duration of your stay (potentially several weeks or months), is the only way to access your ‘apartment’, and gives access to the front door of the building, your ‘apartment’, and your mailbox. That code remains active and is available to Vision’s staff as well as potentially anyone who gains access to your email during the entire duration of your stay.

  • Did you accidentally forward the email to the authorities? Oops. They technically now have access to your ‘apartment’.
  • Did you leave your home laptop or mobile phone unprotected while guests were around? Not great either.
  • Did you accidentally fall for a social engineering scam and reveal your email password?
  • Did someone brute force your email account’s password?
  • Did someone intercept the email on one of the servers it went through while it was being sent?

Some of the above cases might sound stupid, but people do fall for scams all the time, and they are subject to identity theft, fraud, and other crimes. That’s bad enough. You wouldn’t want to leave your house keys hanging where anyone can just pick them up.

Would you leave your keys outside the front door like this? (Image source)

If someone manages to get hold of that email and code, they basically have control over your living space, your physical mail, your belongings, and your life. That’s pretty scary.

Note: I’ve already mentioned in “Surviving in Canton Zurich” that I had a terrible experience with Vision Apartments. The security aspect is one of many things that bothered me, and it would take a whole long article just to explain all of them. If you’re considering staying with Vision, do yourself a favour and don’t, or at least read some reviews first.

Conclusion

Whatever the reason behind contactless check-in, it’s a terrible idea. It’s both bad service and bad security. In fact, it’s a security accident waiting to happen. It might also possibly be in breach of data protection laws.

It’s not worth the risk. So before you stay at an accommodation, always make sure they do actually have a reception.

Hiring Software Engineers: From Dev to Interviewer

Last updated: 24th December 2022

We software engineers are a proud and somewhat entitled bunch. We’re used to being chased on LinkedIn by recruiters, think our work is craftsmanship, and get paid relatively well for work that is relatively low-effort (compared to other jobs, such as teaching, construction, catering, etc.) if perhaps somewhat stressful and possibly boring. And so, it’s common for us to take certain aspects of the tech hiring process to be an affront to our dignity. For example:

  • Why did this company not contact me when my CV is so great?
  • Why does this company expect me to waste time doing a coding exercise in my own time?
  • Why was I rejected after acing the interviews?
  • Why is the interview process taking so long?

All this starts to be clear when you shift to the other side: from being a candidate to an interviewer. However, it doesn’t mean that the things that bother us as candidates are all justified. All too often, the transition from candidate to interviewer is quite a huge context switch. What do you look for in a CV? What questions should you ask in an interview? How do you choose between promising candidates?

When people don’t know how to answer these questions, they do what they do best: they ask Google for insight, find a list of questions they are somewhat familiar with, and prepare a script. The problem is, as with Agile, that companies and roles can be vastly different, so you need to adapt the hiring process to what you do and what you are looking for rather than copying what everyone else is doing.

In this article, I’ll be talking about the entire process of hiring software engineers, not just interviewing. Most of this should also apply to related disciplines such as QA or DevOps engineers.

Vacancy / Job Description

Before you even think about interviewing, the first step is to write up the details of the vacancy you want to fill, and publish it where people can see it. Unless you’re a Big Tech company (in which case you probably don’t need to read this article in the first place), seeing this vacancy will be the first time most people hear about you, so you want to be very clear about what the company does and what kind of person it is looking for.

Job Title

Stick to a traditional job title that more or less reflects what the person will be doing.

  • Avoid things like “Ninja”, “Rockstar”, “Guru” or “Expert”. It’s just pathetic.
  • Something simple like “Software Developer”, “Software Engineer” or even “Programmer” (which for some reason has fallen out of fashion) is okay.
  • Including a focus area (e.g. “.NET Developer” or “Backend Developer”) is okay if that’s primarily what they will be doing, but software engineers will often have to work with multiple technologies or in different areas, so this could at times not reflect very well what they do.
  • Account for seniority and experience by prepending “Senior”. There are a lot of ways you can develop this further (e.g. architects, staff engineers, etc) if you want, but let’s keep it simple. The point is that it’s only fair to have the job title reflect what the person’s experience and resposibilities are. Job titles are important, and experienced individuals might not apply if they feel they would be taking a step back in their career. Having said that, job titles can mean significantly different things in different companies, especially across different company tiers.

Company and Role Introduction

In simple language, explain what the company does, why it is hiring, what kind of work a successful candidate would be doing, and why they should be interested. Although this looks easy, it’s quite common for companies to mess this up completely. Just doing a quick job search on LinkedIn right now, I can find many examples that use too many buzzwords/cliché (e.g. “exciting”, “dynamic”) or are too generic and therefore meaningless. For instance:

“[Company Name] is a leading global information technology, consulting and business process services company. We harness the power of cognitive computing, hyper-automation, robotics, cloud, analytics and emerging technologies to help our clients adapt to the digital world and make them successful. A company recognized globally for its comprehensive portfolio of services, strong commitment to sustainability and good corporate citizenship, we have a dedicated workforce of over 170,000, serving clients across six continents. Together, we discover ideas and connect the dots to build a better and a bold new future.”

Okay, the buzzwords are all there, it’s big and all, but what does the company actually do?

“We’re looking for a Senior Software Engineer / Architect to join our client’s Agile team.

“You’ll need to combine professionalism with passion to champion this company’s name that’s stood since 1998.

If that describes you perfectly then we’d love to see your CV.”

Wow, how incredibly boring. What’s in it for me?

“Do you want to play a key role in driving digitization in HR and have experience in development? Then you’ve come to the right place!”

No, actually, I don’t.

If you want to attract the right people, forget the sales pitch bullshit (including company values) and try to have some empathy. You’re looking to develop a relationship with an individual that could last several years.

A good intro, in a nutshell, could mention:

  • What the company does: “[Company Name] is an established player in the insurance space. We invest heavily in technology to automate our business processes as well as to make it simpler and more accessible for customers to manage their insurance products online.”
  • Why the company is hiring: “We would like to hire a mobile developer to help us develop a better mobile app that can bring our entire product portfolio into every customer’s pocket.”
  • What the work would be like: “The successful candidate would work on expanding the functionality of the Android and iOS mobile apps, integrating with existing APIs and delivering insurance products to a mobile audience using security best practices and a great user experience.”
  • Why they should be interested: “We offer great salary and benefits as well as the opportunity to grow within the company. You would also be working with very smart people and can learn a lot about mobile development, security, user experience, and insurance business.”

Job Requirements

It’s common for vacancies to list several things that either are hard requirements or would be nice to have. In software development, these lists are notorious for going overboard, such as requiring more years of experience with a technology than the time it has been around for, or requiring a huge list of skills for an entry-level position. Let’s discuss a few of these.

  • Computer Science degree: it’s common for vacancies to require a University degree. This is extremely debatable given that some of the best programmers are self-taught. However, statistically speaking (because a company will interview lots of candidates), there’s a higher chance to find good programmers among those with a good Computer Science education than those without, so it’s a reasonable baseline. I just wouldn’t make it a hard requirement.
  • Years of experience: again, having X years of experience with Y language doesn’t make you competent. I’ve interviewed many .NET developers with 10 years of experience who had never even heard of IDisposable. It’s okay to require two or three years of experience to weed out some less experienced candidates when that’s necessary, but don’t go overboard.
  • Specific technology: and again, is it really required to have experience specifically with Node.js, or Python, or whatever? That might be the case if you’re an outsourcing company that promised its client to give them a Python developer who needs to hit the ground running right away, or if you’re doing something really specific. Otherwise, if you just need someone to build APIs and microservices, these are done in basically any language out there and someone who has done that with a different language can ramp up pretty quickly. It’s really annoying when people keep saying that skills are transferable and that a competent developer can switch languages in a short time, but companies never really give the opportunity for that to happen.
  • Subjective stuff: “Team player”, “dynamic”, “passionate” and all that aren’t things you can reasonably measure, so they don’t belong in a list of requirements.

There’s a lot more to be said here, but we’ll talk more about many of these areas in the next sections. The main takeaway is that you should consider the work that the candidate would be doing if hired, and focus on the aspects of that work that are required. This could include things like:

  • Experience developing REST APIs
  • Experience working with cloud providers
  • Experience working with microservices
  • Knowledge of SQL

“Required” is debatable. You could mention experience writing unit tests for instance, but that’s pretty easy for someone to learn, so it probably shouldn’t be in that list.

What’s In It For Me

People have different goals in life. Maybe they want to learn something new, advance their career, look after their family, or even just pay the bills. Is there anything wrong with that?

So, avoid talking exclusively about what the successful candidate would do for the company (especially using language like “You will” every two sentences), and mention a few things that would appeal to people:

  • Salary: avoid words like “competitive” and “attractive” (which mean absolutely nothing) and instead put a salary range. This shows transparency and at the same time avoids wasting time for everybody when the asked and offered salaries don’t overlap.
  • Career advancement: people like recognition for their work and a sense of progression over time, so it’s good to mention that the company has a plan for this.
  • Learning opportunities: this can take many different forms, such as the ability to work with technologies that are trending, or providing a budget to do courses or attend conferences.
  • Remote working: many people prefer to work partly or entirely from home, and appreciate it when this flexibility is offered.
  • Flexible working hours: again, offering some degree of flexibility helps people achieve a better work/life balance, especially when dealing with personal commitments that could require their attention at any time of day.

Another thing many software engineers enjoy is working with smart people, but the meaning of “smart” is unfortunately subjective enough that it doesn’t mean much to an outsider.

Avoid bullshit perks, such as:

  • Free beer (I can afford it thank you very much)
  • Ping pong / pool table (I like this but I’m also not 8 years old)
  • Modern office space (actually a drawback in my opinion)
  • Work laptop (it’s not even a perk)

“Talent”

When you hire someone to work at your company, you’re not hiring their talent. You’re hiring a person, a full package, with hopes and fears, emotions, interests outside of work, a family perhaps. Sometimes they will mess up and you will need to work with them to improve. Sometimes they will shine and you will be proud of them. And sometimes they will go through hard times in their personal life and you’ll need to help them manage that.

So, referring to people as “talent” is extremely dehumanising, and is offensive insofar as those hiring seem to focus on obtaining an input to the business and forget that they’re actually dealing with people. Moreover, it’s also worse than things like “human resources” or “human capital” because it’s actually semantically wrong. People with the right skills don’t necessarily have a talent for what they do.

Sourcing

To get job applications, you have to put that vacancy description somewhere where it can receive the attention of prospective candidates. This is called sourcing. It’s one of the toughest parts of the hiring process and one that interviewers usually aren’t involved in. How do you find candidates? Well, there are a number of different options, including:

  • Advertising job openings on your company website. This is probably the best because you can accept applications directly without paying recruiters, and you get a higher share of applicants that are interested in your company specifically. However, it depends on your company having a well-known brand (e.g. Google) and won’t work very well if you’re a brand new startup that nobody heard about.
  • Social media and job boards. LinkedIn in particular gets a lot of attention from jobseekers, so publishing the vacancy there is bound to get a lot of attention. Some HR software with hiring functionality also has the ability to automatically publish the vacancy to lots of different job boards for visibility. These channels will get you a quantity of applications but not much quality overall, so you’ll need to invest more effort in the CV reviewing stage to filter out the noise.
  • Recruitment agencies. The idea is that a recruiter will reach out to people (e.g. on LinkedIn) and try and get them to apply for the job; if a person they found gets hired, the recruiter takes a percentage of the new hire’s annual salary as commission. While in theory they take care of the hassle of sourcing, in practice their lack of familiarity with tech makes their benefit very limited. What’s worse is that the commission basis means it’s in their interest to inflate candidates’ asking salaries and even help candidates to cheat through coding exercises, both things I’ve seen happen.

CV Reviews

There’s no need to put a photo on your CV. (Image source)

So you’ve started receiving applications for the vacancy. Depending on various factors (e.g. the channels used to publish the vacancy, the attractiveness of the vacancy itself, etc), you might receive a large number of applications for a single job. From here on, your job is to narrow down this list to as many candidates as you need for the position, possibly just one.

Job applications usually come as a Curriculum Vitae (CV, or sometimes also called résumé) accompanied by a cover letter. The cover letter is often not required or not even useful for tech jobs, so I won’t really talk about this. Let’s instead focus on what to look for in a CV. There is already a LOT of material on the internet about how to write a good CV and entire books have been written on the subject (e.g. The Tech Resume Inside Out). But as tech companies and roles can vary significantly, I can’t recommend a lot of the general advice you find out there (e.g. limiting a CV to a single page), and I will instead talk about the things I look for.

First, I need to make very clear that you will never have sufficient information in a CV to hire a person. You might have enough information to reject them, for reasons we’ll discuss shortly, but the CV is really just a starting point from which you will decide whether to begin the interview process at all with this person or not. So, reviewing a CV is not an accurate scoring game. It’s really just a way to look for signals that indicate whether this candidate might have what it takes to do the job competently. Those signals aren’t conclusive and it’s very possible that the interview process will prove otherwise, as it often does.

When looking at the CV, the first thing to check is whether it is relevant at all for the job. Some examples leading to an immediate rejection include:

  • Wrong language. For example, you receive a CV in Turkish and you’re an international company that uses English. Or, you clearly specified you want a German speaker but got a CV in English.
  • Irrelevant experience. For example, you want an experienced software engineer but the candidate only has experience teaching in a school.
  • Unprofessional writing. If a CV contains vulgarity or too many spelling/grammar mistakes, you probably want to pass. Even if the candidate is not a native English speaker, the least they could have done is to use a spellchecker.

The layout of the CV should generally be concise and clear. Sometimes candidates try to get creative and make something stylish at the detriment of clarity. Or worse, they use the EuroPass template, which is a horrendous way of organising information and shows a lack of effort. Despite what recruiters say, there’s no fast rule on length, although it’s true that some people reviewing CVs will discard longer ones. As far as I’m concerned, if it takes 3 pages to give a good summary of one’s experience, they should use 3 pages. It doesn’t make sense for candidates to cram a lot of info with a small font into one page just to fit this stupid one-page requirement.

The following are things you should pay no attention to, as they may introduce bias and might even be illegal to consider as hiring criteria:

  • Photo
  • Age
  • Gender
  • Marital status

In some regions, it’s also common for candidates to put an “Objective”, like a mission statement or cover letter, explaining what the candidate is generally looking for. The ones I’ve seen are way too generic and formal, and are best ignored. You can get a better feel of this in the interview process.

At this point, we can get to the meat of the CV. CVs are all different in terms of layout and content, so what makes an important signal and what is just noise?

  • Industry. They may have the necessary experience, but what industries did they work in? There’s a big difference between the problems you solve in a highly regulated sector such as finance, and building Software-as-a-Service (SaaS) product. There is also a big difference between oursourcing and product companies in terms of exposure.
  • Projects. I get an idea of their experience by seeing what they worked on and what their contribution was. On the other hand, many candidates put a description of what the company does, or their job description, in their work experience and that doesn’t tell me anything.
  • Skills. It’s okay for a CV to contain some of the most relevant programming languages and libraries used, but many CVs list skills with ratings or experience levels that are entirely arbitrary and therefore just noise.
  • Education. As I mentioned earlier, it’s not necessary for a software engineer to have a University degree (unless the company requires it of course), but taking note of their relevant education is beneficial and is part of the overall package that makes up a promising candidate. Professional certifications are also debatable – they prove familiarity with a certain technology, but they are much more about memorising heaps of facts than problem solving.
  • Open source contributions. Lots of aspiring software engineers are aware that companies see an interest in open source, and so many of these people have GitHub repositories full of poor quality hobby code. I would pay attention to someone who has made a significant contribution to a notable open source project that is run by a bigger organisation than just that person, but other than that, seeing people’s code on GitHub is most of the time more of a turnoff and frankly they would be better off not mentioning it at all in their CV.
  • Community. Open source is one way in which candidates can share their experience and give back to the community, but there are other ways, such as blogging or public speaking. This shows a certain passion which, although not required, can make people pleasant to work with.
  • Location. With the increase in remote jobs since the COVID19 pandemic, many software engineers have been questioning the need to be in a specific country or region (e.g. Remote US only). But the truth of the matter is that running a distributed company is a big challenge for various reasons, from the legal and administrative implications of hiring people in different countries to the logistic difficulties of working with people in different timezones. So, if your company is based in the US and you don’t want to hire people in Europe, it’s perfectly okay and there’s nothing discriminatory about it.
  • Language. Some roles require a certain level of proficiency and/or clarity in spoken and written language (e.g. English, German, or whatever), especially when they are client-facing. So again, if it’s a reasonable business requirement, there’s nothing discriminatory about excluding people on the basis of language. Communication is after all a problem that most software companies face even internally, and there’s no point in exacerbating it.
  • Hobbies. These are mostly irrelevant other than for small talk, but I do remember reading in The Soul of a New Machine that some intricate hobbies (e.g. sculpture) can indicate an affinity towards dealing with complex systems. I’ve made a similar observation myself about music. There’s no real correlation between such hobbies and programming proficiency, but in rare cases, interesting hobbies can lead to interesting conversations in which you can learn more about the candidate.
  • Hype. While it’s perfectly okay if a curious software engineer has been learning the ins and outs of Blockchain technology, it’s another story if their whole CV seems to be centered around topics such as Agile, AI, esoteric languages, or anything that seems trendy at the moment. You want a person who can find a solution to any problem using the right tools for the job. So when you come across someone who wants to use their technology of choice for anything, it’s a big red flag.

So, in a nutshell, you want to work with an interesting person who is competent at writing software and solving problems. The CV will give you a basic idea if it’s got enough information about the projects they worked on, industries they worked in, and technologies they worked with, and perhaps a few other things. Depending on these signals, you’ll decide whether the CV goes through the next stage or not.

It’s also essential to take notes about the signals (whether positive or negative) you gained from each candidate’s CV in your HR/hiring software. This is important because as you review dozens or hundreds of other candidates, you will inevitably forget the details of each one. Thus, taking down a few points (a) saves you having to re-read the CV in detail before the interview, (b) provides better transparency on why candidates were rejected, and (c) in some cases lets you prepare questions specific to this person for the interview.

Screening Calls

Before starting more technical interviews, many companies do a brief pre-screening call. It could be anything from 10 minutes to half an hour long, and serves to filter out cases that have passed the CV review stage but clearly aren’t a fit.

The screening is often done by a non-technical person (or even an external recruiter) and is used to assess basic criteria such as language, motivation, attitude, and basic familiarity with technologies and processes that the company uses.

This is a tedious but very important part of the process, because it saves a lot of the time for busy software engineers and managers that would otherwise be wasting a lot of time interviewing a lot more people than necessary.

Unfortunately, this is one area I’ve never really been involved with, so I don’t have any interesting insight to provide in this case.

Interviewing

Job interview with a smile: not your usual job interview. (Image source)

You have candidates that passed the CV review and screening, and now it’s time to meet them!

Scheduling

Before that, you’ll need to agree a date, time and place to have the interview. Interviews may be either on-site at the company’s premises, remote (using software such as Zoom, Teams, Google Meet, etc), or a mix of both. To schedule the interview, you can agree on a date and time via email and then send them a calendar invite for the call, or you can use software such as Calendly that lets the candidate pick a slot and automatically sends the invite to you and the candidate.

I’m not a big fan of Calendly-type scheduling because, although you can restrict the times in which interviews are scheduled, giving away control of your calendar can still lead to a lot of inconvenience (e.g. 4 exhausting hours of back-to-back interviews, or a whole day of alternating hours of interviews and free time in which you won’t manage to get anything done). On this note, it’s also worth mentioning that interviews can be extremely tiring depending on the individual, and can very easily lead to burnout if done frequently and for long periods of time. Ideally, don’t do more than 2 interviews per day, and have other people on rotation that can give you a break or cover you when you’re sick.

Interview: Introduction

A common piece of conventional wisdom is that a candidate should have researched the company and know what they do, and if they don’t, then the interviewer would see this as a lack of motivation on the candidate’s part, and a puppy would die somewhere in the world as a result.

Well, there are a few flaws to this mentality:

  • It implies that the company is awesome and that every candidate should be drooling over it, which is usually not the case.
  • It implies that the candidate’s goal in life is to satisfy the company’s every demand and that they don’t need to pay the bills or look after their family.
  • It requires that companies explain what they actually do on their websites. They don’t. Their websites are full of vague content and buzz-words (“Oh hey, we do digital transformation, like the next 36,000 other companies in this region!”) and are made for sales, not hiring candidates. Seriously, go to any company’s website right now (that you’re not already familiar with) and see if you manage to figure out what they do.

So, my advice is to stop being so pretentious and do exactly the opposite. You want to hire a software engineer? Great. Make them feel welcome: in the interview, spend the first few minutes explaining what the company does, why they’re hiring, and what type of person you’re looking for. This is exactly the same stuff I mentioned that you should have in the vacancy description, but you can go into a bit more detail, e.g. you can talk about the team that’s seeking to fill this vacancy, give more background about the company’s goals for this year, or take general questions even before you get into more technical stuff.

Then, ask the candidate to give you a brief background about their experience, and maybe talk about something interesting they worked on. Again, this is a little repetitive because you’ve already seen this to some extent in their CV, but it (a) often takes new life when spoken spontaneously, (b) allows you to ask specific questions about their experience either from their CV or from what they say at this time, and (c) helps break the ice.

Remember that interviews are a two-way street. The candidate is assessing the company as a potential fit for them just as much as the company is assessing the candidate. Choosing to work with someone is a big investment on both sides and requires a good relationship to be maintained.

Interview: Technical Questions

After the intro is done and dusted, it’s time to do what you’re here for: assess the candidate’s suitability for the job. For a software engineer or similar role, most of the time is usually spent asking technical questions. But which questions should you ask?

In practice, the interview process varies wildly between companies. Big Tech companies such as Google or Facebook (oops, now Meta) are known for their focus on algorithms and data structures as well as system design and architecture. Some companies require candidates to do a coding exercise (either using a platform like Codility or HackerRank, or something custom), and others don’t. Some companies do a single interview, whereas others do up to nine. Some use psychometric tests.

Who’s right? It doesn’t matter. Companies are all different, and you should look inwards at your own company’s needs instead of looking at what other companies do. Unless you’re Google, it’s safe to say you’re not Google, so candidates have no need to endure the same grueling process for a lesser-known and lesser-rewarding company. In fact, software engineering & management influencer Gergely Orosz argues that having less draconian hiring processes is a way for startups with less resources to attract talent… I mean people.

My personal view is that, if you ask the right questions, you should be able to get a good idea about a candidate’s technical aptitude from a single one-hour interview. That’s certainly not a general rule, and it doesn’t mean there isn’t a place for additional interviews (e.g. with management), but I’ll focus on what questions to ask in a technical interview.

Many interviewers prepare a script of questions with a specific answer and go through those one by one in order. While it’s useful to prepare a list of questions, there’s no need to stick to the script or to ask the questions in order. For instance, during my most recent interviewing round, my colleague and I would take it in turns to ask different questions, jumping around different topics in whatever random order the conversation went; it made things more interesting and also gave each of us a regular break during the interview.

Somewhat counterintuitively, I’m not a fan of “questions with a specific answer”. A few examples I’ve been asked or had to ask candidates in the past include:

  • What is the port used by the SMTP protocol?
  • What is an interface in Object Oriented Programming (OOP)?
  • What is IDisposable used for in .NET?
  • What is the command to list currently running containers in Docker?

If the candidate doesn’t know the answer, it’s trivial for them to just Google it. For the same reason, this also tells me nothing about a candidate who does know the answer.

The questions I like to ask are more discussion-oriented. I like to work with people who don’t just write code and do tasks, but who can think and communicate. For this reason, I don’t care whether they’ve used this particular feature of this particular language. I get a much clearer picture if I present a simple debate and let them reason about it.

This is usually as easy as asking “What can you tell me about X”, or, to make it a little less vague, “What are the pros and cons of X”? This works for a lot of different things, such as microservices, serverless, actor frameworks, different Single Page Application frameworks, NoSQL databases, etc. The answer shows whether they have tried alternatives and, more importantly, whether they consider tradeoffs when deciding to adopt a piece of technology. On the other hand, if they profess the benefits of Agile or Kubernetes without being able to mention a single downside, it’s probably not going to work out.

Another, more interesting, class of open-ended questions is those about System Design, or software architecture. This is usually a topic for more senior software engineers (although it is also suitable for smart, less experienced candidates) and takes the form of “how would you build this particular system?” A good answer/debate usually shows the candidate’s aptitude to deal with bigger-picture problems and make several tradeoffs across how data is stored and how communication occurs across a nontrivial system. This type of question is not intended to choose whether to accept or reject a candidate; instead, it helps separate the most promising ones from the rest.

Interview: Behavioural Questions

If choosing the right technical questions is hard, assessing soft skills is even harder. As software engineers, we focus more on tech than interpersonal skills, even though the latter are extremely important, so we are rather ill-prepared to understand people’s attitudes in an interview.

But it’s also hard because it’s hard. I mean, we’re talking about guessing a person’s personality by talking to them for an hour. I’ve only seen this happen on TV, and if it were a thing, everybody’s romantic relationships would be perfect. Sure, there are studies in psychology and all, but can you really get such deep information from such superficial contact?

Earlier in my career, I attended two or three interviews in which I was subjected to psychometric tests. I had to look at some patterns in either image or number form, and figure out something about them. I thought they were nuts and felt like walking out. After all these years, I haven’t changed my mind.

Having said that, during the interview, there are a few things you can do to get a few signals about personality and behaviour. The simplest is to just talk to the candidate. If they are obviously rude, arrogant, or constantly taking over and not letting you speak, then you can pretty much end the interview early.

It’s also good to ask questions about motivation.

  • Why are they interested in this position?
  • Why do they want to leave their current company?
  • What excites them in their work?

It takes some good judgement to parse answers to these questions, because they aren’t obvious. For instance, it’s not necessarily wrong for someone to need to simply provide for their family (meaning your company is as good as any other), and neither is it necessarily wrong if they are leaving due to a conflict (maybe it is a bad company… bad management is quite common, unfortunately).

Speaking of conflict, it’s quite common to ask about conflict resolution, i.e. how would they deal with disagreement with colleagues or management? This is a harmless question but at the same time I don’t see it revealing too much about the candidate. Perhaps they haven’t been in that sort of situation before. In practice, conflicts boil down to lots of different factors (e.g. ego, emotion, ambition, communication, etc), so even if they know how to deal with conflict, it says nothing about how they would deal with conflicts in the future.

Coding Exercises

Oh, this is a can of worms.

Many companies feel that interviewing alone is not enough to properly assess a software engineering candidate, and so they ask the candidate to do a coding exercise on a platform like Codility or HackerRank, write code on a whiteboard, or build a small application based on requirements that the company provides. Presumably, reviewing the resulting code can help interviewers assess the quality of the code that the candidate writes, or possibly their problem-solving skills as well.

As a software engineer, I’ve always seen coding exercises as a waste of time. Some of them can take an entire weekend, and when you consider that on top of the other time the candidate spends on this job application (e.g. filling in the application form, doing interviews, etc), and the fact that they are probably also interviewing at other places, it feels like too much to ask, and it probably is.

On the other hand, I have seen several cases of interviews in which the candidate seemed to be stellar, and then wrote code that was a disaster and led to rejection. So I do understand the counter-argument as well.

There is also the perspective, as mentioned before, that forcing candidates to do coding exercises can repel people who are competent but genuinely feel that spending their free time doing coding exercises for a company that may just throw their work away is not a good use of their time (even if in some rare cases, companies actually pay for the time).

In fact, I think one of the biggest problems with these coding exercises is how arbitrary they are. Each company does it in a different way, so as a candidate you never really know what is expected of you – perhaps you invest all the time and do it well, and they reject you because they were expecting something different.

For instance, you might be asked to write a piece of software that is “production-ready”, but since it’s an interview exercise, the actual complexity is always limited to the time available, so your API might have two or three endpoints at most. So perhaps you will put a lot of layers into your application and try to impress the interviewer with your MediatR and CQRS and Clean Architecture™ and show it’s production ready. Some interviewers might indeed be impressed. Me, I would reject the candidate for overcomplicating a simple task. Who is right? That’s the problem, because every company is different.

There’s also the issue of what you’re trying to assess with the exercise.

  • The candidate forgot to clean up a resource. Is this really so terrible? You can catch that in a code review and point it out so that they are more careful in future.
  • The candidate doesn’t use very good indentation, variable naming, or consistent syntax. Again, it’s not the end of the world. Point it out in a pull request.
  • The candidate isn’t comfortable writing code on a whiteboard. They are right. We have IDEs nowadays for a reason.
  • The candidate can’t remember how to write a merge sort. Well, I can’t either. It’s been about 15 years since I learned it at University, and since then I’ve focused on solving more interesting problems than reinventing the wheel (at least until I started programming in Go).
  • The candidate isn’t comfortable using HackerRank because they’re used to their own IDE. Well, it’s normal. HackerRank, Codility and their ilk try to cater for different languages in-browser, and do so very badly. Additionally, they hide tests from users instead of being clear about requirements. Any developer would need time to adjust to a different IDE they aren’t comfortable with. Let’s face it: the only reason companies use such online assessment tools is that they scale better, so they’re obviously not trying to make the candidate comfortable.

So, I’ve been at both ends of coding exercises, and I’ve thought and discussed at length about the pros and cons, but I remain of the opinion that coding exercises are a waste of time that assess the wrong skills. As I mentioned before, the most important things to assess in a candidate are whether they can think and communicate.

Scoring

Once you have some candidates that made it through the interview process, you still need to choose which one(s) you want to actually hire. Perhaps you have 25 promising candidates and only one vacancy.

What some people do is come up with a scoring system and give a number for different areas. For instance, you could give each candidate a score of 1-5 in areas such as Python (or whatever specific programming language you’re after), SQL, NoSQL, cloud, etc.

I’m not a fan of this approach because I don’t believe it’s as simple as reducing the answers to a number. What does it mean if two candidates both scored 3.5? They almost certainly didn’t say the same things.

As I mentioned before, I’m more of a fan of open-ended questions, and this obviously doesn’t help scoring in a quantitative way. But, if you take note of the answers, you can later compare candidates qualitatively based on how well they answered, as well as any concerns you might have noticed during the interview. This then helps to make a relative comparison, because in the end that’s what you need to do. You don’t need to determine which candidate got 90% or over in an exam. You need to compare the candidates based on the signals you got in their answers, and the only reasonable way I know to do that is to reason about them individually and compare. The alternative of reducing them to numbers is really just a way of losing information.

Hiring

Once your best candidates are chosen, it’s time to extend them an offer. This is higher up the ladder than I’ve been directly involved with, but typically it’s a matter of things like (a) salary negotiation, (b) timing, (c) competition with other offers, and (d) the contract being acceptable.

Onboarding

After the vacancy is filled and the candidate is hired, it’s the end of the recruitment process, but it’s really just the beginning. A romantic relationship does not end with marriage, or so many of us hope.

It’s now time to nurture the new hire and help them become successful. That means being there for them from the beginning, helping them get everything set up, guiding them through the company’s processes, and explaining the essentials of the work they will be doing (such as the architecture of the codebase).

There is a scene from Jurassic Park in which John Hammond says he is always present when a new dinosaur is born, and it helps establish a bond of trust. It’s the same in software engineering. All too often, when I joined a company, people have been too busy to give me any attention and it didn’t do much to help my motivation. Over the years, in every company I worked, I’ve tried to change that, always being there to help new hires get on their feet. It’s an investment, even if it slows down your output.

I also think it’s very important to give new hires real work. That doesn’t necessarily mean pushing code to production on the first day, as some companies love to boast. But, there’s no better way to demotivate an excited new hire than to ask them to read some policy documents, or do some work that you never felt like doing (e.g. adding some documentation, writing some unit tests, or adding some logging).

Instead, give them something real to do: add a feature, fix a bug, etc. Prepare them by giving them the necessary background into the system so that they know where to look, and then let them loose. It is fun for them to learn the system by actually contributing. A good developer can be productive in less than a week, rather than the usual expected 6 months, if you just give them the opportunity.

This also ties in with probation. Most companies have a probation period, which could be anything between 3 months and a year, in which either the candidate or the company can terminate the employment contract with short or no notice for any reason. The idea is mainly to ensure that new hires are competent and can pull their own weight within a reasonable time, but in practice, managers are often too busy to check in with them and these new hires are often not given meaningful work until several months after their start date. By then, the probation period is past, and it’s too late to terminate a problematic employee in the rare cases that it’s necessary.

Retention

Nurturing doesn’t stop at onboarding either. Throughout the employee’s tenure with the company, it’s necessary to keep the relationship healthy. There are various mechanisms to do this, ranging from periodic reviews to weekly one-to-ones. This is an in-depth topic that some books cover in some detail, but the important thing is to maintain a rapport of respect and professionalism, and promptly address any issues as they arise.

It’s also kind of wrong that everyone (including this article) focuses so much on hiring and so little on retention. If companies took better care of their employees, they wouldn’t have such high turnover, and would need to spend much less money and effort on continuous hiring.

Conclusion

Hiring people is not easy, and hiring software engineers or similar roles comes with its own quirks and challenges. Many interviewees are rightfully frustrated by the processes they have to deal with every time they apply for a new job, but at the same time, they are not always aware of the dynamics that take place on the other side.

As interviewers, we can give candidates a better experience and also project a better image of the company we work for by being a little more prepared. This means analysing the individual needs of the company and trying to identify the best way to match candidates to those needs, instead of looking at other companies for inspiration. Other companies can provide ideas, but the context is usually different, so they need to be applied with caution.

It’s also fundamental to consider the entire hiring process, as well as the candidate’s future with the company after joining, in order to make the best of this. Hiring someone is a huge financial investment, a big part of team dynamics, and also has various personal implications (I’m thinking of around 15,000 people who recently lost their jobs at Meta and Twitter alone due to reckless management). It’s worth getting this right, because the worst thing you can do is give hiring a low priority and hire the wrong person. It can and will destroy team or company culture.

Formatting JSON in Visual Studio Code

If you have some minified string of JSON data (e.g. from an HTTP response), it’s quite common to want to format it in a way that’s a little more readable to a human being. In Visual Studio Code (VS Code), this can be a little tricky the first time, depending on whether the JSON is in a file or not.

Note: shortcuts provided are for Linux, and may vary on Windows or Mac.

Formatting a JSON File

Let’s start with the simple scenario: you have a .json file open in VS Code. All you have to do is right-click and select the “Format Document” option (or use the keyboard shortcut, Ctrl+Shift+I:

Just right-click and select “Format Document“, or press Ctrl+Shift+I.

This formats the JSON quite nicely:

The resulting formatted JSON.

Formatting JSON From Clipboard

A more common scenario for me is to copy a chunk of JSON and paste it directly into VS Code, without saving it first.

Press Ctrl+N or select File -> New Text File from the application menu to open a new/unsaved file, and paste a chunk of JSON into it. If you right-click in this case… there’s no “Format Document” option!

If it’s not a file, it’s not so simple any more… there’s no “Format Document” option.

The problem is that VS Code doesn’t know that this chunk of text you pasted is actually JSON. In order to tell it exactly this, press Ctrl+Shift+P, start typing “Change“, then select “Change Language Mode“:

Press Ctrl+Shift+P, then select “Change Language Mode“.

Then, start typing “JSON” and select it when it comes up:

Select “JSON” from the list of languages.

At this point, you’ll see the JSON get syntax highlighting, and the “Format Document” option is now available:

Format Document” is now possible.

…and here’s the result:

The JSON is nicely formatted and human-readable.