Description
There is a website with a login page. Can you log in? The application is vulnerable to SQL injection.
Setup
Open the challenge login page in your browser.
Solution
- Step 1Inject SQL into the username fieldThe login query is likely constructed by string concatenation: SELECT * FROM users WHERE username='INPUT' AND password='...'. Entering admin' OR '1'='1 as the username closes the username string early and appends a condition that is always true, bypassing the authentication check entirely.
Learn more
SQL injection (SQLi) is one of the oldest and most dangerous web vulnerabilities - consistently ranked in the OWASP Top 10. It occurs when user-supplied input is concatenated directly into a SQL query string without sanitization. The database then executes the attacker's input as part of the query, allowing arbitrary data retrieval, authentication bypass, data modification, or even operating system command execution.
The classic login bypass payload
admin' OR '1'='1works by manipulating the query structure. A vulnerable query looks like:SELECT * FROM users WHERE username='USERINPUT' AND password='PASSINPUT'After injection it becomes:
SELECT * FROM users WHERE username='admin' OR '1'='1' AND password='...'. BecauseOR '1'='1'is always true and OR has lower precedence than AND, the WHERE clause evaluates to true for the admin row, returning it regardless of the password.Other common payloads to know:
' OR 1=1 --- comment out the rest of the query (MySQL/MSSQL)' OR 1=1 #- comment out with hash (MySQL)' OR 'x'='x- always-true string comparisonadmin'--- comment out password check entirely
- Step 2Submit the injection and collect the flagSet username to admin' OR '1'='1 and enter any value for the password. Submit the form. The always-true WHERE clause causes the query to return a row, granting you access. The flag is displayed on the authenticated page.
Learn more
Once the injected query returns a matching row, the application's authentication logic is fooled into believing the login succeeded. The server creates a session and redirects to the authenticated area, where the flag is displayed. This is authentication bypass - the attacker never needed to know a valid password.
Prevention: The definitive fix for SQL injection is parameterized queries (also called prepared statements). Instead of building a query string with user input, you pass a query template with placeholders and supply values separately. The database driver handles escaping, ensuring user input is always treated as data, never as SQL syntax. Example in Python with sqlite3:
cursor.execute("SELECT * FROM users WHERE username=? AND password=?", (username, password))ORMs (Object-Relational Mappers) like SQLAlchemy and Django ORM use parameterized queries by default. Input validation, web application firewalls (WAFs), and the principle of least privilege (database users with only SELECT permission) provide defense-in-depth but should not replace parameterized queries as the primary control.
Flag
picoCTF{...}
SQL injection occurs when user input is concatenated directly into a SQL query - always use parameterized queries or prepared statements to prevent it.