B Binance · The world's largest crypto exchangeBinance Sign up → AD OKX OKX · A leading global crypto exchangeOKX Sign up → AD
💻 Coding Basics · Lesson 10 / 10

Reading and Verifying AI-Written Code — Tests, Security, Licenses, Privacy

AI-written code can look convincing yet fail on edge cases or be unsafe. Reading the code, checking it with tests you wrote yourself, and reviewing secrets, packages, licenses and personal data is the job of the person who uses it.

⏱ About 24 min ✍️ 5 practice questions 🧪 4 code exercises Updated 2026-10-09
🎯 By the end of this lesson you can
  • Read an AI-written function line by line in input–process–output order and explain it
  • Write your own tests with empty values, 0 and boundary values to find and fix hidden bugs
  • Recognize security risks such as exposed secrets, missing input validation, eval and nonexistent packages
  • Say what to check for open-source license terms and for protecting personal data

1.Why you need to verify AI-written code

An AI coding assistant writes convincing code in seconds. The syntax is clean and the explanation sounds confident. But the AI produces "code shaped like what it has often seen"; it does not actually run it on your data in your situation before answering. So you can get code that is right for common inputs but wrong for empty or boundary values, or code that runs but is dangerous.

You are the one who runs the code and uses its results. If a sales total is wrong and a bad report goes out, or code containing a password becomes public, "the AI wrote it that way" is no excuse. Checking the results and taking responsibility falls to the person and organization that used the code. Everything you learned up to Lesson 9 — values, conditions, loops, functions, arrays and strings — is a tool for exactly this verification. If you can read short code yourself, you can use AI far more safely and effectively.

Verification has four main strands: reading the code to understand what it does, checking results with tests you wrote yourself, reviewing security risks, and checking issues outside the code such as licenses and personal data. This lesson practices them one by one in that order.

  • Reading: what does this function take, and what does it return?
  • Testing: do common inputs, empty values, 0 and boundary values give the expected result?
  • Security: are there secrets, unvalidated input, eval or unfamiliar packages?
  • Outside the code: were license terms, company or school policy, and personal data handled properly?

2.Reading line by line — input, process, output

When you read code an AI gave you, do not just skim it from top to bottom; fit it to the "input → process → output" frame from Lesson 1. Look at the function name and parameters to see what it takes, and find return to see what it gives back. Then go through the middle lines one at a time and say in words what each variable holds once that line has run. Any line where your explanation stalls is the place to check.

Ask "what if" questions as you read. What if the array is empty? What if the values come in as strings? What if they are 0 or negative? The average function below is correct for ordinary scores, but an empty array gives 0 / 0, which is NaN, and string scores taken from a CSV make + join text and produce a nonsense value. It is all the more dangerous because the wrong value comes out with no error message.

If you hit syntax you do not understand, it is fine to ask the AI to "explain what this line does for a beginner." But after hearing the explanation, print intermediate values with console.log as in Lesson 8 and check for yourself that the explanation matches reality. The explanation is also an AI answer, so it needs checking too.

Ordinary input gives the right answer. An empty array and string scores give wrong values with no error.
// A function an AI coding assistant wrote (as is)
function averageScore(scores) {
  let sum = 0;
  for (const s of scores) {
    sum += s;
  }
  return sum / scores.length;
}

console.log(averageScore([80, 90, 100]));
console.log(averageScore([]));
console.log(averageScore(["80", "90"]));
Output
90
NaN
4045

3.Writing your own tests — boundary values find bugs

A test means writing down in advance "this input should give this value" and checking it with code. You decide the expected value by hand before looking at the code. If you leave the tests to the AI as well, it may put the same misunderstanding into the tests as into the code, so write at least a few yourself. A small tool like the check function below, which compares the result with the expected value and prints PASS or FAIL, is all you need.

A good set of tests includes edge cases alongside ordinary cases: an empty array or empty string, 0, negative numbers, a single value, the exact value where a condition flips (the boundary values from Lesson 3), numbers with a different number of digits, and repeated values. Bugs usually hide at these edges.

Below is an "AI-written function that picks the top scores." Tested only with two-digit scores, it passes and looks correct. But it goes wrong once a score of 100 is included. Without a compare function, JavaScript's sort() converts values to strings and sorts them in dictionary order, so "100" comes before "80". On top of that, sort changes the order of the original array, so the caller's data is quietly changed too.

