Skip to content
    SeaCode
    Learning tracksCode ArenaWorkshops & EventsInstructors
    Log inSign up
    SQLSQL

    First questions to the data

    • What are SQL and databases?
    • SELECT: choosing columns
    • WHERE: filtering rows
    • ORDER BY and LIMIT: sort and take the top

    Summarizing and grouping

    • Aggregates: COUNT, SUM, AVG
    • GROUP BY and HAVING
    • CASE, COALESCE and text functions

    Joining tables

    • Keys and relationships
    • INNER JOIN
    • LEFT JOIN: leave nobody out
    • Three-table joins and self joins
    • Subqueries and CTEs

    Building tables and changing data

    • CREATE TABLE and constraints
    • INSERT, UPDATE and DELETE
    • Transactions: all or nothing
    • SQL injection: the most dangerous mistake

    Professional level

    • Indexes: why is my query slow?
    • Window functions: rankings and totals without losing rows
    • Designing tables: normalization
    • Project: analytics for a learning platform
    SQL

    Building tables and changing data · Lesson 16 of 20

    SQL injection: the most dangerous mistake

    How user-typed text can hijack your query, and the one right fix.

    8 minutes2 games

    When code builds a query by gluing in text from the user, the user can type SQL instead of data. That's SQL injection, one of the most dangerous and common vulnerabilities in the web's history.

    JavaScript
    // ❌ Never do this
    const name = req.query.name
    const sql = "SELECT * FROM students WHERE name = '" + name + "'"
    await db.query(sql)

    If the user types a normal name like Omar, fine. But if they type ' OR '1'='1, this is the query that runs. Run it and see:

    SQL
    -- What the server built from the input  ' OR '1'='1
    SELECT * FROM students WHERE name = '' OR '1'='1';

    The condition is now true for every row, so every student came back. Other inputs can drop tables, skip a login check, or leak password hashes.

    JavaScript
    // ✅ Parameterized query: the value travels separately from the SQL
    await db.query("SELECT * FROM students WHERE name = $1", [name])
    
    // ✅ Query builders and clients do this for you
    const { data } = await supabase.from("students").select("*").eq("name", name)

    Important

    The right fix is parameterized queries (prepared statements): the query is sent with placeholders like $1 or ? and the values are sent separately, so the database never treats a value as code. Escaping by hand or "filtering" dangerous characters is incomplete; don't rely on it.

    Spot the bug

    Which line has the vulnerability?

    Quick question

    Which approach actually prevents SQL injection?

    Interview question

    What is SQL injection and how do you prevent it?

    Learn more from

    • OWASP: SQL Injection Prevention Cheat Sheetcheatsheetseries.owasp.org
    • OWASP: SQL Injectionowasp.org
    • node-postgres: Parameterized queriesnode-postgres.com

    Played 0 of 2 games

    Sign in to save your progress and earn XP.

    PreviousTransactions: all or nothingNextIndexes: why is my query slow?
    SeaCode

    Learn to code for real, online or at our branch in front of Cairo University, Giza.

    Learn

    • All courses
    • Interactive tutorials
    • Interview practice problems
    • Mock interview
    • Learning tracks
    • Code Arena
    • Workshops & Events
    • Knowledge library
    • Team projects

    Your account

    • Log in
    • Sign up
    • Learning plan
    • Certificates
    • Site map

    Contact us

    • WhatsApp
    • 010 9094 1104
    • In front of Cairo University, Giza

    © 2026 SeaCode. All rights reserved.