Skip to content

Commit aa6821e

Browse files
committed
Add notes on SQL injection
1 parent 4191774 commit aa6821e

File tree

1 file changed

+87
-1
lines changed

1 file changed

+87
-1
lines changed

README.md

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3032,7 +3032,7 @@ First you create a connection to the database (if the database doesn't exist it'
30323032

30333033
Create a cursor (a temporary workspace for SQL commands).
30343034

3035-
USe the cursor to execute your SQL command, such as creating or inserting into a table.
3035+
Use the cursor to execute your SQL command, such as creating or inserting into a table.
30363036

30373037
Commit the changes.
30383038

@@ -3055,3 +3055,89 @@ conn.commit()
30553055
# Close connection
30563056
conn.close()
30573057
```
3058+
3059+
You can create a query before you execute it.
3060+
3061+
```python
3062+
insert_query = "INSERT INTO friends VALUES ('Merry', 'Lewis', 7);"
3063+
c.execute(insert_query)
3064+
```
3065+
3066+
You can interpolate variables into your query using `?` and a tuple. This handles quotes and sanitizing the data.
3067+
3068+
```python
3069+
data = ("Mary", "Reed", 9)
3070+
query = "INSERT INTO friends VALUES (?,?,?);"
3071+
c.execute(query, data)
3072+
```
3073+
3074+
You can carry out bulk inserts using `executemany`.
3075+
3076+
```python
3077+
people = [
3078+
("Roald", "Amundsen", 5),
3079+
("Rosa", "Parks", 9),
3080+
("Henry", "Hudson", 5),
3081+
("Neil", "Armstrong", 7),
3082+
("Daniel", "Bruhl", 3)
3083+
]
3084+
3085+
c.executemany("INSERT INTO friends VALUES (?,?,?)", people)
3086+
```
3087+
3088+
If you want to do something with each item along with inserting it, use a loop.
3089+
3090+
```python
3091+
for person in people:
3092+
c.execute("INSERT INTO friends VALUES (?,?,?)", person)
3093+
print("Inserting now")
3094+
```
3095+
3096+
### Selecting with Python
3097+
3098+
When you select with Python, you can iterate over the cursor object, use `c.fetchall()` to get back a list containing the results or `c.fetchone()` to get just the first result.
3099+
3100+
```python
3101+
import sqlite3
3102+
conn = sqlite3.connect("my_friends.db")
3103+
c = conn.cursor()
3104+
3105+
c.execute("SELECT * FROM friends WHERE closeness > 5 ORDER BY closeness;")
3106+
3107+
c.fetchall()
3108+
3109+
conn.commit()
3110+
conn.close()
3111+
```
3112+
3113+
### SQL Injection
3114+
3115+
If you don't sanitize your inputs, a user could write SQl into their input and manipulate the database.
3116+
3117+
In the example below, if a user entered `' OR 1=1--` the single quote would close the quote, `1=1` would always evaluate to true and `--` would comment out any remaining characters.
3118+
3119+
```python
3120+
import sqlite3
3121+
conn = sqlite3.connect("users.db")
3122+
c = conn.cursor()
3123+
3124+
user_name = input("Please enter your username...")
3125+
password = input("Please enter your password...")
3126+
3127+
# Bad idea
3128+
# query = f"SELECT * FROM users WHERE username='{user_name}' AND password='{password}' OR 1=1 --'"
3129+
3130+
# Better idea
3131+
query = "SELECT * FROM users WHERE username=? AND password=?"
3132+
3133+
c.execute(query, (user_name, password))
3134+
3135+
result = c.fetchone()
3136+
if(result):
3137+
print("Welcome back")
3138+
else:
3139+
print("Failed login")
3140+
3141+
conn.commit()
3142+
conn.close()
3143+
```

0 commit comments

Comments
 (0)