Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #105163 > unrolled thread

Re: WP-A: A New URL Shortener

Started byDaniel Wilcox <dmw@yubasolutions.com>
First post2016-03-17 15:34 -0700
Last post2016-04-06 20:42 +0200
Articles 10 — 3 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: WP-A: A New URL Shortener Daniel Wilcox <dmw@yubasolutions.com> - 2016-03-17 15:34 -0700
    Re: WP-A: A New URL Shortener Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-03-18 00:17 +0100
      Re: WP-A: A New URL Shortener Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-03-19 15:00 +0100
        Re: WP-A: A New URL Shortener Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-03-25 22:28 +0100
          Re: WP-A: A New URL Shortener Chris Angelico <rosuav@gmail.com> - 2016-03-26 08:48 +1100
            Re: WP-A: A New URL Shortener Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-03-25 23:25 +0100
              Re: WP-A: A New URL Shortener Chris Angelico <rosuav@gmail.com> - 2016-03-26 10:04 +1100
                Re: WP-A: A New URL Shortener Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-03-26 04:30 +0100
                  Re: WP-A: A New URL Shortener Chris Angelico <rosuav@gmail.com> - 2016-03-26 14:46 +1100
                    Re: WP-A: A New URL Shortener Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-04-06 20:42 +0200

#105163 — Re: WP-A: A New URL Shortener

FromDaniel Wilcox <dmw@yubasolutions.com>
Date2016-03-17 15:34 -0700
SubjectRe: WP-A: A New URL Shortener
Message-ID<mailman.291.1458254120.12893.python-list@python.org>
+list

Cool thanks, highly recommended to use an ORM to deter easy SQL
injections.  I heard django mentioned I'd vouch for that.  BTW you can get
a free (like actually free--don't get me started) certificate for your
server from letsencrypt.org.  I noticed you weren't using HTTPS.

Django would also make it easy to add a user registration system -- once
you register a custom domain I don't see any way to update it.  You could
add stuff like that, usage counts, even the ability to browse other users
shortened URLs (put that in a privacy policy if you do it).

I noticed also that after creating a test URL the links below to create new
ones were just a link to the current page, FYI.

I don't think changing the way you store the the urls in the sqlite
database will change much regarding injection.  You should avoid crafting
queries by hand or... use this as an exercise to see what you can escape
into a URL that might get unescaped later (with hilarious insecurity for
all).  Then you'll want to either a) learn SQL escaping for your database
of choice *really really well* or b) use an ORM.

Be well,

-D

On Thu, Mar 17, 2016 at 4:46 AM, Vinicius <me@vmesel.com> wrote:

