Skip to content

Job & Recruitment Scams

💡
Before you start

Python 3 and a terminal. No employer is contacted, no money is involved, and every company and person named below is invented. macOS and Linux include Python; on Windows install it from python.org with “Add python.exe to PATH” ticked, then check with python3 --version.

The five files are independent — each one runs on its own, so you can do them in any order or stop after the ones that apply to you. If you are reading this because something has already happened, step 2 explains the cheque timing and step 3 explains the legal position, and both are worth reading before you contact anyone.

Why a Job Offer Is the Perfect Pretext

Most scams have to talk you into something unusual. A job scam does not. Everything it asks for is exactly what a real employer would ask for: your full name and address, your date of birth, a copy of your passport or driving licence, your bank details for payroll, and software installed on your computer so you can start work.

That is what makes this category so effective. The requests are not suspicious in isolation — they are only suspicious because the company does not exist. And the victim is, by definition, motivated: someone looking for work is hopeful, often under financial pressure, and reluctant to annoy a prospective employer by asking awkward questions.

The FBI has issued public warnings about criminals using fake job listings to harvest applicants' personally identifiable information, noting that the data is then used for account takeover, opening financial accounts, and creating fraudulent identity documents.

💡
The single rule that defeats the whole category.

You applied, or you did not. If a recruiter contacted you out of the blue, do not proceed through any channel they supplied. Go to the company's real website yourself and apply or enquire there. Everything below is detail on why that works.

The Five Variants

  • Identity harvesting -- The "job" progresses quickly to an offer, then asks for identity documents and bank details for onboarding. There is no job; there is a complete identity package. This is the most common and the most damaging, because unlike a password you cannot reissue your date of birth
  • Malware delivery -- You are told to install a "company VPN", a "work-from-home security suite", a proprietary chat client, or a coding assignment. The installer is a remote-access trojan or an infostealer. Developers are targeted with repositories whose build step runs the payload
  • Advance-fee -- Payment is requested for training, certification, equipment, or a background check, sometimes with a promise of reimbursement in the first paycheque. Legitimate employers never charge you to be hired
  • Money mule recruitment -- The "role" involves receiving payments into your own bank account and forwarding them, or buying cryptocurrency on the company's behalf. This is money laundering. The victim can be prosecuted, and being deceived is not automatically a defence
  • Task scams -- App-based "work" rating products or completing sets of tasks. Small withdrawals succeed, then you must deposit your own money to unlock a higher-earning tier. This is the investment-scam engine wearing a job costume

What Modern Ones Look Like

Advice written five years ago tells you to look for bad grammar. That test has stopped working, and repeating it gives false confidence.

  • The company is real -- attackers impersonate genuine, well-known employers rather than inventing one, so your research confirms the company exists
  • The careers site is a near-perfect clone on a lookalike domain: an added hyphen, a swapped letter, .careers or .co instead of the real suffix
  • The recruiter profile looks established -- aged social profiles, plausible history, and an AI-generated photograph that will not reverse-image-search to anything
  • The interview happens -- often on a lesser-known conferencing app, occasionally with a real-time face-swap impersonating a named executive
  • The written material is flawless -- job descriptions, contracts and offer letters are generated and read perfectly
⚠️
"I checked the company and it was real" is not verification.

Of course it is real -- that is the point of the impersonation. The question is never whether the company exists. It is whether the person messaging you works there, and whether the site you are on belongs to them.

The Signals That Still Work

  • They contacted you first, for a role you never applied to, and the process moves unusually fast
  • An offer arrives with little or no real assessment -- a genuine employer does not hire a stranger after a ten-minute chat
  • The domain is not the company's own -- read the part immediately before the first single slash, character by character. Correspondence from a free webmail address for a large employer is decisive
  • Interviews avoid live video, or use a text-only chat app with an email-based account rather than a corporate system
  • Identity documents are requested before a signed contract. Passport scans belong at onboarding with a verified employer, never at application
  • You are asked to pay for anything, or to buy equipment with a cheque they send you -- the cheque will bounce after you have spent the money
  • You must install software from a link rather than from the vendor's official site or a managed company device
  • Money passes through your personal account in any form
  • Pressure and secrecy -- an exploding deadline, or instructions not to discuss details with anyone

