You get a message: "Your account is locked. Confirm your details here." The link on the button says mybank.example somewhere in it. Is it safe? Most beginners (and plenty of experienced people) check whether the bank's name appears in the link. That check is wrong, and this article shows what to look at instead.
A web address is called a URL (Uniform Resource Locator). Here is a full one, split into pieces:
https://mybank.example:8443/login?next=/home#top
\___/ \___________/\___/\____/ \_______/ \__/
scheme host port path query fragment
The scheme (https) says how to talk. The host says which computer to ask. The port is an optional door number on that computer. Everything after the first single / (the path, query and fragment) is just instructions handed to whoever owns the host: which page, which options. That is the key idea: only the host decides who you are talking to. Anything the host's owner wants can appear in the path, including the words "mybank".
Host names are made of labels separated by dots, and they get more specific from right to left. In login.mybank.example, the last label example is the top-level domain (like com or org). Someone registers one name beneath it, here mybank, and that owner may then create as many labels in front of it as they like (login., help., anything.). So the owner of the site is the last two labels (for endings like .co.uk it is the last three, because co.uk is itself shared; browsers use a maintained list called the Public Suffix List to know).
That means login.mybank.example belongs to mybank.example, but mybank.example.secure-check.test belongs to secure-check.test. The bank's name sits at the front, where anyone who registered secure-check.test can put whatever they like.
There is one more trap. A URL may contain a username before an @: https://user@host/. It is an old feature and browsers still parse it, so the real host is what comes after the @. Let's ask a real URL parser. This is JavaScript that runs in any browser or in Node.js:
const u = new URL("https://[email protected]/login");
console.log(u.hostname); // evil.test
console.log(u.username); // mybank.example
Output when we ran it:
evil.test
mybank.example
The part that looks like the bank is just a "username" typed into the other site's address.
.example is reserved for examples, so none of these are real sites.)Look at the link, decide, then tap an answer.
Look-alike names. rnybank.example uses r and n next to each other to imitate an m. A hyphen or an extra word (secure-mybank) makes a completely different name. The fix is the same as before: read the owner part slowly, letter by letter.
Look-alike letters. Domain names can contain letters from other alphabets. The Cyrillic а looks like the Latin a but is a different character. Under the hood such names are stored in a plain-ASCII form that starts with xn--. We asked Node to parse a name with a Cyrillic first letter:
console.log(new URL("https://аpple.example/").hostname);
// xn--pple-43d.example
Browsers have rules about when they show the original letters and when they show the xn-- form, but you cannot rely on spotting the difference by eye.
Shortened links. A link shortener hides the host until you open it. Be extra careful with those in messages you did not expect.
Reading the owner is a good habit, but it is not the whole defence, because a real site can also be hacked and a good fake can be convincing. A more reliable habit is to not use the link at all: type the bank's address yourself or use a bookmark you made earlier, then log in there. If the message was real, the notice will be waiting in your account.
A few more rules of thumb that hold up:
https only mean your connection to that host is encrypted. Fake sites can have them too, so they do not tell you who owns the site.You now have a skill that works for every link you meet: ignore the words, find the end of the host, and read the last two labels.