With only two-digit scores, you would never have found the bug. The original array changed too.
function check(name, got, want) {
  const same =
    JSON.stringify(got) === JSON.stringify(want);
  console.log(same ? "PASS" : "FAIL", name, got);
}

// AI-written function: the top n scores
function topScores(scores, n) {
  return scores.sort().reverse().slice(0, n);
}

check("two digits", topScores([70, 90, 85], 2), [90, 85]);
check("100 points", topScores([100, 95, 80], 2), [100, 95]);
check("n is 0", topScores([70, 90], 0), []);

const mine = [70, 90, 85];
topScores(mine, 1);
console.log("original", mine);
Output
PASS two digits [ 90, 85 ]
FAIL 100 points [ 95, 80 ]
PASS n is 0 []
original [ 90, 85, 70 ]
Sort a copy with the numeric compare function (a, b) => b - a to put the biggest numbers first.
function topScores(scores, n) {
  const copy = [...scores];
  copy.sort((a, b) => b - a);
  return copy.slice(0, n);
}

const mine = [100, 95, 80];
console.log(topScores(mine, 2));
console.log(topScores([], 3));
console.log("original", mine);
Output
[ 100, 95 ]
[]
original [ 100, 95, 80 ]
ExampleAn AI wrote a "shipping fee function" for you. The rule: orders of 50,000 won or more ship free; otherwise the fee is 3,000 won. Which tests should you include?
// AI-written function (as is)
function shippingFee(price) {
  return price > 50000 ? 0 : 3000;
}
for (const p of [49999, 50000, 50001]) {
  console.log(p, shippingFee(p));
}
Output
49999 3000
50000 3000
50001 0
  1. Step 1: Find the boundary in the rule. The value where the condition flips is 50,000 won.
  2. Step 2: Pick just below, at and just above the boundary: 49,999 won → 3,000, 50,000 won → 0, 50,001 won → 0.
  3. Step 3: Add extreme and odd values: decide first what should happen with 0 won, a negative amount and the string "50000".
  4. Step 4: When you run it, 50,000 won gives 3,000. Reading the code, it uses > instead of >=.
AnswerInclude the boundary value 50,000 won and the values on either side, plus 0, a negative amount and a string. In this example, the boundary test revealed that > must be changed to >=.
When you ask an AI for code, also ask for "a list of edge-case tests for this function." Add your own cases to that list, and decide the expected values yourself.

4.Security — secrets, input validation, `eval`

The first rule is to never put secrets such as passwords, API keys or access tokens into code or prompts. A key written in code easily leaks through file sharing, a repository made public or a screenshot. Pasting code that contains a key into an AI assistant while asking about an error carries the same risk. Replace the key with a fake value like "YOUR_API_KEY" when you show it, and keep the real key outside the code in the way each service recommends (environment variables, a configuration file, a secrets manager and so on). If a key has already been exposed, deleting it is not enough; revoke it with that service and issue a new one.

The second rule is input validation. Treat values from users, files and other programs as possibly different from what you expect, and check their shape and range before using them. AI-written code often assumes only "normal input." As below, the safe approach is to define the allowed shape first and reject everything else with null. "Accept only good values" misses less than "filter out bad values."

Third, never pass untrusted input to eval or new Function. eval runs a string as code, so commands hidden in the input can run as is. If you asked for a calculator or a settings reader and the AI gave you code that uses eval, ask for another approach. If the goal is to exchange data, read the JSON from Lesson 6 with JSON.parse. JSON.parse only reads data, never runs code, and throws an error if the format is wrong.

The regular expression ^\d+$ means "digits only, from start to end." Anything outside the allowed range is null.
// accepts only whole-number ages from 0 to 150
function parseAge(input) {
  const s = String(input).trim();
  if (!/^\d+$/.test(s)) return null;
  const n = Number(s);
  if (n > 150) return null;
  return n;
}

const tries = ["35", " 7 ", "-3", "2.5", "abc", "", "999"];
for (const x of tries) {
  console.log(JSON.stringify(x), "→", parseAge(x));
}
Output
"35" → 35
" 7 " → 7
"-3" → null
"2.5" → null
"abc" → null
"" → null
"999" → null
JSON.parse does not run a string that looks like code; it rejects it with a SyntaxError. try { … } catch (e) { … } is syntax that keeps going when an error occurs, catching the error in the catch part to handle it.
const input = '{"name": "Alex", "score": 90}';
const data = JSON.parse(input);
console.log(data.name, data.score);

try {
  JSON.parse("console.log('secretly run')");
} catch (e) {
  console.log("Rejected:", e.name);
}
Output
Alex 90
Rejected: SyntaxError