> Hey Daniel,
>
> Thanks for the idea, but in someway it's already working.
> If you go to the New URL?(http://wp-a.co/new/) you can define a custom
> hash for the shortened URL.
>
> In it's next version the softaare will count onlt with .TXT database, so
> it won't be injectful.
>
> Vinicius Mesel
>
> Em 16 de mar de 2016, às 1:28 AM, Daniel Wilcox <dmw@yubasolutions.com>
> escreveu:
>
> I dare say I'm with Rick on this point -- keep it up, go learn stuff, put
> things together and see how they break -- I think it's the best way to get
> feel for how things fit together and, somewhat inevitably, fall over (when
> the conditions they were designed in no longer apply).
>
> *quick glance at source*
> The raw SQL scares me a bit, there is a lot of escaping that you could add
> to protect from sql injections (at least for mysql, sqlite I'm not sure).
> And since you want to run this on the Internet I highly recommend putting a
> mariadb/mysql database behind it.  Glancing over the Flash documentation
> they seem to suggest SQLAlchemy which sounds like a reasonable choice for
> an ORM.
>
> An neat idea I've seen before that was neat was a sematic shorten-er where
> you could specify the shortened URL to make it easy to remember and
> reference.  A lot of security, aka input sanitation, involved but might be
> fun -- and who knows it could spark a land rush to claim useful short URLs
> like wp-a.co/flask-tips. :)
>
> Speak up if you need any pointers!
>
> Daniel
>
> On Tue, Mar 15, 2016 at 12:56 PM, Vinicius Mesel <me@vmesel.com> wrote:
>
> Hey guys,
>
>
> I'm a 16 year old Python Programmer that wanted to do something different.
>
> But, like we know, ideas are quite difficult to find.
>
> So I decided to develop a URL Shortener to help the Python community out
>
> and share my coding knowledge, and today the project was launched with its
>
> first stable version.
>
> So if you want to see the software working, go check it out at:
>
> http://wp-a.co/
>
> Or if you want to see the source code to contribute and help the project:
>
> https://github.com/vmesel/WP-A.CO
>
>
>
> Hugs,
>
> Vinicius Mesel
>
> Brazilian and Portuguese Speaker
>
> http://www.vmesel.com
>
>
>
>
> --
>
> https://mail.python.org/mailman/listinfo/python-list
>
>
>
>

[toc] | [next] | [standalone]


#105171

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2016-03-18 00:17 +0100
Message-ID<1964524.jFVgOtWIx9@PointedEars.de>
In reply to#105163
Daniel Wilcox wrote:

> Cool thanks, highly recommended to use an ORM to deter easy SQL
> injections. 

That is to crack a nut with a sledgehammer.  SQL injection can be easily and 
more efficiently prevented with prepared statements.  While an Object-
Relational Mapper (ORM) can use those, and there are benefits to using an 
ORM, avoiding SQL injection should not be the primary reason to use an ORM.  
In fact, using an ORM is often not only overkill, but effectively *reduces* 
application performance.

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#105270

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2016-03-19 15:00 +0100
Message-ID<2334208.C0ktZ5B2k1@PointedEars.de>
In reply to#105171
Chris Angelico wrote:

> On Fri, Mar 18, 2016 at 10:17 AM, Thomas 'PointedEars' Lahn
> <PointedEars@web.de> wrote:
>> Daniel Wilcox wrote:
>>> Cool thanks, highly recommended to use an ORM to deter easy SQL
>>> injections.
>>
>> That is to crack a nut with a sledgehammer.  SQL injection can be easily
>> and more efficiently prevented with prepared statements.  While an
>> Object-Relational Mapper (ORM) can use those, and there are benefits to
>> using an ORM, avoiding SQL injection should not be the primary reason to
>> use an ORM. In fact, using an ORM is often not only overkill, but
>> effectively *reduces* application performance.
> 
> You don't even need prepared statements. All you need is parameterized
> queries.

A prepared statement in this context uses a parameterized query.

<https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_1:_Prepared_Statements_.28Parameterized_Queries.29>

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#105709

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2016-03-25 22:28 +0100
Message-ID<4500052.tJGngFWhWt@PointedEars.de>
In reply to#105270
Chris Angelico wrote:

> […] Thomas 'PointedEars' Lahn […] wrote:
>> Chris Angelico wrote:
>>> […] Thomas 'PointedEars' Lahn […] wrote:
>>>> Daniel Wilcox wrote:
>>>>> Cool thanks, highly recommended to use an ORM to deter easy SQL
>>>>> injections.
>>>> That is to crack a nut with a sledgehammer.  SQL injection can be
>>>> easily and more efficiently prevented with prepared statements.  […]
>>> You don't even need prepared statements. All you need is parameterized
>>> queries.
>> A prepared statement in this context uses a parameterized query.
>>
>> 
<https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_1:_Prepared_Statements_.28Parameterized_Queries.29>
> 
> I know what a prepared statement is. And I know that they are
> effective. However they are overkill - as I said, you merely need
> parameterization.

Then enlighten me, please: How is “parameterization” or a “parameterized 
query”, as *you* understand it, different from a prepared statement?

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#105710

FromChris Angelico <rosuav@gmail.com>
Date2016-03-26 08:48 +1100
Message-ID<mailman.13.1458942513.28225.python-list@python.org>
In reply to#105709
On Sat, Mar 26, 2016 at 8:28 AM, Thomas 'PointedEars' Lahn
<PointedEars@web.de> wrote:
> Chris Angelico wrote:
>
>> […] Thomas 'PointedEars' Lahn […] wrote:
>>> Chris Angelico wrote:
>>>> […] Thomas 'PointedEars' Lahn […] wrote:
>>>>> Daniel Wilcox wrote:
>>>>>> Cool thanks, highly recommended to use an ORM to deter easy SQL
>>>>>> injections.
>>>>> That is to crack a nut with a sledgehammer.  SQL injection can be
>>>>> easily and more efficiently prevented with prepared statements.  […]
>>>> You don't even need prepared statements. All you need is parameterized
>>>> queries.
>>> A prepared statement in this context uses a parameterized query.
>>>
>>>
> <https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_1:_Prepared_Statements_.28Parameterized_Queries.29>
>>
>> I know what a prepared statement is. And I know that they are
>> effective. However they are overkill - as I said, you merely need
>> parameterization.
>
> Then enlighten me, please: How is “parameterization” or a “parameterized
> query”, as *you* understand it, different from a prepared statement?

This is a prepared statement:

http://www.postgresql.org/docs/current/static/sql-prepare.html

You use a special "PREPARE" query to create *and store* a half-run
query, and then you execute it afterwards. Back in the 1990s, I had
the option of actually *compiling* my SQL queries as part of my C
code, which would prepare all the queries for future execution. It is
completely different from the dynamic parameterized queries that most
people use.

Parameterization is a more general concept which prepared statements
invariably use, but which general code need not use. A Python database
connector could choose to PREPARE/EXECUTE for every query it's given,
or it could choose to escape all the parameters and embed them, or it
could (if it's using a decent database back-end like PostgreSQL)
simply send the query and its associated parameters as-is. Only one of
these options is a "prepared statement". All three are "parameterized
queries", at least from the POV of Python code.

ChrisA

[toc] | [prev] | [next] | [standalone]


#105712

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2016-03-25 23:25 +0100
Message-ID<7663219.M9yg8PEDtW@PointedEars.de>
In reply to#105710
Chris Angelico wrote:

> On Sat, Mar 26, 2016 at 8:28 AM, Thomas 'PointedEars' Lahn
> <PointedEars@web.de> wrote:
>> Chris Angelico wrote:
>>> […] Thomas 'PointedEars' Lahn […] wrote:
>>>> Chris Angelico wrote:
>>>>> […] Thomas 'PointedEars' Lahn […] wrote:
>>>>>> Daniel Wilcox wrote:
>>>>>>> Cool thanks, highly recommended to use an ORM to deter easy SQL
>>>>>>> injections.
>>>>>> That is to crack a nut with a sledgehammer.  SQL injection can be
>>>>>> easily and more efficiently prevented with prepared statements.  […]
>>>>> You don't even need prepared statements. All you need is parameterized
>>>>> queries.
>>>> A prepared statement in this context uses a parameterized query.
>>>>
>>>>
>> 
<https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_1:_Prepared_Statements_.28Parameterized_Queries.29>
>>>
>>> I know what a prepared statement is. And I know that they are
>>> effective. However they are overkill - as I said, you merely need
>>> parameterization.
>>
>> Then enlighten me, please: How is “parameterization” or a “parameterized
>> query”, as *you* understand it, different from a prepared statement?
> 
> This is a prepared statement:
> 
> http://www.postgresql.org/docs/current/static/sql-prepare.html
> 
> You use a special "PREPARE" query to create *and store* a half-run
> query,

[Having written a database layer (in PHP) myself, I know what a prepared 
statement is, thank you very much.]

Your statement is incorrect both for MySQL (which I know) and PostgreSQL 
(AIUI your reference): The query is processed and stored of course, but it 
is definitely _not_ *run* before the EXECUTE command is issued for it.

> and then you execute it afterwards.

In both DMBSs, the query/statement is filled with parameter values and then 
executed not before, and then only if and when, one issues the EXECUTE 
statement for it.

> Back in the 1990s, I had the option of actually *compiling* my SQL queries
> as part of my C code, which would prepare all the queries for future
> execution. It is completely different from the dynamic parameterized
> queries that most people use.

Interesting, but irrelevant.
 
> Parameterization is a more general concept which prepared statements
> invariably use, but which general code need not use.

If it is to be safe from SQL injection, it better uses a parameterized query 
as it is *commonly* understood.

> A Python database connector could choose to PREPARE/EXECUTE for every
> query it's given,

That would not be wise, given that not every query contains variable 
parameters.

> or it could choose to escape all the parameters and embed them,

Recommended against, and not a parameterized query at all.

> or it could (if it's using a decent database back-end like PostgreSQL)
> simply send the query and its associated parameters as-is. Only one of
> these options is a "prepared statement".

Maybe.  I do not know enough about PostgreSQL and its “[sending] the query 
and its associated parameters as-is” yet to confirm or deny this.

> All three are "parameterized queries", at least from the POV of Python
> code.

You are mistaken, then: Of the three kinds of “parameterized queries” as 
*you* understand them (OWASP and I beg to differ), at least one of them
that is not used in a prepared statement is *insufficient to prevent SQL 
injection*.

The second kind also moves tasks to the programming language that are better 
done by the DBMS; the program code should database-agnostic (in the best 
case, for mockup testing, even oblivious of the database).

Which is why programming languages have come to support prepared statements, 
and why OWASP recommends to use either them or stored procedures.

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.y

[toc] | [prev] | [next] | [standalone]


#105713

FromChris Angelico <rosuav@gmail.com>
Date2016-03-26 10:04 +1100
Message-ID<mailman.14.1458947054.28225.python-list@python.org>
In reply to#105712
On Sat, Mar 26, 2016 at 9:25 AM, Thomas 'PointedEars' Lahn
<PointedEars@web.de> wrote:
> Chris Angelico wrote:
>
>> On Sat, Mar 26, 2016 at 8:28 AM, Thomas 'PointedEars' Lahn
>> <PointedEars@web.de> wrote:
>>> Chris Angelico wrote:
>>>> […] Thomas 'PointedEars' Lahn […] wrote:
>>>>> Chris Angelico wrote:
>>>>>> […] Thomas 'PointedEars' Lahn […] wrote:
>>>>>>> Daniel Wilcox wrote:
>>>>>>>> Cool thanks, highly recommended to use an ORM to deter easy SQL
>>>>>>>> injections.
>>>>>>> That is to crack a nut with a sledgehammer.  SQL injection can be
>>>>>>> easily and more efficiently prevented with prepared statements.  […]
>>>>>> You don't even need prepared statements. All you need is parameterized
>>>>>> queries.
>>>>> A prepared statement in this context uses a parameterized query.
>>>>>
>>>>>
>>>
> <https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet#Defense_Option_1:_Prepared_Statements_.28Parameterized_Queries.29>
>>>>
>>>> I know what a prepared statement is. And I know that they are
>>>> effective. However they are overkill - as I said, you merely need
>>>> parameterization.
>>>
>>> Then enlighten me, please: How is “parameterization” or a “parameterized
>>> query”, as *you* understand it, different from a prepared statement?
>>
>> This is a prepared statement:
>>
>> http://www.postgresql.org/docs/current/static/sql-prepare.html
>>
>> You use a special "PREPARE" query to create *and store* a half-run
>> query,
>
> [Having written a database layer (in PHP) myself, I know what a prepared
> statement is, thank you very much.]
>
> Your statement is incorrect both for MySQL (which I know) and PostgreSQL
> (AIUI your reference): The query is processed and stored of course, but it
> is definitely _not_ *run* before the EXECUTE command is issued for it.

It legal to partly perform the query. DB2 can retain a "query plan"
which consists of the exact paths it will follow. So I stand by my
statement.

>> Back in the 1990s, I had the option of actually *compiling* my SQL queries
>> as part of my C code, which would prepare all the queries for future
>> execution. It is completely different from the dynamic parameterized
>> queries that most people use.
>
> Interesting, but irrelevant.

Not really, no. It was a form of PREPARE/EXECUTE that hid the PREPARE
behind a convenient syntax, and then replaced it with EXECUTE for the
run-time.

>> Parameterization is a more general concept which prepared statements
>> invariably use, but which general code need not use.
>
> If it is to be safe from SQL injection, it better uses a parameterized query
> as it is *commonly* understood.

Why? All it needs to do is guarantee that no user data can affect the
query. There are myriad ways to do that, and prepared statements are
only one of them. Even parameterization is not strictly necessary, as
long as the escaping is perfect. (Though that does have its own
consequences, and is not recommended.)

>> A Python database connector could choose to PREPARE/EXECUTE for every
>> query it's given,
>
> That would not be wise, given that not every query contains variable
> parameters.

Irrelevant. It would still be legal. Do you understand the difference
between what is legal according to a specification and what is
actually worth doing? In an explanation of what a parameterized query
is, I would expect to be discussing what is semantically and
functionally valid, not which optimizations are worth doing.

>> or it could choose to escape all the parameters and embed them,
>
> Recommended against, and not a parameterized query at all.

Not once it reaches the underlying database, but it is parameterized
in the source code. It's not possible for an external attacker to get
past the escaping, if it is done correctly. It is still legal,
however, it is indeed not recommended.

>> or it could (if it's using a decent database back-end like PostgreSQL)
>> simply send the query and its associated parameters as-is. Only one of
>> these options is a "prepared statement".
>
> Maybe.  I do not know enough about PostgreSQL and its “[sending] the query
> and its associated parameters as-is” yet to confirm or deny this.

The wire protocol supports this.

>> All three are "parameterized queries", at least from the POV of Python
>> code.
>
> You are mistaken, then: Of the three kinds of “parameterized queries” as
> *you* understand them (OWASP and I beg to differ), at least one of them
> that is not used in a prepared statement is *insufficient to prevent SQL
> injection*.

Okay, then. Please explain how this code is vulnerable to SQL injection:

conn = some_db_module.connect("")
cur = conn.cursor()
data = input("Enter a value: ")
cur.execute("insert into some_table (some_column) values (%s)", (input,))
conn.commit()

Do you need to know the implementation of cur.execute to be able to
say whether this is safe, or can you be confident that, short of
really blatantly obvious bugs in the database connector, this is
genuinely a parameterized query? I posit that the latter is the case.
MY CODE has a query with a parameter. After that, it's not my problem;
attacks on lower-level services are always possible, but aren't called
"SQL injection".

> The second kind also moves tasks to the programming language that are better
> done by the DBMS; the program code should database-agnostic (in the best
> case, for mockup testing, even oblivious of the database).
>
> Which is why programming languages have come to support prepared statements,
> and why OWASP recommends to use either them or stored procedures.

What would you change in the above code? Does it really need prepared
statements or stored procedures? Surely the recommendation of Python
is to keep things simple and expressive?

ChrisA

[toc] | [prev] | [next] | [standalone]


#105724

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2016-03-26 04:30 +0100
Message-ID<2279730.a2M0GptDFN@PointedEars.de>
In reply to#105713
Chris Angelico wrote:

> On Sat, Mar 26, 2016 at 9:25 AM, Thomas 'PointedEars' Lahn
> <PointedEars@web.de> wrote:

Attribution line, not attribution novel.

>> Chris Angelico wrote:
>>> On Sat, Mar 26, 2016 at 8:28 AM, Thomas 'PointedEars' Lahn
>>> <PointedEars@web.de> wrote:
>>>> Then enlighten me, please: How is “parameterization” or a
>>>> “parameterized query”, as *you* understand it, different from a
>>>> prepared statement?
>>>
>>> This is a prepared statement:
>>>
>>> http://www.postgresql.org/docs/current/static/sql-prepare.html
>>>
>>> You use a special "PREPARE" query to create *and store* a half-run
>>> query,
>>
>> [Having written a database layer (in PHP) myself, I know what a prepared
>> statement is, thank you very much.]
>>
>> Your statement is incorrect both for MySQL (which I know) and PostgreSQL
>> (AIUI your reference): The query is processed and stored of course, but
>> it is definitely _not_ *run* before the EXECUTE command is issued for it.
> 
> It legal to partly perform the query.

What are you getting at?  A query cannot be performed if the values of its 
parameters have no defined value yet.

> DB2 can retain a "query plan" which consists of the exact paths it will
> follow. So I stand by my statement.

A query plan is _not_ the *execution* (“run”) of a query, but the result of 
*processing* a query (AISB).  So you are still wrong.
 
>>> Back in the 1990s, I had the option of actually *compiling* my SQL
>>> queries as part of my C code, which would prepare all the queries for
>>> future execution. It is completely different from the dynamic
>>> parameterized queries that most people use.
>> Interesting, but irrelevant.
> 
> Not really, no. It was a form of PREPARE/EXECUTE that hid the PREPARE
> behind a convenient syntax, and then replaced it with EXECUTE for the
> run-time.

IOW, a prepared statement.  Thanks for the confirmation.
 
>>> Parameterization is a more general concept which prepared statements
>>> invariably use, but which general code need not use.
>>
>> If it is to be safe from SQL injection, it better uses a parameterized
>> query as it is *commonly* understood.
> 
> Why? […]

Far beyond the scope of this newsgroup/mailing list.  RTFM I referred to.

>>> A Python database connector could choose to PREPARE/EXECUTE for every
>>> query it's given,
>> That would not be wise, given that not every query contains variable
>> parameters.
> 
> Irrelevant. It would still be legal. Do you understand the difference
> between what is legal according to a specification and what is
> actually worth doing?

Red herring.  Legality (better: validity) was not the issue.  Whether 
legal/valid code or or not, it would still not be wise because application 
performance would be reduced at little advantage, if any.

>>> or it could choose to escape all the parameters and embed them,
>> Recommended against, and not a parameterized query at all.
> 
> Not once it reaches the underlying database,

And that is not how “parameterized query” is commonly defined.

>>> All three are "parameterized queries", at least from the POV of Python
>>> code.
>> You are mistaken, then: Of the three kinds of “parameterized queries” as
>> *you* understand them (OWASP and I beg to differ), at least one of them
>> that is not used in a prepared statement is *insufficient to prevent SQL
>> injection*.
> 
> Okay, then. Please explain how this code is vulnerable to SQL injection:
> 
> conn = some_db_module.connect("")
> cur = conn.cursor()
> data = input("Enter a value: ")
         ^^^^^
> cur.execute("insert into some_table (some_column) values (%s)", (input,))
                                                                   ^^^^^
> conn.commit()

This code is not vulnerable to SQL injection, unless “input” referred to an 
object that had both a suitable __call__() or __init__(), and __str__() 
method ;->

Probably you meant

#---------------------------------------------------------------------------
conn = some_db_module.connect("")
cur = conn.cursor()
data = input("Enter a value: ")
cur.execute("insert into some_table (some_column) values (%s)", (data,))
conn.commit()
#---------------------------------------------------------------------------

Since nothing indicates the used module and accessed DBMS (only that, if it 
is Python code, the module cannot be sqlite3 as that does not support “%s”), 
then this code can, if the module uses an escaping mechanism, still be 
vulnerable to SQL injection.  For example, I could input something to the 
effect of

#---------------------------------------------------------------------------
data = r'\"); DROP TABLE some_table; --'
#---------------------------------------------------------------------------

if, for example, the string escaping mechanism in the module would simply 
duplicate any double-quote it finds to escape it in the string literal that 
it created (as is possible in MySQL and PostgreSQL), and still inject my 
code because the resulting query would be

  insert into some_table (some_column) values ("\"");
  DROP TABLE some_table;
  --")

which is at least syntactically valid MySQL code, but from the perspective 
of the so-attacked it is still not fine as the table would be gone 
afterwards.

See also:

- <http://stackoverflow.com/a/139810/855543>
- <https://xkcd.com/327/> ;-)

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#105726

FromChris Angelico <rosuav@gmail.com>
Date2016-03-26 14:46 +1100
Message-ID<mailman.18.1458964008.28225.python-list@python.org>
In reply to#105724
On Sat, Mar 26, 2016 at 2:30 PM, Thomas 'PointedEars' Lahn
<PointedEars@web.de> wrote:
> Since nothing indicates the used module and accessed DBMS (only that, if it
> is Python code, the module cannot be sqlite3 as that does not support “%s”),
> then this code can, if the module uses an escaping mechanism, still be
> vulnerable to SQL injection.  For example, I could input something to the
> effect of
>
> #---------------------------------------------------------------------------
> data = r'\"); DROP TABLE some_table; --'
> #---------------------------------------------------------------------------
>
> if, for example, the string escaping mechanism in the module would simply
> duplicate any double-quote it finds to escape it in the string literal that
> it created (as is possible in MySQL and PostgreSQL), and still inject my
> code because the resulting query would be
>
>   insert into some_table (some_column) values ("\"");
>   DROP TABLE some_table;
>   --")
>
> which is at least syntactically valid MySQL code, but from the perspective
> of the so-attacked it is still not fine as the table would be gone
> afterwards.

In other words, you are assuming that the string escaping *in the
module* is buggy. Well, duh. This is exactly what I said about not
having stupid bugs. The developer of a MySQL binding library should
know the *entire* rules for escaping, and, duh, that's going to
include escaping the backslash. So the escaped query would be
something like:

  insert into some_table (some_column) values ("\\"");
  DROP TABLE some_table;
  --")

which would be interpreted correctly by MySQL.

ChrisA

[toc] | [prev] | [next] | [standalone]


#106594

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2016-04-06 20:42 +0200
Message-ID<1661862.z6Vd3VmDt3@PointedEars.de>
In reply to#105726
Chris Angelico wrote:

> In other words, you are assuming that the string escaping *in the
> module* is buggy. Well, duh. This is exactly what I said about not
> having stupid bugs. The developer of a MySQL binding library should
> know the *entire* rules for escaping, and, duh, that's going to
> include escaping the backslash. So the escaped query would be
> something like:
> 
>   insert into some_table (some_column) values ("\\"");
>   DROP TABLE some_table;
>   --")
> 
> which would be interpreted correctly by MySQL.

There is no way a version of a module can safely use an escaping mechanism 
that handles all possible *future* cases.  Further, there are escaping costs 
on the client to be considered for *every* query.

So my recommendation, based on best current practice (OWASP), stands: Use 
prepared statements or stored procedures and let the database do the job.  
*Better be safe than sorry.*  See xkcd.

Bonuses with prepared statements: Not only can the client skip the escaping, 
but queries are faster if you have to do the same query just with different 
parameters.  And you can do things with prepared statements that you cannot 
do in another way (for example, parameterized LIMIT [1]).

Bonus with stored procedures: You can do more complex tasks with less 
overhead.

Off-topic --> EOD.

[1] <news:2193528.dSJ3Ry9s4d@PointedEars.de>

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web