I'm currently working on a Flask restful API that searches for doctors within a certain distance based on area. I would like to know exactly what kind of SQL injection it's vulnerable to, since sqllite3 does not allow multiple commands in one statement. It has a couple of different tables associated with it but I've included the relevant ones and what the sqllite query looks like within the API code. The API itself is pretty large so you'll have to forgive me for not posting the whole thing.
from flask import Flask
from flask_restful import Api, Resource, reqparse
import sqlite3
app = Flask(__name__)
api = Api(app)
class fullname(Resource):
def get(self, zipcode,distance,fname,lname):
con = sqlite3.connect('DoctorZipLookup.db')
with con:
cur = con.cursor()
cur.execute("SELECT Latitude, Longitude FROM Zipcodes WHERE Zip = " + zipcode)
#does some math and finds zipcodes less than distance away
cur.execute("SELECT * FROM Doctors WHERE Zip IN(SELECT Zip FROM closezipcodes) AND FirstName LIKE '" + fname + "%' AND LastName LIKE '" + lname + "%' ORDER BY Zip")
cur.execute("SELECT * FROM Comments ORDER BY id")
#put doctors and their comments in a JSON object and return it
api.add_resource(fullname, "/fullname/<string:zipcode>&<string:distance>&<string:fname>&<string:lname>")
app.run(debug=True)
I understand that queries written like this are vulnerable to SQL Injection, and I've been trying some examples just to get a better understanding of how it works. So far though I haven't gotten it to do much of anything. Most examples I've found online include a ; to execute a second statement and drop a table or spit a lot more information out. But sqlite3 won't allow you to execute 2 statements at once, is there a way to get around this and execute something else? Alternatively, what harm can actually be done by modifying a single statement that's formatted like this? So far all I have figured out is doing something like
import requests
zip = '27265 or Zip LIKE \'%\''
resp = requests.get('http://127.0.0.1:5002/fullname/' + zip + '&10&first&last')
which would cause the Zipcodes table to vomit out all of its content. What else can be done with the way this is set up?