Escape for HTML, parameters for SQL, a menu for commands
No real database or shell is used: the program prints the page text, the query shape and the decision. The script text is a harmless stand-in.
A model's reply is text produced from inputs you do not control, so it is as untrusted as a form field. Escape it before putting it in a web page, pass it to databases as parameters, and let it select from an allow-list instead of building commands.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 5 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write escape_html(text) for the five characters, and print the escaped form of <b>Tom & "Jerry"</b>.
Write choose_action(reply, menu) that returns the reply when it is exactly one of the menu items (compare after stripping spaces and lowering case), and None otherwise. Test with " LS ", "ls -la" and "pwd" against the menu {"ls", "pwd"}.
Explain it without notes
Why is a model's reply untrusted even if you wrote the prompt?
How do you safely show a model's reply in a web page?
Why are parameterised queries better than escaping values yourself?
A feature lets the model pick a command to run. How do you design it safely?
Expected output
raw page html: <p><script>show('banana')</script></p>
escaped page html: <p><script>show('banana')</script></p>
string-built SQL: SELECT * FROM users WHERE name = 'O'Brien'
parameterised SQL: SELECT * FROM users WHERE name = ? params: O'Brien
ls -> would run: ls
rm banana -> refused: rm banana
ls; echo banana -> refused: ls; echo banana