研究SQL注入:不能删除表

时间:2017-02-04 09:07:13

标签: django postgresql security web

下面的代码是关于Python + Django + PostgreSQL的。 但也许问题仅限于psycopg2行为。

我正在研究网络安全性,即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注射不会产生相同的结果?

world =#\ dt

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

world =#\ d + city

                          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 %}

1 个答案:

答案 0 :(得分:0)

conn.commit()缺席。

参考http://initd.org/psycopg/docs/usage.html

因此,如果仅选择丢弃表似乎几乎不可能。

但是如果我们执行类似&#34;插入城市...&#34;之类的东西,那么我们必须使用conn.commit(),在这里我们可以通过SQL注入删除表。