Verifying an Offer Properly

1
Navigate to the company yourself.

Type the address or use a search engine — never a link from the message. If the vacancy is real it will be on their own careers page. If it is not listed, that is your answer.

2
Phone the company's published switchboard.

Ask whether the recruiter works there and whether the role exists. Use the number from their real website, never one supplied in the correspondence.

3
Compare the domain letter by letter.

Put the real address and the one you were given side by side. Lookalike domains are designed to survive a glance, not a comparison.

4
Stage what you hand over.

A CV early. Identity documents only after a signed contract with a verified employer. Bank details last. There is no legitimate reason to reverse that order.

5
Never install their software on your own machine.

Real employers issue managed devices or use mainstream tools you already have. If you must run an assessment, use a throwaway virtual machine — never the computer holding your email, banking or crypto.

If You Have Already Engaged

  • If you installed something -- treat the device as compromised. Follow the infostealer recovery order: clean or rebuild the machine first, then revoke active sessions, then change passwords from a different device. Changing passwords on an infected machine just hands over the new ones
  • If you sent identity documents -- freeze your credit with the relevant bureaus, tell your bank to expect impersonation attempts, and consider a protective registration or fraud marker where your country offers one
  • If you gave bank details -- alert your bank. Account number and sort code alone are lower risk than full card details, but the account should be watched
  • If money moved through your account -- stop immediately and contact your bank and the police yourself. Self-reporting matters enormously here; continuing makes your position far worse
  • Report the listing to the job board, the impersonated company, and your national cybercrime service (ic3.gov in the US). Companies can only take down clone sites they know about

Check a Job Offer the Way a Fraud Investigator Would, in Five Steps

Job fraud is aimed at people who need work, which means it arrives at exactly the moment somebody is least able to walk away from it. The defences that matter are therefore mechanical rather than intuitive — things you can check in two minutes without deciding whether you feel suspicious, because feeling suspicious is a luxury of people who are not worried about rent. In the next twenty minutes you will verify an employer without asking them anything, follow the overpayment cheque through to the day the bank takes it back, see what a “payment processing” role actually is in law, and finish with a single rule that covers every variant. Every line of output below came from running these files.

1
Check the employer, not the offer

Go: open a terminal in a folder you can write to — cd ~/Desktop on macOS or Linux, cd %USERPROFILE%\Desktop on Windows.

Do: save this as employer.py and run python3 employer.py.

"""Check the employer, not the offer."""

FREE_MAIL = {"gmail.com", "outlook.com", "hotmail.com", "yahoo.com", "proton.me",
             "icloud.com", "mail.com"}

OFFERS = [
    ("Northwind Components", "hr@northwind-components.co.uk", "northwind-components.co.uk"),
    ("Northwind Components", "northwind.hr2026@gmail.com",    "northwind-components.co.uk"),
    ("Northwind Components", "careers@northwind-careers.net", "northwind-components.co.uk"),
    ("Brightpath Supplies",  "recruit@brightpath-supplies.com", "brightpath-supplies.com"),
]

for company, sender, real_domain in OFFERS:
    domain = sender.split("@")[1].lower()
    if domain in FREE_MAIL:
        verdict = "FREE MAILBOX -- anyone can open one in this company's name"
    elif domain != real_domain:
        verdict = "DIFFERENT DOMAIN -- not %s" % real_domain
    else:
        verdict = "matches the company's own domain"
    print("%-22s %-32s %s" % (company, sender, verdict))

print()
print("The company's real domain is the one you find yourself -- from the")
print("website you reached by typing its name into a search engine, not from")
print("a link in the message. Everything else is chosen by the sender.")

You should see: two offers that fail on the address alone:

Northwind Components   hr@northwind-components.co.uk    matches the company's own domain
Northwind Components   northwind.hr2026@gmail.com       FREE MAILBOX -- anyone can open one in this company's name
Northwind Components   careers@northwind-careers.net    DIFFERENT DOMAIN -- not northwind-components.co.uk
Brightpath Supplies    recruit@brightpath-supplies.com  matches the company's own domain

The company's real domain is the one you find yourself -- from the
website you reached by typing its name into a search engine, not from
a link in the message. Everything else is chosen by the sender.

