AI assistants such as ChatGPT, Claude, Copilot and Cursor can write a working feature in minutes. Working is not the same as safe, though. The assistant writes what you asked for, and security is usually something nobody asked for.
The mistakes below are not unique to AI. People make them too. They are simply easy to accept when code arrives quickly and looks finished. Each one comes with a quick way to check your own code and a fix.
1. Secrets written straight into the code
Ask for an example that calls a payment or email API and you will often get the key written inline. If you paste your real key into the prompt, it ends up in the file, then in Git, then possibly on GitHub.
# Risky: the key travels with the code
client = PaymentClient(api_key="sk_live_51H...")Read keys from the environment or a secret manager instead, and keep your .env file out of Git.
import os
client = PaymentClient(api_key=os.environ["PAYMENT_API_KEY"])Check: search your project for key =, secret, password and token. If a real key was ever committed, rotate it. Deleting the line is not enough, because it stays in the Git history.
2. Database queries built from strings
Assistants often build SQL with string formatting because it reads clearly. If any part of that string comes from a user, it is an SQL injection risk.
# Risky: a crafted email can change the query
cursor.execute(f"SELECT * FROM users WHERE email = '{email}'")Use parameters, so the database treats the value as data and never as part of the query:
cursor.execute("SELECT * FROM users WHERE email = %s", (email,))The same rule applies to every language and every library: pass values as parameters, never by joining strings.
3. Missing checks on who can see what
This is the hardest one to spot, because the code works perfectly in a demo. An endpoint such as /invoices/1042 loads invoice 1042, but never checks that it belongs to the person asking. Change the number in the address and you can read someone else's invoice.
# Risky: any signed-in user can read any invoice
invoice = db.get_invoice(invoice_id)
# Safer: only look among the current user's invoices
invoice = db.get_invoice(invoice_id, owner_id=current_user.id)Check: for every page or API route that takes an ID, ask "what stops another customer from changing this ID?" If the answer is nothing, fix it. Automated tools struggle here, so this is where a person reviewing the code earns their keep.
4. Running commands or code with user input
Code that calls the shell or evaluates text is quick to write and easy to abuse.
# Risky: a file name like "a.txt; rm -rf /" runs a second command
subprocess.run(f"convert {filename} out.png", shell=True)
# Safer: arguments as a list, no shell
subprocess.run(["convert", filename, "out.png"], check=True)Avoid eval, exec and pickle.loads on anything a user can influence. If you need to accept a choice from a user, compare it against a fixed list of allowed values.
5. Outdated or made-up packages
Assistants learned from code written years ago, so they often suggest old package versions with known vulnerabilities. Sometimes they suggest a package that does not exist at all. Attackers have started publishing packages under those invented names, hoping someone installs one.
- Before adding a package, check that it exists, is maintained and is the one you meant.
- Pin versions in a lock file.
- Check your dependencies against known advisories with
pip-audit,npm auditor the free OSV database.
A simple routine for AI-written code
- Read the code before you accept it, especially anything that touches login, payments, files or the database.
- Ask the assistant directly: "What are the security risks in this code?" It is often good at answering, even when it did not volunteer the information.
- Run an automated scan. Our free scanner checks code from a ZIP file or a GitHub, GitLab or Bitbucket repository for the patterns above, and shows each finding with a suggested fix.
- Have a person review the parts that handle money or personal data.
AI makes writing code faster. A few minutes of checking keeps it from making mistakes faster too.