Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #105163 > unrolled thread
| Started by | Daniel Wilcox <dmw@yubasolutions.com> |
|---|---|
| First post | 2016-03-17 15:34 -0700 |
| Last post | 2016-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.
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
| From | Daniel Wilcox <dmw@yubasolutions.com> |
|---|---|
| Date | 2016-03-17 15:34 -0700 |
| Subject | Re: 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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2016-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2016-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2016-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]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2016-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]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2016-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]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2016-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