5.Nonexistent packages — check before installing

Real-world code often installs and uses packages (libraries) that others have built and published. But AI assistants sometimes make up plausible package names that do not actually exist, or recommend packages that stopped being maintained long ago. The bigger problem is that someone can publish a malicious package in advance under such a frequently invented name, or under a name one letter off from a popular package. If you run the install command without checking, someone else's code runs on your computer.

So before running an install command, check a few things: whether the package really exists in the official package registry, whether the name is spelled exactly as in the official documentation, whether it has been maintained recently, whether it has a public source repository and documentation, and whether it is widely used. Companies and schools may have an approved package list or a security review process, so follow those rules first.

For a small job, also ask whether it can be done without a package. The text cleanup and totals in Lesson 9 needed nothing beyond JavaScript's built-in features. The fewer packages you depend on, the less there is to check and the fewer places things can go wrong. That said, for jobs with tricky rules, such as reading real CSV files or encryption, choosing a well-tested package is safer than writing it yourself.

  • Does that name really exist in the official package registry?
  • Is the spelling exactly the same as in the official docs? (Watch for fake names one letter off)
  • Has it been updated recently, and is it maintained?
  • Are its source repository, documentation and license public?
  • Did you follow your company's or school's approved list and security procedures?

6.Copyright, licenses and personal data

Being public does not mean code is free to use however you like. Open-source code comes with a license, and a license is a promise: "you may use this if you follow these terms." The terms differ from license to license. A common term is to keep the copyright notice and license text along with the code, and some licenses require that when you distribute a program containing the code, you publish its source code under the same terms. Code with no license at all may not be licensed for use, even if it is publicly visible.

AI-written code may also closely resemble existing public code. Before putting a long piece of code straight into a product, check whether you can trace its origin and whether your company or school has a policy on AI-generated code and open-source use. The table below lists only general features of common types and is not legal advice. Read the license text for the actual terms, and when in doubt, ask the relevant department at your organization or an expert.

Personal data is another important issue outside the code. If you paste a real customer list, student grades or phone numbers while asking an AI for code, that information leaves your control. What you need to build code is the "shape" of the data, not the real values. As below, create fake data to show, and run the real data only on your own computer. For example addresses, use a domain reserved for documentation such as example.com, so nothing ever reaches a real person. When you share results, show only as much as needed, for example by masking the middle digits of phone numbers.