The third row is the one worth studying, because it is not obviously wrong: northwind-careers.net is a plausible domain for a recruitment arm, and plenty of real companies do use separate hiring domains. That is exactly why the check is written as a comparison against a domain you established, rather than as a judgement about whether an address looks reasonable.

How to establish it: search for the company by name, open the site you find, and read the address in your browser's own address bar. Do not follow a link from the message, and do not accept a domain because it appears in the signature — both are supplied by the person you are checking.

If not: if every row reports a match, the real_domain values were made identical to the sender domains; they are the third item in each tuple and are deliberately different for rows two and three.

2
Follow the overpayment cheque to the end

Go: the same folder.

Do: save this as cheque.py and run python3 cheque.py.

"""'Funds available' is not 'the cheque cleared'. The gap is the whole scam."""

DAY = {0: "cheque deposited",
       1: "bank shows funds available -- you can spend them",
       2: "you buy the equipment and wire the surplus",
       9: "the cheque is returned unpaid; the bank reverses the credit"}

cheque = 3800.00
equipment_cost = 800.00
wired_to_their_supplier = 3000.00

for day in sorted(DAY):
    print("day %-2d %s" % (day, DAY[day]))

print()
print("credited to your account   : %8.2f" % cheque)
print("reversed on day 9          : %8.2f" % -cheque)
print("money you sent out         : %8.2f" % -(equipment_cost + wired_to_their_supplier))
print("-" * 44)
print("your position              : %8.2f" % (cheque - cheque - equipment_cost - wired_to_their_supplier))
print()
print("The bank is not being unfair. 'Available' means they have advanced")
print("you the money while the cheque travels. When it fails, they take it")
print("back -- and what you sent onward is gone.")

You should see: a loss equal to the entire cheque:

day 0  cheque deposited
day 1  bank shows funds available -- you can spend them
day 2  you buy the equipment and wire the surplus
day 9  the cheque is returned unpaid; the bank reverses the credit

credited to your account   :  3800.00
reversed on day 9          : -3800.00
money you sent out         : -3800.00
--------------------------------------------
your position              : -3800.00

The bank is not being unfair. 'Available' means they have advanced
you the money while the cheque travels. When it fails, they take it
back -- and what you sent onward is gone.

The critical idea is the difference between available and cleared. When a cheque or a transfer is credited to your account, many banks make the money spendable immediately as a convenience — they are lending it to you while the payment is verified behind the scenes. That verification can take a week or more, and if the payment turns out to be fraudulent or the account it came from is reversed, the credit is taken back in full.

So “I checked, the money is definitely in my account” is not evidence of anything, and it is the sentence the whole scheme is built around. The window between the credit appearing and it being reversed is not a flaw somebody is exploiting; it is the product.

If not: the numbers are constants and should match exactly. If your position prints a positive number, the signs in the final subtraction were changed — the cheque is credited and then removed, so it cancels itself and what remains is what you sent out.

3
Find out what the job actually is

Go: the same folder.

Do: save this as mule.py and run python3 mule.py.

"""'Payment processing agent': what the job actually is."""

payments = [
    ("Mrs A. Doyle",  2400.00, "she believes she is buying a caravan"),
    ("R. Ferreira",   1750.00, "he believes he is paying a deposit on a flat"),
    ("K. Osei",       3100.00, "she believes she is paying an invoice"),
]

commission_rate = 0.08
total_in = sum(a for _, a, _ in payments)

print("%-16s %10s   %s" % ("MONEY ARRIVES FROM", "AMOUNT", "WHAT THEY THINK IT IS"))
print("-" * 78)
for who, amount, why in payments:
    print("%-16s %10.2f   %s" % (who, amount, why))

commission = total_in * commission_rate
forwarded = total_in - commission

print()
print("total through your account : %10.2f" % total_in)
print("your 'commission'          : %10.2f" % commission)
print("forwarded abroad           : %10.2f" % forwarded)
print()
print("What the bank's records show: three victims paid YOU, and you moved")
print("the money on. Your name, your account, your identity documents.")
print()
print("The legal term for the role is money mule. It is prosecuted, the")
print("account is closed, and being deceived is not automatically a defence.")

