Back-end programming · Programmation back-end
| English | Français |
|---|---|
| route/ruːt/ | voie |
| validate input/ˈvælɪdeɪt ˈɪnpʊt/ | valider l'entrée |
| status/ˈsteɪtəs/ | statut |
| SQL injection/ˌes kjuː ˈel ɪnˈdʒekʃn/ | injection SQL |
| parameterised query/ˌpærəˈmetəraɪzd ˈkwɪərɪ/ | requête paramétrée |
A search string changes the query
- A name search receives
' OR 1=1 --. If code pastes it into SQL, the text may change the condition instead of remaining a name. - A route 路由 maps a request method and path to its handler. Keep the route contract clear before implementing the lookup.
Check shape and permission
- Validate input 校验输入 means checking required values, types, permitted lengths and ranges. Check the caller’s permission separately.
- A status · statut 状态码 describes the result: 200 for this successful lookup, 400 for invalid input and 404 for a missing resource. Permission failures need the application’s agreed policy; they are not automatically bad input.
Match these results under the lesson’s route contract.
These meanings do not by themselves define how private permission failures should be represented.
Keep values outside the SQL text
- SQL injection · injection SQL SQL 注入 happens when untrusted text becomes part of SQL syntax. A parameterised query 参数化查询 binds a value separately from the statement.
- Placeholders bind values, not arbitrary table names or sort directions. Choose such identifiers from a fixed server-side allowlist when a route needs them.
Which lookup keeps a submitted name separate from SQL syntax?
Binding values keeps them separate from the fixed statement.
Explain what binding a name to a SQL placeholder changes.
The statement stays fixed while the separately bound value remains data.
A value placeholder can safely represent any table name or sort direction.
Placeholders bind values. Choose dynamic identifiers from a fixed server-side allowlist.
Run a complete local example
- Save and run this Python example using SQLite. The unusual string is stored as a name, then searched as a bound value.
- The result contains only that named row. Binding prevents this value becoming SQL syntax; it does not establish permission or make every application secure.
import sqlite3
con = sqlite3.connect(":memory:")
con.execute("CREATE TABLE students (id INTEGER PRIMARY KEY, name TEXT)")
name = "' OR 1=1 --"
con.executemany("INSERT INTO students VALUES (?, ?)", [(1, "Mei"), (2, name)])
rows = con.execute("SELECT id FROM students WHERE name = ?", (name,)).fetchall()
print(rows) # [(2,)]
con.close()
What does the complete SQLite example print?
The unusual string is stored and then matched as a literal name.
Keep failures useful and private
- Give the browser a clear message it can act on, such as an invalid field or a temporary failure. Do not return raw SQL errors, private credentials or stack traces.
- Record diagnostic details only in protected logs with sensitive values removed. Log enough context to investigate without copying every private request body.
Return raw database errors to ordinary visitors so they can debug the SQL.
Return useful safe messages; protect diagnostic logs and remove sensitive values.
Verify more than a happy path
- Check valid, missing, wrong-type and oversized input; denied access; an empty match; and a simulated database failure. State the expected result for each.
- Keep every dynamic value bound, including dropdown values. The browser’s list does not prevent someone sending a different value directly.
Validate the request, authorize the caller and bind data values. These solve different problems; none replaces the others.
Which external inputs need appropriate server checks? Select all that apply.
Ordinary-looking external values can still have wrong types, lengths or permissions.
A query is parameterised, but any caller can read private student rows. What remains missing?
Binding addresses injection of values; it does not authorize the caller.