Instead of a real list, generate fake data in the same shape to show the AI.
function fakeCustomers(n) {
  const list = [];
  for (let i = 1; i <= n; i++) {
    const no = String(i).padStart(4, "0");
    list.push({
      id: i,
      name: "Customer" + i,
      phone: "010-0000-" + no,
      email: "user" + i + "@example.com",
    });
  }
  return list;
}
console.log(fakeCustomers(2));
Output
[ { id: 1, name: 'Customer1', phone: '010-0000-0001', email: '[email protected]' }, { id: 2, name: 'Customer2', phone: '010-0000-0002', email: '[email protected]' } ]
General features of open-source license types (not legal advice — check the license text and your organization's policy)
TypeExamplesCommon terms
PermissiveMIT, BSDBroadly allows copying, modification and commercial use. Keep the copyright notice and license text with the code
Permissive (with patent clause)Apache-2.0Broadly permissive like MIT. Keep a copy of the license and notices, mark changes in modified files, and includes patent-related clauses
CopyleftGPL familyStronger terms, such as having to provide source code under the same license when you distribute a program that includes the code
No licensePublic code with no license fileBeing public may not mean you have permission to use it. Check before using

7.Making the review steps a habit

If you build the habit of checking AI-given code in the same order every time, you miss less. First read it to see whether what the code does matches what you asked for, and for any line you do not understand, get an explanation and then confirm with console.log. Next, write tests with expected values you set yourself — two or three ordinary cases and three or four edge cases — and run them.

If a test fails, gather the failing input, the value you got and the expected value, and ask the AI again. As in Lesson 8, "input [100, 95, 80], expected [100, 95], actual [95, 80]" gets fixed much faster than "it's wrong." When you get the fixed code, rerun all the original tests to make sure fixing one place did not break another. Putting the code before and after the fix into a text diff checker shows exactly what changed.

Finally, do the security and outside-the-code checks: no secrets left in the code, input is validated, no eval, unfamiliar packages were checked, and license and personal-data rules were followed. Only code that has been through this process is "code you can take responsibility for." This completes the Coding Basics course. Now that you can read, test and fix short code, keep AI as your assistant and turn your repetitive tasks into code one at a time.

  • Purpose: does what the code does match what you asked for?
  • Line-by-line reading: input, process, output; confirm unclear lines with console.log
  • Tests: set the expected values yourself and always include boundary values
  • Rerun: after any fix, run every test from the start
  • Security and beyond the code: secrets, input validation, eval, packages, licenses, personal data

📌 Key points

  • AI code can be right for common inputs and wrong at the edges — the person using it must verify it
  • Set the expected values yourself first, and test with empty values, 0, boundary values and numbers of different lengths
  • Without a compare function, sort() sorts in string order and changes the original
  • Keep secrets out of code and prompts, validate input, and never use eval on untrusted input
  • Check that packages really exist and are maintained, check license terms and policies, and use fake data instead of personal data

✍️ Practice questions

Answer first, then open "Answer and explanation".

Q1. What is the result of [100, 95, 80].sort()?

⭕ Correct

❌ Not quite — see the explanation

Answer and explanation
Answer ③ [100, 80, 95]

Without a compare function, values are converted to strings and sorted in dictionary order: "100" < "80" < "95". For numeric sorting, pass a compare function, as in sort((a, b) => a - b).

Q2. When testing a "free shipping on orders of 50,000 won or more" function, which test value matters most?

⭕ Correct

❌ Not quite — see the explanation

Answer and explanation
Answer ② 50,000 won

It is the boundary value where the condition flips. A bug that mixes up > and >= shows up only at exactly 50,000 won.

Q3. You want to ask an AI assistant about an error, but the code contains a real API key. What should you do?

⭕ Correct

❌ Not quite — see the explanation

Answer and explanation
Answer ② Replace the key with a fake value like "YOUR_API_KEY" and then paste it

Secrets go in neither code nor prompts. If a key has already been exposed, revoke it with the service and issue a new one.

Q4. An AI told you to install a package you have never seen. Which of these is NOT a sensible thing to check before installing?

⭕ Correct

❌ Not quite — see the explanation

Answer and explanation
Answer ③ Whether the AI sounded confident

An AI can confidently make up package names that do not exist. Check for yourself whether it exists, its spelling, its maintenance status and your organization's policy.

Q5. You want to ask an AI for code that cleans up your company's customer data. Describe how to ask while protecting personal data.

Answer and explanation
Answer Instead of the real data, show only the format with a few lines of fake data in the same shape (fake names, 010-0000-0001, example.com addresses and so on), and run the code you get on the real data on your own computer. Also check your company's AI usage policy.

What you need to build the code is the shape of the data. If you paste the real values, that information leaves your control.

🧪 Code lab

Use tests to find and fix hidden bugs in code that looks AI-written, and build functions for input validation and masking personal data. Look at the failing inputs in the test results first.

Your code runs only inside an isolated sandbox in this browser and is never sent to a server. It has no network access and is stopped after 2 seconds. Edited code is saved only in this browser. Ctrl+Enter (⌘+Enter) runs it; Tab inserts two spaces (press Esc, then Tab, to move on).

JavaScript is off, so the code can't run here, but you can still read each task, its starter code, the automatic checks and a sample solution.

1Fixing the edge case in an average function

The AI-written average(nums) returns NaN for an empty array. Fix it so it returns 0 for an empty array and the average otherwise. The array contains only numbers.

Automatic checks
  • average([80,90,100])expected 90
  • average([])expected 0
  • average([0,0])expected 0
  • average([-10,10,30])expected 10
  • average([7])expected 7
💡 Hint

At the very start of the function, if nums.length === 0, immediately return 0;.

Show a sample solution
function average(nums) {
  if (nums.length === 0) return 0;
  let sum = 0;
  for (const x of nums) {
    sum += x;
  }
  return sum / nums.length;
}

2The sorting bug in a top-scores function

The AI-written topScores(scores, n) should return the top n scores from largest to smallest, but it goes wrong once a 100 is included. Fix it to sort by numeric value, and do not change the original array. If n is larger than the array length, return as many as there are.

Automatic checks
  • topScores([70,90,85], 2)expected [90,85]
  • topScores([100,95,80], 2)expected [100,95]
  • topScores([5,100,20,9], 3)expected [100,20,9]
  • topScores([60,70], 0)expected []
  • topScores([], 3)expected []
  • topScores([88], 5)expected [88]
💡 Hint

Copy with [...scores], sort largest first with sort((a, b) => b - a), then slice(0, n).

Show a sample solution
function topScores(scores, n) {
  const copy = [...scores];
  copy.sort((a, b) => b - a);
  return copy.slice(0, n);
}

3Validating an order quantity

Complete the function parseQuantity(input). After removing leading and trailing spaces from the string input, return the number if it is a whole number made only of digits between 1 and 99 inclusive; otherwise return null. "2.5", "-1", "1e3" and the empty string all give null.

Automatic checks
  • parseQuantity("3")expected 3
  • parseQuantity(" 12 ")expected 12
  • parseQuantity("0")expected null
  • parseQuantity("100")expected null
  • parseQuantity("2.5")expected null
  • parseQuantity("1e3")expected null
💡 Hint

Check for digits only with /^\d+$/.test(s), and return null if n < 1 || n > 99. Also note that Number("") is 0.

Show a sample solution
function parseQuantity(input) {
  const s = input.trim();
  if (!/^\d+$/.test(s)) return null;
  const n = Number(s);
  if (n < 1 || n > 99) return null;
  return n;
}

4Masking the middle of a phone number

Write a function maskPhone(s) that hides personal data when you share results. If s has the 3-4-4 digit shape like 010-1234-5678, return 010-****-5678 with the middle four digits replaced by ****; if it does not have this shape, return null.

Automatic checks
  • maskPhone("010-1234-5678")expected "010-****-5678"
  • maskPhone("010-0000-0001")expected "010-****-0001"
  • maskPhone("01012345678")expected null
  • maskPhone("")expected null
  • maskPhone("010-12-5678")expected null
💡 Hint

The regular expression /^\d{3}-\d{4}-\d{4}$/ lets through only "3 digits-4 digits-4 digits." Anything that fails is null.

Show a sample solution
function maskPhone(s) {
  if (!/^\d{3}-\d{4}-\d{4}$/.test(s)) return null;
  const parts = s.split("-");
  return parts[0] + "-****-" + parts[2];
}

🤖 Try asking AI like this

Copy a prompt and replace the [ ] parts with your own situation. Don't take the answer on trust — check it against this lesson.

When you want to understand code an AI gave you

Explain the JavaScript code below line by line, as if to a beginner. Using the sample input [sample input], trace what the main variables hold after each line, and point out what happens when an empty value, 0 or a string comes in.
[code]

When you want to find every case worth testing

The purpose of the function below is [purpose]. Make a list of inputs to test, grouped into ordinary cases, boundary values, empty values and invalid input. I'll decide the expected values myself, so just write the inputs and why each case matters.
[function code]

When you want a security and license review of your code

Review the code below from a security point of view. List any secrets left in the code, unvalidated input, dangerous features like `eval`, and how to check that the packages it uses really exist and are maintained. If any part was taken from open-source code, tell me in general terms which license terms I should check (it doesn't need to be legal advice). I've already replaced keys and personal data in the code with fake values.
[code]

🧰 Related tools

Tools for checking and tidying the JSON, regular expressions and text from this lesson. Don't paste real personal data or passwords.

References
  • MDN Web Docs — reference pages for Array.prototype.sort, JSON.parse and eval (including the advice to avoid eval)
  • OWASP — general guidance on input validation and secrets management
  • Open Source Initiative — texts and general explanations of open-source licenses (MIT, Apache-2.0, GPL and others)

Reached every goal above? Mark the lesson complete.

💻 Coding Basics

  1. 1What Is a Program? — Breaking Work into Sequence, Choice, and Repetition
  2. 2Values, Variables, and Types — Putting Name Tags on Values
  3. 3Conditionals — Taking Different Paths Depending on the Situation
  4. 4Loops — Doing the Same Thing Many Times, Exactly
  5. 5Functions — Splitting Work into Small Named Machines
  6. 6Arrays and Objects — Storing and Handling Data
  7. 7Strings and Text — Cutting, Finding and Replacing Characters
  8. 8Debugging and Reading Errors — Turning Red Text into Clues
  9. 9Simple Automation — Spreadsheet Math and Text Cleanup in Code
  10. 10Reading and Verifying AI-Written Code — Tests, Security, Licenses, Privacy
📚 Worth reading
📊Using AI for Spreadsheets, and Checking the Formulas→ 💻AI Coding Assistants: Security and Licence Risks→ 💬Practising Conversation in a Foreign Language with AI→ ⚙️Finding Work Tasks Worth Automating with AI→
← Foundations for the AI Era