You should see: three victims, one intermediary, and whose name is on it:

MONEY ARRIVES FROM     AMOUNT   WHAT THEY THINK IT IS
------------------------------------------------------------------------------
Mrs A. Doyle        2400.00   she believes she is buying a caravan
R. Ferreira         1750.00   he believes he is paying a deposit on a flat
K. Osei             3100.00   she believes she is paying an invoice

total through your account :    7250.00
your 'commission'          :     580.00
forwarded abroad           :    6670.00

What the bank's records show: three victims paid YOU, and you moved
the money on. Your name, your account, your identity documents.

The legal term for the role is money mule. It is prosecuted, the
account is closed, and being deceived is not automatically a defence.

Roles advertised as “payment processing agent”, “financial co-ordinator”, “local representative” or “transaction assistant” are almost always this. The work genuinely exists, the commission is genuinely paid, and it is genuinely a criminal offence — because the money passing through the account is the proceeds of frauds committed against other people, and moving it is laundering it.

The consequences are practical and long-lasting. Bank accounts are closed and the closure is shared between institutions, which can make opening another one difficult for years. Prosecution is a real outcome, not a theoretical one. And “I thought it was a job” is a defence you have to persuade someone of, not a fact that ends the matter.

If not: if the commission is zero, commission_rate was set to 0; it should be 0.08. The totals derive from the list, so adding a fourth payment will correctly change every figure below it.

4
Look at what the onboarding pack is really collecting

Go: the same folder.

Do: save this as identity.py and run python3 identity.py.

"""The 'onboarding pack' that arrives before any contract does."""

ASKED_FOR = [
    ("passport scan",              "open a bank account in your name"),
    ("national insurance number",  "claim benefits or file tax in your name"),
    ("date of birth + address",    "pass telephone identity checks"),
    ("a selfie holding the passport", "defeat photo identity verification"),
    ("bank account and sort code", "receive fraudulent payments as you"),
    ("mother's maiden name",       "answer security questions"),
]

print("%-34s %s" % ("DOCUMENT REQUESTED", "WHAT IT IS ENOUGH TO DO"))
print("-" * 84)
for item, use in ASKED_FOR:
    print("%-34s %s" % (item, use))

print()
print("items requested :", len(ASKED_FOR))
print("interviews held :", 0)
print("contract signed :", "no")
print()
print("Collected together, this is not employment paperwork -- it is a")
print("complete identity. A real employer asks for right-to-work documents")
print("AFTER an offer, and never for a security-question answer at all.")

You should see: six documents and no interview:

DOCUMENT REQUESTED                 WHAT IT IS ENOUGH TO DO
------------------------------------------------------------------------------------
passport scan                      open a bank account in your name
national insurance number          claim benefits or file tax in your name
date of birth + address            pass telephone identity checks
a selfie holding the passport      defeat photo identity verification
bank account and sort code         receive fraudulent payments as you
mother's maiden name               answer security questions

items requested : 6
interviews held : 0
contract signed : no

Collected together, this is not employment paperwork -- it is a
complete identity. A real employer asks for right-to-work documents
AFTER an offer, and never for a security-question answer at all.

Any one of these requests is ordinary in the right context. Arriving together, before any interview and before any contract, they are not onboarding — they are an identity being assembled, and the “job” is the pretext that makes handing it over feel routine.

The sequence is what tells you. A real employer interviews you, makes an offer, sends a contract, and only then asks for right-to-work documents, because until there is an offer they have no lawful reason to hold them. Anything that reverses that order is worth refusing, politely and without explanation. And no employer, ever, needs your mother's maiden name — that request has exactly one purpose, which step 3 of the social-engineering material covers in detail.

If not: this script prints a fixed list, so it cannot fail; if the columns misalign, widen the terminal to 84 characters.

5
Reduce all of it to one rule

Go: the same folder.

Do: save this as direction.py and run python3 direction.py.

"""One rule, applied to eight things a 'job' might ask for."""

