2017-02-04 2 views
0

Код ниже о Python + Django + PostgreSQL. Но, возможно, вопрос ограничивается поведением psycopg2.Изучение SQL-инъекций: не удается удалить таблицы

Я изучаю веб-безопасность, а именно SQL-инъекции. Только для обучения.

Это база данных образцов мира (http://pgfoundry.org/frs/?group_id=1000150&release_id=366#world-world-1.0-title-content).

Я изобрел эту SQL инъекции:

1'; drop table city cascade;select 1 where 'me'='me 
1'; drop owned by admin;select 1 where 'me'='me 

Я нахожусь в режиме отладки, так что я могу видеть ошибки, если таковые имеются. Ну, эти инъекции не приводят к ошибкам.

Но таблицы все еще присутствуют.

И я могу выполнить эти команды в PSQL:

world=# drop owned by admin; 
DROP OWNED 
world=# \dt 
No relations found. 

ВОПРОС: Не могли бы вы помочь мне понять, почему моя SQL инъекция не дает такой же результат?

мир = # \ дт

  List of relations 
Schema |  Name  | Type | Owner 
--------+-----------------+-------+------- 
public | city   | table | admin 
public | country   | table | admin 
public | countrylanguage | table | admin 

мир = # \ d + город

      Table "public.city" 
    Column |  Type  | Modifiers | Storage | Stats target | Description 
-------------+--------------+-----------+----------+--------------+------------- 
id   | integer  | not null | plain |    | 
name  | text   | not null | extended |    | 
countrycode | character(3) | not null | extended |    | 
district | text   | not null | extended |    | 
population | integer  | not null | plain |    | 

views.py

class FormView(View): 

    def get(self, request): 
     return render(request, 
         "home/city.html") 

    def post(self, request): 
     city = request.POST.get("city") 
     try: 
      conn = psycopg2.connect(dbname='world', user='admin', password='password') 
     except psycopg2.OperationalError: 
      print("Unable to connect to db!") 
      exit(); 
     cur = conn.cursor() 
     select = "select countrycode, district from city where name='{}'".format(city) 
     cur.execute(select); 

     selection = cur.fetchall() 

     return render(request, 
         "home/city.html", 
         context={'city': city, 'selection': selection}) 

city.html

{% extends 'base.html' %} 

{% block content %} 
<h2>City</h2> 
<form method="post"> 
    {% csrf_token %} 
    <input name="city"> 
    <button>Submit</button> 
</form> 

<h2>Country code and district for {{ city }}:</h2> 
<ul> 
    {% for row in selection %} 
     <li>{{ row.0 }} {{ row.1 }}</li> 
    {% empty %} 
     <p>Nothing so far.</p> 
    {% endfor %} 
</ul> 

{% endblock %} 
+0

Включите 'log_statements = 'all'' в' postgresql.conf' и посмотрите инструкции SQL в журнале базы данных. Это поможет вам понять, что приходит в базу данных. –

ответ

0

conn.commit() отсутствовал.

Ссылка http://initd.org/psycopg/docs/usage.html

Таким образом, в случае таблиц только падение выбора, как представляется, вряд ли возможно.

Но если мы выполним что-то вроде «вставить в город ...», тогда мы должны использовать conn.commit(), и здесь мы можем отбросить таблицы через SQL-инъекцию.

Смежные вопросы