Learning paths / Vibe coding to production / Security of AI-written code

Injection, invented packages and licences

Reading · 6 min · Module 6, lesson 3 of 411 min left in this module

Module 6 · Security of AI-written codeLesson 3 of 4

Goal: Recognise injection bugs, check a suggested dependency before installing it, and know whose licence covers the code you ship.

3:59 · captions and chapters · narrated with an AI-generated voice
Transcript

Narration uses an AI-generated voice.

[00:00] Where we're going

By the end of this video, you'll be able to spot three risks in an agent's change. Injection. Invented packages. And licences. All three look like working code. None fails a test unless you write one for it.

[00:16] Injection

Start with injection: text from a user, pasted into something that runs. A database query. A web page. A spreadsheet formula. You met one in lesson four point four point two: a task title that became a spreadsheet formula.

Here's the same bug in SQL, in an agent's new search route. The title comes straight from the request, and it's pasted into the query text. So the title becomes part of the query itself. A crafted title can close the quote and add its own condition. Now the query returns every row.

[00:54] Keep data apart

The fix is a placeholder. The query says dollar one, and the title travels separately, as data. The database never reads the title as SQL, so it can't be rewritten.

The rule is the same everywhere: pass data separately, the tool's way. Placeholders, for SQL. Text content rather than inner HTML, for web pages, as the starter's page already does. And escaping, for CSV. So when user input reaches something that runs, ask how the data is kept separate.

[01:31] Invented packages

Next, invented packages. Agents sometimes name packages that don't exist, because the name sounds right. They reuse the same invented names, so attackers publish real packages under them, with harmful code inside. That's slopsquatting. Its cousin, typosquatting, uses names one typo from a popular package. And installing runs a package's scripts on your machine.

[01:57] Four checks

Before any new dependency goes in, four checks. First, do you need it? Most briefs should say no new dependencies. Second, find it yourself on the registry, with the exact spelling. Third, is it alive? A source repository, releases, a known maintainer, real downloads. Fourth, read the diff to package dot json and the lockfile. A dependency you didn't ask for is a scope change.

[02:28] Check the registry

npm view shows a package's page on the registry. Express is real. Hundreds of versions, a homepage, known maintainers, and a recent release. Ask for its repository, and you get a link to its source. Now a name that sounds just as right. Not found. It doesn't exist, so it never gets installed.

[02:51] Licences

Last, licences. Each one says what you may do with the code. Express uses MIT, a permissive licence. Some licences require you to publish your own source if you ship theirs. Agents don't check this. You do.

Generated code can also closely resemble public code. So read your agent's terms on who owns its output, and whether it filters matches with public code. For anything commercial, ask someone qualified, early.

[03:24] Recap

To recap. Keep user data apart from anything that runs. Check a new package on the registry yourself, before it's installed. Know what each licence lets you do. None of these fails a test, so look for them in every review.

Check yourself. An agent suggests a package you've never heard of. What do you do first? Look it up on the registry yourself, and check it's real. Or skip the dependency. Next, check what you've learned.

Key idea

Three risks look exactly like working code. Injection: user text gets treated as instructions. Invented packages: a dependency that doesn't exist, or isn't what it seems. Licences: code you don't have the rights to ship. None of them fails a test unless you write one for it.

Injection: keep data apart from instructions

Injection happens when text from a user is pasted into something that runs: a database query, a web page, a spreadsheet formula. You met one in lesson 4.4.2: a task titled =1+1 became a formula in the CSV export.

The same bug in SQL looks like this:

// Unsafe: the title becomes part of the query itself
db.query(`SELECT * FROM tasks WHERE title = '${title}'`);

// Safe: the query has a placeholder; the title travels separately, as data
db.query("SELECT * FROM tasks WHERE title = $1", [title]);

A title like ' OR '1'='1 rewrites the first query to return every row. The second can't be rewritten, because the database never reads the title as SQL.

The rule is the same everywhere: use the tool's way of passing data separately (placeholders for SQL, textContent rather than innerHTML for web pages, escaping for CSV). The starter's page already gets this right: it sets each title with textContent. When an agent builds a string out of user input and hands it to something that runs, stop and ask how the data is kept separate.

Invented packages

Agents sometimes name packages that don't exist, because the name sounds like one that should. They tend to invent the same names again and again, so attackers publish real packages under those names, with harmful code inside. It's called slopsquatting, a cousin of typosquatting: look-alike names one typo from a popular package.

Installing a package runs its install scripts on your machine, and its code ends up in your app. Before any new dependency goes in:

  1. Ask whether you need it. "No new dependencies" belongs in most briefs.
  2. Find it yourself. Open its page on the registry (npmjs.com for Node, pypi.org for Python) and check the exact spelling against the library's own documentation.
  3. Check it's alive and real. A linked source repository, a history of releases, more than one maintainer or a known one, and plenty of downloads.
  4. Read the diff to package.json and the lockfile. A dependency you didn't ask for is a scope change.

From the terminal, npm view express shows a real package's registry entry: versions, maintainers, homepage. npm view express repository.url prints where its source lives.

Licences

Every dependency comes with a licence that says what you may do with it. npm view express license prints MIT, a permissive one; some licences require you to publish your own source if you ship theirs. Agents don't check this when they add a package; you do.

Generated code can also closely resemble code from public repositories. Read your agent's terms on who owns its output and whether it filters matches with public code. For anything commercial, ask someone qualified before a licence question becomes a launch blocker.

Check yourself

An agent suggests installing a package you've never heard of that makes the feature 'one line'. What do you do first?
Which query is safe from SQL injection?