REQUESTS = [
    ("your CV",                                   "none",     "normal"),
    ("a video interview on a scheduled call",     "none",     "normal"),
    ("proof of identity AFTER a signed contract", "none",     "normal"),
    ("your bank details for salary",              "none",     "normal, once hired"),
    ("payment for a background check",            "you pay",  "NO -- employers pay for these"),
    ("payment for training materials",            "you pay",  "NO -- employers provide these"),
    ("buy equipment, we reimburse you",           "you pay",  "NO -- reversed later"),
    ("receive a payment and forward most of it",  "you move", "NO -- this is money laundering"),
]

print("%-44s %-10s %s" % ("WHAT IS ASKED FOR", "MONEY", "VERDICT"))
print("-" * 92)
for what, money, verdict in REQUESTS:
    print("%-44s %-10s %s" % (what, money, verdict))

bad = sum(1 for _, m, _ in REQUESTS if m != "none")
print()
print("requests involving money moving from or through you:", bad)
print("of those, legitimate:", 0)
print()
print("THE RULE: in a real job, money moves in exactly one direction --")
print("from the employer to you, after you have worked. Anything else is")
print("either a fraud or a crime you are being recruited into.")

You should see: four requests involving money, none of them legitimate:

WHAT IS ASKED FOR                            MONEY      VERDICT
--------------------------------------------------------------------------------------------
your CV                                      none       normal
a video interview on a scheduled call        none       normal
proof of identity AFTER a signed contract    none       normal
your bank details for salary                 none       normal, once hired
payment for a background check               you pay    NO -- employers pay for these
payment for training materials               you pay    NO -- employers provide these
buy equipment, we reimburse you              you pay    NO -- reversed later
receive a payment and forward most of it     you move   NO -- this is money laundering

requests involving money moving from or through you: 4
of those, legitimate: 0

THE RULE: in a real job, money moves in exactly one direction --
from the employer to you, after you have worked. Anything else is
either a fraud or a crime you are being recruited into.

The value of the rule is that it needs no expertise and survives variants you have never seen. It does not ask you to recognise a particular scam, judge whether a company sounds real, or spot a badly written email — frauds have improved on all three. It asks a single factual question about the direction money travels, and the answer is available before you have committed to anything.

Two legitimate-looking exceptions people ask about. Some genuine roles do require you to buy your own tools, and some genuinely reimburse expenses — but never before you are employed, never through a supplier the employer nominates, and never with money the employer sent you first. If all three of those are present, the pattern is the one in step 2, no matter how the job is described.

If not: if requests involving money prints something other than 4, a row's middle field was changed — four rows carry a value other than "none".

🎉
Check yourself before moving on

Without scrolling up: a remote role offers good pay, the interview happened over a chat app, and the company asks you to buy a specific laptop from a supplier they name, promising reimbursement with your first payslip. They have already sent the money, and it is showing in your account. What is happening, and what do you do? Answer: this is the overpayment pattern from step 2. The money showing in the account is available, not cleared — the bank has advanced it while the payment is verified, and when the payment is reversed the credit is taken back in full while whatever you paid the nominated supplier is gone. The nominated supplier is the tell: a real employer buying you equipment buys it themselves, and a real reimbursement happens after you spend your own money, not before. What to do is straightforward: send nothing, buy nothing, and do not spend the credit. Ring your bank on the number on your card, tell them you believe you have received a fraudulent payment, and ask them to return it. Then verify the company independently — step 1's method — and if you want to be certain, telephone the company's published switchboard and ask whether the person who contacted you works there.

Now do it without the page: extend direction.py with three requests taken from a real advert you have seen, and decide for each whether money moves from, to, or through you. Then do the check that catches most of these before anything else: search the exact wording of the offer's opening sentence in quotation marks. Recruitment fraud is sent at volume, so identical text appears in many places at once, and a phrase that returns dozens of unrelated companies has answered the question for you.

Summary

  • Job scams ask for exactly what real employers ask for -- which is why the requests never feel wrong
  • The company being real proves nothing -- impersonation is the method
  • Grammar checks are obsolete; domain checks are not
  • Nobody legitimate charges you to be hired, and nobody routes company money through your personal account
  • Never install an employer's software on your personal machine before the employer is verified
  • Stage your disclosures -- CV, then contract, then identity, then bank
🎉
Asking is not rude.

A real employer will not withdraw an offer because you rang the switchboard to confirm it. Anyone who reacts badly to being verified has told you what you needed to know.