Now in adapting our form DB
code to use a real database,
you might have written something
that looks a lot like this.
In the get all posts function, you
connect to a database, make a cursor,
execute a SELECT statement,
format the results appropriately,
close the connection return the posts.
But then to add a post,
connect to the database, make a cursor.
Execute an INSERT that
substitutes in the post content,
commit that to the database and close.
Now, this looks good,
but it isn't quite.
If you're writing a bunch
of different forum app.
Are there any posts that don't
seem to work quite right?
Say what?
Wait a minute.
That looked like a perfectly good post.
Why are we getting this
weird error from it?
Let's go back to our terminal.
Oh, look at this.
We have a trace back from python.
It says programming error.
Syntax error at or near t.
And there's out INSERT statement VALUES.
I can't find a problem.
Let's look back at the code.
So, here's where the post content,
gets sent to the database.
It just gets added into a SQL statement.
Inside single quotes.
Because, we put SQL strings
inside single quotes.
But the database, sees the quote from
the post, and it thinks that's the end
of a string, and that t is
something it doesn't understand.
By the way,
if your code didn't have this bug,
congratulations, that's awesome.
But stay tuned, because there's more
to this bug than might first appear.
Despite the fact that we had a little
problem, we can still post things.
As long as they don't have
single quotes in them.
But here's something to try.
Single quote.
Close param.
Semi colon.
Don't retype this from what I'm saying.
Copy it from the instructor notes,
and put them into your forum.
Delete from posts.
Semi colon.
Double dash.
Post this.
Wait, all, all of our posts are gone.
I thought we had a database here.
Hey, wait a minute.
I thought I saw this one
on the webcomic XKCD.
What we have here is a security hole
called an SQL injection attack.
Some of the post's text is being
treated as a database command,
namely delete from posts.
Which as it happens, means delete
every row from the posts table.
Well, that stinks.
All those brilliant test
posts we wrote are gone, and
we have a famous security
bug in our code.
How are we going to fix this?
Well, we might not be able to get
all those great posts back, but
we should be able to at least
keep it from happening again.
الآن عند تعديل التعليمة البرمجية لقاعدة
،بيانات النموذج من أجل استخدام قاعدة بيانات حقيقية
ربما تكون قد كتبت شيئًا
.يبدو مثل هذا
في دالة get all posts، تقوم
،بالاتصال بقاعدة بيانات، وعمل cursor
،وتنفيذ عبارة SELECT
،وتنسيق النتائج بطريقة ملائمة
.وإغلاق الاتصال وإرجاع المنشورات
،لكن بعد ذلك، لإضافة منشور
.اتصل بقاعدة البيانات، وقم بعمل cursor
قم بتنفيذ أمر INSERT والذي يقوم
،بالاستبدال في محتويات المنشور
.وتثبيت تلك التغييرات في قاعدة البيانات والإغلاق
،الآن، يبدو ذلك جيدًا
.لكن ليس إلى حد كبير
إذا كنت تقوم بكتابة مجموعة
.من تطبيقات منتديات المناقشة المختلفة
هل توجد منشورات يبدو
أنها لا تعمل بطريقة صحيحة؟
ما هي هذه الرسالة؟
.انتظر دقيقة
.لقد بدا ذلك وكأنه منشور مثالي
لماذا يظهر لنا هذا
الخطأ الغريب؟
.لنرجع إلى الوحدة الطرفية الخاصة بنا
.انظر لهذا
.لدينا عنصر تتبع من python
.يقول أنه خطأ في البرمجة
.Syntax error at or near t
.وتظهر عبارة INSERT والتي تتضمن قيمًا VALUES
.I can't find a problem
.لننظر مرة أخرى على التعليمة البرمجية
،هذا هو مكان إرسال post content
.إلى قاعدة البيانات
.لقد تم إضافته إلى عبارة SQL
.داخل علامتي اقتباس مفردتين
لأننا نضع سلاسل SQL داخل
.علامات اقتباس مفردة
لكن قاعدة البيانات، ترى علامة الاقتباس في
المنشور، وتعتقد أنها نهاية
سلسلة، وأن الحرف t شيء
.لا تفهمه
،بالمناسبة
،إذا كانت التعليمة البرمجية الخاصة بك لا تحتوي على هذا الخطأ
.تهانينا، هذا أمر رائع
لكن تابع هذا الموضوع، ربما توجد أشياء أكثر
.تتعلق بهذا الخطأ أكثر مما ظهر أول مرة
وعلى الرغم من حقيقة أن لدينا مشكلة
.صغيرة، يظل بإمكاننا نشر أشياء
طالما لا يوجد فيها
.علامات اقتباس مفردة
.لكن فيما يلي بعض الأشياء لتجربتها
.علامة اقتباس مفردة
.معلمة إغلاق
.فاصلة منقوطة
.لا تقم بإعادة كتابة شيء مما أقوله
،انسخها من ملاحظات المدرب
.وضعها في منتدى المناقشة الخاص بك
.حذف من المنشورات
.فاصلة منقوطة
.شرطة مزدوجة
.انشر هذا
.انتظر، كل منشوراتنا غير موجودة
.اعتقدت أن لدينا قاعدة بيانات هنا
.انتظر دقيقة
أعتقد أنني رأيت هذا في
.موقع XKCD للقصص المصورة على الويب
ما لدينا هنا هو ثغرة أمنية تسمى
.هجمة بحقن SQL
بعض نصوص المنشورات يتم معاملتها
،على أنها أمر قاعدة بيانات
.وهو بالتحديد delete from posts
والذي بمجرد تنفيذه، يحذف
.كل الصفوف من جدول المنشورات
.حسنًا، هذا في منتهى السوء
جميع تلك المنشورات الرائعة
الخاصة بالاختبار قد اختفت، ولدينا
خطأ أمني شهير
.في التعليمة البرمجية
كيف سنقوم بإصلاح هذا؟
حسنًا، قد لا نتمكن من استعادة
كل تلك المنشورات الرائعة، لكن
يجب أن نكون قادرين على الأقل
.أن نمنع حدوث ذلك مرة أخرى
Adaptando nosso código de banco de dados de formulários
para usar um banco de dados reais,
você deve ter escrito algo
que se parece muito com isto.
Na função get all posts, você
se conecta a um banco de dados, cria um cursor,
executa uma instrução SELECT,
formata os resultados corretamente,
fecha a conexão, retorna as postagens.
Mas, em seguida, para adicionar uma postagem,
conecte-se ao banco de dados, crie um cursor.
Execute um INSERT que
faça substituições no conteúdo da postagem,
confirme isso no banco de dados e feche.
Parece bom,
mas não está perfeito.
Se você estiver escrevendo vários
aplicativos de fórum diferentes.
Existem algumas postagens que parecem
não estar funcionando corretamente?
Quer saber?
Espere um minuto.
Esta parecia ser uma postagem totalmente perfeita.
Por que ela está causando este
erro estranho?
Vamos voltar ao nosso terminal.
Ah, veja só isso.
Temos um rastreamento do Python.
Ele diz erro de programação.
Erro de sintaxe no t ou próximo a ele.
E ainda existem os VALORES da instrução de INSERÇÃO.
Não consigo achar um problema.
Vamos olhar novamente o código.
É aqui que o conteúdo da postagem
é enviado para o banco de dados.
Ele apenas é adicionado a uma instrução SQL.
Dentro de aspas simples.
Porque colocamos strings SQL
dentro de aspas simples.
Mas o banco de dados vê as aspas da
postagem e pensa que elas são o fim de
uma string, e isso é
algo que ele não entende.
A propósito,
se o seu código não tiver esse bug,
parabéns, isso é maravilhoso.
Mas fique atento, pois existem mais coisas
a respeito desse bug que podem não aparecer à primeira vista.
Apesar de termos tido um pequeno
problema, ainda conseguimos postar coisas.
Desde que elas não tenham
aspas simples.
Aqui está uma opção para você experimentar.
Aspas simples.
Parâmetro de fechamento.
Ponto-e-vírgula.
Não redigite isso daqui.
Copie das notas do instrutor e
cole em seu fórum.
Exclua das postagens.
Ponto-e-vírgula.
Traço duplo.
Poste isto.
Espere, todas as nossas postagens sumiram.
Pensei que tínhamos um banco de dados aqui.
Ei, espere um minuto.
Pensei ter visto este aqui
no webcomic XKCD.
O que temos aqui é um furo de segurança
chamado de ataque de injeção SQL.
Parte do texto da postagem está sendo
tratada como um comando de banco de dados,
ou seja, delete from posts.
Isso significa excluir
cada linha da tabela de postagens.
Bem, isso é desagradável.
Todas aquelas postagens de teste brilhantes
que escrevemos sumiram, e
temos um famoso bug de segurança
em nosso código.
Como vamos corrigir isso?
Bem, talvez não seja possível
recuperar todas aquelas ótimas postagens, mas
devemos conseguir pelo menos
evitar que isso aconteça de novo.
在我们改进数据库代码 使其用上真正的数据库时
你写出的东西可能跟这个很像
在 getAllPosts 函数里连接数据库 创建光标
执行一个 select 语句 将结果正确地格式化
关闭连接并返回贴子
接下来这个添加贴子的函数 连接数据库 创建光标
执行一个嵌入了帖子内容的 insert 语句
向数据库提交改动然后关闭
看起来没什么不对 然而并不是这样
如果你要写一堆不同的论坛应用
有没有哪些贴子是不能正常运行的?
什么?
稍等
这个贴子挺正常的呀
怎么就出现这个奇怪的错误了呢?
先回到终端里
噢 看这
有一个 python 的回溯信息
写道代码里有错误
在 t 的附近有语法错误
问题发生在 INSERT 语句的 VALUES
并不能看出有啥问题啊
再回头来看看代码
这里就是负责把贴子内容发到数据库的现场
不过是添加了一个 SQL 语句而已
不过是在一对单引号里
因为我们把 SQL 字符串放进一对单引号里
在数据库看来 贴子里也有一个单引号
就把它当成整个语句的结束引号了
所以数据库就看不懂这个 t 是啥了
多说一句 如果你的代码没有这个错误
那么恭喜你 一切完美
但你还要注意这个问题 因为类似错误有很多 可能不会都首次出现
尽管这里有一些小错误 但仍旧还可以发贴子
只要不发带单引号的内容就行了
但我这还有一个例子
单引号
右括号
分号
不用跟着我说的打
从指导步骤中复制到你的论坛就行
从 posts 删除
分号
两个短横
点击发布
哎呦 所有的贴子都没了
我们不是有数据库的吗
等等
我记得这种情况在 XKCD 漫画里有看到过
这其实是一种叫做 SQL 注入攻击的安全漏洞
贴子里的内容被当作了数据库命令
也就是 从 posts 表单删除
当它执行时 就删掉了 posts 表单里所有行的数据
特别讨厌
而且代码里还有一个臭名昭著的安全漏洞
怎么修复它呢?
也许我们再也不能挽回之前那些超酷的贴子了
但至少我们应该避免让它再次发生