ID |
English原文 |
中文翻译 |
最近翻译记录 |
状态 |
操作 |
0#翻译 |
Chapter 19: Security
--------------------
|
第十九章 安全
-------------------- |
6171天前 |
|
翻译 |
1#翻译 |
The Internet can be a scary place.
|
Internet并不安全。 |
5996天前 |
|
翻译 |
2#翻译 |
These days, high-profile security gaffes seem to crop up on a daily basis. Weve seen
viruses spread with amazing speed, swarms of compromised computers wielded as weapons, a
never-ending arms race against spammers, and many, many reports of identify theft from
hacked Web sites.
|
现如今,每天都会出现新的安全问题。我们目睹过病毒飞速地蔓延,大量被控制的肉鸡作为武器来攻击其他人,与垃圾邮件的永无止境的军备竞赛,以及许许多多站点被黑的报告。 |
5963天前 |
|
翻译 |
3#翻译 |
As Web developers, we have a duty to do what we can to combat these forces of darkness.
Every Web developer needs to treat security as a fundamental aspect of Web programming.
Unfortunately, it turns out that implementing security is *hard* attackers need to find
only a single vulnerability, but defenders have to protect every single one.
|
作为web开发人员,我们有责任来对抗这些黑暗的力量。每一个web开发者都应该把安全看成是web编程中的基础部分。不幸的是,要实现安全是困难的。攻击者只需要找到一个微小的薄弱环节,而防守方却要保护得面面俱到。 |
5965天前 |
|
翻译 |
4#翻译 |
Django attempts to mitigate this difficulty. Its designed to automatically protect you from
many of the common security mistakes that new (and even experienced) Web developers make.
Still, its important to understand what these problems are, how Django protects you, and
most important the steps you can take to make your code even more secure.
|
Django试图减轻这种难度。它被设计为自动帮你避免一些web开发新手(甚至是老手)经常会犯的错误。尽管如此,需要弄清楚,Django如何保护我们,以及我们可以采取哪些重要的方法来使得我们的代码更加安全。 |
5965天前 |
|
翻译 |
5#翻译 |
First, though, an important disclaimer: We do not intend to present a definitive guide to
every known Web security exploit, and so we wont try to explain each vulnerability in a
comprehensive manner. Instead, well give a short synopsis of security problems as they
apply to Django.
|
首先,一个重要的前提:我们并不打算给出web安全的一个详尽的说明,因此我们也不会详细地解释每一个薄弱环节。在这里,我们会给出Django所面临的安全问题的一个大概。 |
5965天前 |
|
翻译 |
6#翻译 |
The Theme of Web Security
`````````````````````````
|
Web安全现状
`````````````````````````
|
5965天前 |
|
翻译 |
7#翻译 |
If you learn only one thing from this chapter, let it be this:
|
如果你从这章中只学到了一件事情,那么它会是: |
5930天前 |
|
翻译 |
8#翻译 |
Never under any circumstances trust data from the browser.
|
在任何条件下都不要相信浏览器端提交的数据。 |
5996天前 |
|
翻译 |
9#翻译 |
You *never* know whos on the other side of that HTTP connection. It might be one of your
users, but it just as easily could be a nefarious cracker looking for an opening.
|
你从不会知道HTTP连接的另一端会是谁。可能是一个正常的用户,但是同样可能是一个寻找漏洞的邪恶的骇客。 |
5996天前 |
|
翻译 |
10#翻译 |
Any data of any nature that comes from the browser needs to be treated with a healthy dose
of paranoia. This includes data thats both in band (i.e., submitted from Web forms) and out
of band (i.e., HTTP headers, cookies, and other request information). Its trivial to spoof
the request metadata that browsers usually add automatically.
|
从浏览器传过来的任何性质的数据,都需要近乎狂热地接受检查。这包括用户数据(比如web表单提交的内容)和带外数据(比如,HTTP头、cookies以及其他信息)。要修改那些浏览器自动添加的元数据,是一件很容易的事。 |
5965天前 |
|
翻译 |
11#翻译 |
Every one of the vulnerabilities discussed in this chapter stems directly from trusting
data that comes over the wire and then failing to sanitize that data before using it. You
should make it a general practice to continuously ask, Where does this data come from?
|
在这一章所提到的所有的安全隐患都直接源自对传入数据的信任,并且在使用前不加处理。你需要不断地问自己,这些数据从何而来。 |
5965天前 |
|
翻译 |
12#翻译 |
SQL Injection
`````````````
|
SQL注入 |
6045天前 |
|
翻译 |
13#翻译 |
*SQL injection* is a common exploit in which an attacker alters Web page parameters (such
as ``GET`` /``POST`` data or URLs) to insert arbitrary SQL snippets that a naive Web
application executes in its database directly. Its probably the most dangerous and,
unfortunately, one of the most common vulnerabilities out there.
|
SQL注入 是一个很常见的形式,在SQL注入中,攻击者改变web网页的参数(例如 ``GET`` /``POST`` 数据或者URL地址),加入一些其他的SQL片段。未加处理的网站会将这些信息在后台数据库直接运行。这也许是最危险的一种,然而不幸的是,也是最多的一种隐患。 |
5930天前 |
|
翻译 |
14#翻译 |
This vulnerability most commonly crops up when constructing SQL by hand from user input.
For example, imagine writing a function to gather a list of contact information from a
contact search page. To prevent spammers from reading every single email in our system,
well force the user to type in someones username before providing her email address:
|
这种危险通常在由用户输入构造SQL语句时产生。例如,假设我们要写一个函数,用来从通信录搜索页面收集一系列的联系信息。为防止垃圾邮件发送器阅读系统中的email,我们将在提供email地址以前,首先强制用户输入用户名。 |
5965天前 |
|
翻译 |
17#翻译 |
Note
|
备注 |
2871天前 |
Johnette |
翻译 |
18#翻译 |
In this example, and all similar dont do this examples that follow, weve deliberately left
out most of the code needed to make the functions actually work. We dont want this code to
work if someone accidentally takes it out of context.
|
在这个例子中,以及在以下所有的“不要这样做”的例子里,我们都去除了大量的代码,避免这些函数可以正常工作。我们可不想这些例子被拿出去使用。 |
5965天前 |
|
翻译 |
19#翻译 |
Though at first this doesnt look dangerous, it really is.
|
尽管,一眼看上去,这一点都不危险,实际上却不尽然。 |
5965天前 |
|
翻译 |
20#翻译 |
First, our attempt at protecting our entire email list will fail with a cleverly
constructed query. Think about what happens if an attacker types ``"' OR 'a'='a"`` into the
query box. In that case, the query that the string interpolation will construct will be:
|
首先,我们对于保护email列表所采取的措施,遇到精心构造的查询语句就会失效。想象一下,如果攻击者在查询框中输入 ``"' OR 'a'='a"`` 。此时,查询的字符串会构造如下: |
2871天前 |
Zaiya |
翻译 |
23#翻译 |
Because we allowed unsecured SQL into the string, the attackers added ``OR`` clause ensures
that every single row is returned.
|
由于我们允许不安全的SQL语句出现在字符串中,攻击者加入 ``OR`` 子句,使得每一行数据都被返回。 |
5963天前 |
|
翻译 |
24#翻译 |
However, thats the *least* scary attack. Imagine what will happen if the attacker submits
``"'; DELETE FROM user_contacts WHERE 'a' = 'a'"`` . Well end up with this complete query:
|
事实上,这是最温和的攻击方式。如果攻击者提交了 ``"'; DELETE FROM user_contacts WHERE 'a' = 'a'"`` ,我们最终将得到这样的查询: |
5963天前 |
|
翻译 |
27#翻译 |
Yikes! Whered our contact list go?
|
哦!我们整个通信录名单去哪儿了? |
5965天前 |
|
翻译 |
28#翻译 |
The Solution
''''''''''''
|
解决方案
''''''''''''
|
5965天前 |
|
翻译 |
29#翻译 |
Although this problem is insidious and sometimes hard to spot, the solution is simple:
*never* trust user-submitted data, and *always* escape it when passing it into SQL.
|
尽管这个问题很阴险,并且有时很难发现,解决方法却很简单:
绝不信任用户提交的数据,并且在传递给SQL语句时,总是转义它。 |
5965天前 |
|
翻译 |
30#翻译 |
The Django database API does this for you. It automatically escapes all special SQL
parameters, according to the quoting conventions of the database server youre using (e.g.,
PostgreSQL or MySQL).
|
20ILMD <a href="http://ttrjghnexixr.com/">ttrjghnexixr</a>, [url=http://uasrdouyximt.com/]uasrdouyximt[/url], [link=http://xhsyxhkdudmy.com/]xhsyxhkdudmy[/link], http://udcefujhrbii.com/ |
4745天前 |
|
翻译 |
31#翻译 |
For example, in this API call:
|
举个例子,在下面这个API调用中: |
5963天前 |
|
翻译 |
34#翻译 |
Django will escape the input accordingly, resulting in a statement like this:
|
Django会自动进行转义,得到如下表达: |
5965天前 |
|
翻译 |
37#翻译 |
Completely harmless.
|
完全无害。 |
5965天前 |
|
翻译 |
38#翻译 |
This applies to the entire Django database API, with a couple of exceptions:
|
这被运用到了整个Django的数据库API中,只有一些例外: |
5965天前 |
|
翻译 |
39#翻译 |
* The ``where`` argument to the ``extra()`` method (see Appendix C). That parameter
accepts raw SQL by design.
|
* 传给 ``extra()`` 方法的 ``where`` 参数(参见附录C)。这个参数接受原始的SQL语句。 |
5930天前 |
|
翻译 |
40#翻译 |
* Queries done by hand using the lower-level database API.
|
* 使用底层数据库API的查询。
|
5965天前 |
|
翻译 |
41#翻译 |
In each of these cases, its easy to keep yourself protected. In each case, avoid string
interpolation in favor of passing in *bind parameters* . That is, the example we started
this section with should be written as follows:
|
以上列举的每一个示例都能够很容易的让您的应用得到保护。在每一个示例中,为了避免字符串被篡改而使用 *绑定参数* 来代替。也就是说,在本章中我们使用到的所有示例都应该写成如下所示: |
5963天前 |
|
翻译 |
44#翻译 |
The low-level ``execute`` method takes a SQL string with ``%s`` placeholders and
automatically escapes and inserts parameters from the list passed as the second argument.
You should *always* construct custom SQL this way.
|
底层 ``execute`` 方法采用了一个SQL字符串作为其第二个参数,这个SQL字符串包含若干'%s'占位符,execute方法能够自动对传入列表中的参数进行转义和插入。 |
2871天前 |
Diandra |
翻译 |
45#翻译 |
Unfortunately, you cant use bind parameters everywhere in SQL; theyre not allowed as
identifiers (i.e., table or column names). Thus, if you need to, say, dynamically construct
a list of tables from a ``POST`` variable, youll need to escape that name in your code.
Django provides a function, ``django.db.backend.quote_name`` , which will escape the
identifier according to the current databases quoting scheme.
|
不幸的是,您并不是在SQL中能够处处都使用绑定参数,绑定参数不能够作为标识符(如表或列名等)。因此,如果您需要这样做--我是说--动态构建 ``POST`` 变量中的数据库表的列表的话,您需要在您的代码中来对这些数据库表的名字进行转义。Django提供了一个函数, ``django.db.backend.quote_name`` ,这个函数能够根据当前数据库引用结构对这些标识符进行转义。 |
5963天前 |
|
翻译 |
46#翻译 |
Cross-Site Scripting (XSS)
``````````````````````````
|
跨站点脚本 (XSS)
``````````````````````````
|
5963天前 |
|
翻译 |
47#翻译 |
*Cross-site scripting* (XSS), is found in Web applications that fail to escape
user-submitted content properly before rendering it into HTML. This allows an attacker to
insert arbitrary HTML into your Web page, usually in the form of ``<script>`` tags.
|
在Web应用中, *跨站点脚本* (XSS)有时在被渲染成HTML之前,不能恰当地对用户提交的内容进行转义。这使得攻击者能够向你的网站页面插入通常以 ``<script>`` 标签形式的任意HTML代码。 |
5930天前 |
|
翻译 |
48#翻译 |
Attackers often use XSS attacks to steal cookie and session information, or to trick users
into giving private information to the wrong person (aka *phishing* ).
|
攻击者通常利用XSS攻击来窃取cookie和会话信息,或者诱骗用户将其私密信息透漏给别人(又称 *钓鱼* )。 |
5528天前 |
|
翻译 |
49#翻译 |
This type of attack can take a number of different forms and has almost infinite
permutations, so well just look at a typical example. Consider this extremely simple Hello,
World view:
|
这种类型的攻击能够采用多种不同的方式,并且拥有几乎无限的变体,因此我们还是只关注某个典型的例子吧。让我们来想想这样一个极度简单的Hello World视图: |
5963天前 |
|
翻译 |
52#翻译 |
This view simply reads a name from a ``GET`` parameter and passes that name to the
``hello.html`` template. We might write a template for this view as follows:
|
这个视图只是简单的从GET参数中读取姓名然后将姓名传递给hello.html模板。我们可能会为这个视图编写如下所示的模板: |
5964天前 |
|
翻译 |
55#翻译 |
So if we accessed ``http://example.com/hello/name=Jacob`` , the rendered page would contain
this:
|
因此,如果我们访问 ``http://example.com/hello/?name=Jacob`` ,被呈现的页面将会包含一以下这些: |
5930天前 |
|
翻译 |
58#翻译 |
But wait what happens if we access ``http://example.com/hello/name=<i>Jacob</i>`` ? Then we
get this:
|
但是,等等,如果我们访问 ``http://example.com/hello/?name=<i>Jacob</i>`` 时又会发生什么呢?然后我们会得到: |
2871天前 |
Lilly |
翻译 |
61#翻译 |
Of course, an attacker wouldnt use something as benign as ``<i>`` tags; he could include a
whole set of HTML that hijacked your page with arbitrary content. This type of attack has
been used to trick users into entering data into what looks like their banks Web site, but
in fact is an XSS-hijacked form that submits their back account information to an attacker.
|
当然,一个攻击者不会使用<i>标签开始的类似代码,他可能会用任意内容去包含一个完整的HTML集来劫持您的页面。这种类型的攻击已经运用于虚假银行站点以诱骗用户输入个人信息,事实上这就是一种劫持XSS的形式,用以使用户向攻击者提供他们的银行帐户信息。 |
2871天前 |
Latisha |
翻译 |
62#翻译 |
The problem gets worse if you store this data in the database and later display it it on
your site. For example, MySpace was once found to be vulnerable to an XSS attack of this
nature. A user inserted JavaScript into his profile that automatically added him as your
friend when you visited his profile page. Within a few days, he had millions of friends.
|
如果您将这些数据保存在数据库中,然后将其显示在您的站点上,那么问题就变得更严重了。例如,一旦MySpace被发现这样的特点而能够轻易的被XSS攻击,后果不堪设想。某个用户向他的简介中插入JavaScript,使得您在访问他的简介页面时自动将其加为您的好友,这样在几天之内,这个人就能拥有上百万的好友。 |
5964天前 |
|
翻译 |
63#翻译 |
Now, this may sound relatively benign, but keep in mind that this attacker managed to get
*his* code not MySpaces running on *your* computer. This violates the assumed trust that
all the code on MySpace is actually written by MySpace.
|
现在,这种后果听起来还不那么恶劣,但是您要清楚——这个攻击者正设法将 *他* 的代码而不是MySpace的代码运行在 *您* 的计算机上。这显然违背了假定信任——所有运行在MySpace上的代码应该都是MySpace编写的,而事实上却不如此。 |
5963天前 |
|
翻译 |
64#翻译 |
MySpace was extremely lucky that this malicious code didnt automatically delete viewers
accounts, change their passwords, flood the site with spam, or any of the other nightmare
scenarios this vulnerability unleashes.
|
MySpace是极度幸运的,因为这些恶意代码并没有自动删除访问者的帐户,没有修改他们的密码,也并没有使整个站点一团糟,或者出现其他因为这个弱点而导致的其他噩梦。 |
5964天前 |
|
翻译 |
65#翻译 |
The Solution
''''''''''''
|
解决方案
''''''''''''
|
2871天前 |
Aggy |
翻译 |
66#翻译 |
The solution is simple: *always* escape *any* content that might have come from a user. If
we simply rewrite our template as follows:
|
解决方案是简单的:总是转义可能来自某个用户的任何内容。如果我们像如下代码来简单的重写我们的模板: |
5964天前 |
|
翻译 |
69#翻译 |
then were no longer vulnerable. You should *always* use the ``escape`` tag (or something
equivalent) when displaying user-submitted content on your site.
|
这样一来就不总是那么的弱不禁风了。在您的站点上显示用户提交的内容时,您应该总是使用escape标签(或其他类似的东西)。 |
5964天前 |
|
翻译 |
70#翻译 |
Why Doesnt Django Just Do This for You?
|
为什么Django没有为您完成这些呢? |
5964天前 |
|
翻译 |
71#翻译 |
Modifying Django to automatically escape all variables displayed in templates is a frequent
topic of discussion on the Django developer mailing list.
|
在Django开发者邮件列表中,将Django修改成为能够自动转义在模板中显示的所有变量是一个老话题了。 |
5964天前 |
|
翻译 |
72#翻译 |
So far, Djangos templates have avoided this behavior because it subtly changes what should
be relatively straightforward behavior (displaying variables). Its a tricky issue and a
difficult tradeoff to evaluate. Adding hidden implicit behavior is against Djangos core
ideals (and Pythons, for that matter), but security is equally important.
|
迄今为止,Django模板都避免这种行为,因为这样就略微改变了Django应该相对直接的行为(展现变量)。这是一个棘手的问题,在评估上的一种艰难折中。增加隐藏隐式行为违反了Django的核心理念(对于Pythons也是如此),但是安全性是同等的重要。 |
5964天前 |
|
翻译 |
73#翻译 |
All this is to say, then, that theres a fair chance Django will grow some form of
auto-escaping (or nearly auto-escaping) behavior in the future. Its a good idea to check
the official Django documentation for the latest in Django features; it will always be more
up to date than this book, especially the print edition.
|
所有这一切都表明,在将来某个适当的时机,Django会开发出某些形式的自动转义(或者很大程度上的自动转义)。在Django特性最新消息中查找正式官方文档是一个不错的主意,那里的东西总是要比本书中陈述的要更新的多,特别是打印版本。 |
5964天前 |
|
翻译 |
74#翻译 |
Even if Django does add this feature, however, you should *still* be in the habit of asking
yourself, at all times, Where does this data come from? No automatic solution will ever
protect your site from XSS attacks 100% of the time.
|
甚至,如果Django真的新增了这些特性,您也应该习惯性的问自己,一直以来,这些数据都来自于哪里呢?没有哪个自动解决方案能够永远保护您的站点百分之百的不会受到XSS攻击。 |
5964天前 |
|
翻译 |
75#翻译 |
Cross-Site Request Forgery
``````````````````````````
|
伪造跨站点请求
`````````````` |
5930天前 |
|
翻译 |
76#翻译 |
Cross-site request forgery (CSRF) happens when a malicious Web site tricks users into
unknowingly loading a URL from a site at which theyre already authenticated hence taking
advantage of their authenticated status.
|
伪造跨站点请求(CSRF)发生在当某个恶意Web站点诱骗用户不知不觉的从一个信任站点下载某个URL之时,这个信任站点已经被通过信任验证,因此恶意站点就利用了这个被信任状态。 |
5930天前 |
|
翻译 |
77#翻译 |
Django has built-in tools to protect from this kind of attack. Both the attack itself and
those tools are covered in great detail in Chapter 14.
|
Django拥有内建工具来防止这种攻击。这种攻击的介绍和该内建工具都在第14章中进行进一步的阐述。 |
5748天前 |
|
翻译 |
78#翻译 |
Session Forging/Hijacking
`````````````````````````
|
会话伪造/劫持
````````````````````````` |
5963天前 |
|
翻译 |
79#翻译 |
This isnt a specific attack, but rather a general class of attacks on a users session data.
It can take a number of different forms:
|
这不是某个特定的攻击,而是对用户会话数据的通用类攻击。这种攻击可以采取多种形式: |
5964天前 |
|
翻译 |
80#翻译 |
A *man-in-the-middle* attack, where an attacker snoops on session data as it travels
over the wire (or wireless) network.
|
*中间人* 攻击:在这种攻击中攻击者在监听有线(或者无线)网络上的会话数据。
|
2871天前 |
Jace |
翻译 |
81#翻译 |
*Session forging* , where an attacker uses a session ID (perhaps obtained through a
man-in-the-middle attack) to pretend to be another user.
|
*伪造会话* :攻击者利用会话ID(可能是通过中间人攻击来获得)将自己伪装成另一个用户。 |
5930天前 |
|
翻译 |
82#翻译 |
An example of these first two would be an attacker in a coffee shop using the shops
wireless network to capture a session cookie. She could then use that cookie to
impersonate the original user.
|
这两种攻击的一个例子可以是在一间咖啡店里的某个攻击者利用店的无线网络来捕获某个会话cookie,然后她就可以利用那个cookie来假冒原始用户。 |
5930天前 |
|
翻译 |
83#翻译 |
A *cookie-forging* attack, where an attacker overrides the supposedly read-only data
stored in a cookie. Chapter 12 explains in detail how cookies work, and one of the
salient points is that its trivial for browsers and malicious users to change cookies
without your knowledge.
|
*伪造cookie* :就是指某个攻击者覆盖了在某个cookie中本应该是只读的数据。第12章详细地解释了cookie的工作原理,cookie的一个显著特点就是浏览者和恶意用户想要背着您做些修改,是一件很稀松平常的事情。 |
5930天前 |
|
翻译 |
84#翻译 |
Theres a long history of Web sites that have stored a cookie like ``IsLoggedIn=1`` or
even ``LoggedInAsUser=jacob`` . Its dead simple to exploit these types of cookies.
|
Web站点以 ``IsLoggedIn=1`` 或者 ``LoggedInAsUser=jacob`` 这样的方式来保存cookie由来已久,使用这样的cookie是再简单不过的了。 |
5930天前 |
|
翻译 |
85#翻译 |
On a more subtle level, though, its never a good idea to trust anything stored in
cookies; you never know whos been poking at them.
|
但是,从更加细微的层面来看,信任存储在cookie中的任何东西都从来不是一个好主意,因为您从来不知道多少人已经对它一清二楚。 |
5930天前 |
|
翻译 |
86#翻译 |
*Session fixation* , where an attacker tricks a user into setting or reseting the users
session ID.
|
*会话滞留* :攻击者诱骗用户设置或者重设置该用户的会话ID。 |
5930天前 |
|
翻译 |
87#翻译 |
For example, PHP allows session identifiers to be passed in the URL (e.g.,
``http://example.com/?PHPSESSID=fa90197ca25f6ab40bb1374c510d7a32`` ). An attacker who
tricks a user into clicking a link with a hard-coded session ID will cause the user to
pick up that session.
|
例如,PHP允许在URL(如 ``http://example.com/?PHPSESSID=fa90197ca25f6ab40bb1374c510d7a32`` 等)中传递会话标识符。攻击者诱骗用户点击某个带有硬编码会话ID的链接就会导致该用户恢复那个会话。 |
5930天前 |
|
翻译 |
88#翻译 |
Session fixation has been used in phishing attacks to trick users into entering
personal information into an account the attacker owns. He can later log into that
account and retrieve the data.
|
会话滞留已经运用在钓鱼攻击中,以诱骗用户在攻击者拥有的账号里输入其个人信息,之后攻击者就能够登陆自己的帐户来获取被骗用户输入的数据。 |
2871天前 |
Neveah |
翻译 |
89#翻译 |
*Session poisoning* , where an attacker injects potentially dangerous data into a users
session usually through a Web form that the user submits to set session data.
|
*会话中毒* :攻击者通过用户提交设置会话数据的Web表单向该用户会话中注入潜在危险数据。 |
5930天前 |
|
翻译 |
90#翻译 |
A canonical example is a site that stores a simple user preference (like a pages
background color) in a cookie. An attacker could trick a user into clicking a link to
submit a color that actually contains an XSS attack; if that color isnt escaped, the
user could again inject malicious code into the users environment.
|
一个经典的例子就是一个站点在某个cookie中存储了简单的用户偏好(比如一个页面背景颜色)。攻击者能够诱骗用户点击某个链接来提交某种颜色,而实际上链接中已经包含了某个XXS攻击,如果这个颜色没有被转义,攻击者就可以继续向该用户环境中注入恶意代码。 |
5930天前 |
|
翻译 |
91#翻译 |
The Solution
''''''''''''
|
解决方案
''''''''''''
|
5963天前 |
|
翻译 |
92#翻译 |
There are a number of general principles that can protect you from these attacks:
|
有许多基本准则能够保护您不受到这些攻击: |
5964天前 |
|
翻译 |
93#翻译 |
Never allow session information to be contained in the URL.
|
不要在URL中包含任何session信息。 |
5930天前 |
|
翻译 |
94#翻译 |
Djangos session framework (see Chapter 12) simply doesnt allow sessions to be contained
in the URL.
|
Django的session框架(见第12章)干脆不允许URL中包含session。 |
5930天前 |
|
翻译 |
95#翻译 |
Dont store data in cookies directly; instead, store a session ID that maps to session
data stored on the back-end.
|
不要直接在cookie中存储数据,而是保存一个映射后台session数据的session ID。 |
5930天前 |
|
翻译 |
96#翻译 |
If you use Djangos built-in session framework (i.e., ``request.session`` ), this is
handled automatically for you. The only cookie that the session framework uses is a
single session ID; all the session data is stored in the database.
|
如果使用Django内置的session框架(即 ``request.session`` ),它会自动进行处理。这个session框架仅在cookie中存储一个session ID,所有的session数据将会被存储在数据库中。 |
5930天前 |
|
翻译 |
97#翻译 |
Remember to escape session data if you display it in the template. See the earlier XSS
section, and remember that it applies to any user-created content as well as any data
from the browser. You should treat session information as being user created.
|
如果需要在模板中显示session数据,要记得对其进行转义。可参考之前的XSS部分,对所有用户提交的数据和浏览器提交的数据进行转义。对于session信息,应该像用户提交的数据一样对其进行处理。 |
5930天前 |
|
翻译 |
98#翻译 |
Prevent attackers from spoofing session IDs whenever possible.
|
任何可能的地方都要防止攻击者进行session欺骗。 |
5930天前 |
|
翻译 |
99#翻译 |
Although its nearly impossible to detect someone whos hijacked a session ID, Django
does have built-in protection against a brute-force session attack. Session IDs are
stored as hashes (instead of sequential numbers), which prevents a brute-force attack,
and a user will always get a new session ID if she tries a nonexistent one, which
prevents session fixation.
|
尽管去探测究竟是谁劫持了会话ID是几乎不可能的事儿,Django还是内置了保护措施来抵御暴力会话攻击。会话ID被存在哈希表里(取代了序列数字),这样就阻止了暴力攻击,并且如果一个用户去尝试一个不存在的会话那么她总是会得到一个新的会话ID,这样就阻止了会话滞留。 |
5930天前 |
|
翻译 |
100#翻译 |
Notice that none of those principles and tools prevents man-in-the-middle attacks. These
types of attacks are nearly impossible to detect. If your site allows logged-in users to
see any sort of sensitive data, you should *always* serve that site over HTTPS.
Additionally, if you have an SSL-enabled site, you should set the ``SESSION_COOKIE_SECURE``
setting to ``True`` ; this will make Django only send session cookies over HTTPS.
|
请注意,以上没有一种准则和工具能够阻止中间人攻击。这些类型的攻击是几乎不可能被探测的。如果你的站点允许登陆用户去查看任意敏感数据的话,你应该 *总是* 通过HTTPS来提供网站服务。此外,如果你的站点使用SSL,你应该将 ``SESSION_COOKIE_SECURE`` 设置为 ``True`` ,这样就能够使Django只通过HTTPS发送会话cookie。 |
5930天前 |
|
翻译 |
101#翻译 |
Email Header Injection
``````````````````````
|
邮件头部注入
``````````````````````
|
5963天前 |
|
翻译 |
102#翻译 |
SQL injections less well-known sibling, *email header injection* , hijacks Web forms that
send email. An attacker can use this technique to send spam via your mail server. Any form
that constructs email headers from Web form data is vulnerable to this kind of attack.
|
*邮件头部注入* :仅次于SQL注入,是一种通过劫持发送邮件的Web表单的攻击方式。攻击者能够利用这种技术来通过你的邮件服务器发送垃圾邮件。在这种攻击面前,任何方式的来自Web表单数据的邮件头部构筑都是非常脆弱的。 |
5930天前 |
|
翻译 |
103#翻译 |
Lets look at the canonical contact form found on many sites. Usually this sends a message
to a hard-coded email address and, hence, doesnt appear vulnerable to spam abuse at first
glance.
|
让我们看看在我们许多网站中发现的这种攻击的形式。通常这种攻击会向硬编码邮件地址发送一个消息,因此,第一眼看上去并不显得像面对垃圾邮件那么脆弱。 |
5964天前 |
|
翻译 |
104#翻译 |
However, most of these forms also allow the user to type in his own subject for the email
(along with a from address, body, and sometimes a few other fields). This subject field is
used to construct the subject header of the email message.
|
但是,大多数表单都允许用户输入自己的邮件主题(同时还有from地址,邮件体,有时还有部分其他字段)。这个主题字段被用来构建邮件消息的主题头部。 |
5964天前 |
|
翻译 |
105#翻译 |
If that header is unescaped when building the email message, an attacker could submit
something like ``"hello\ncc:spamvictim@example.com"`` (where ``"\n`` is a newline
character). That would make the constructed email headers turn into:
|
如果那个邮件头部在构建邮件信息时没有被转义,那么攻击者可以提交类似 ``"hello\ncc:spamvictim@example.com"`` (这里的 ``"\n"`` 是换行符)的东西。这有可能使得所构建的邮件头部变成: |
2871天前 |
Buddy |
翻译 |
108#翻译 |
Like SQL injection, if we trust the subject line given by the user, well allow him to
construct a malicious set of headers, and he can use our contact form to send spam.
|
就像SQL注入那样,如果我们信任了用户提供的主题行,那样同样也会允许他构建一个头部恶意集,他也就能够利用联系人表单来发送垃圾邮件。 |
2871天前 |
Bubbie |
翻译 |
109#翻译 |
The Solution
''''''''''''
|
解决方案
''''''''''''
|
5963天前 |
|
翻译 |
110#翻译 |
We can prevent this attack in the same way we prevent SQL injection: always escape or
validate user-submitted content.
|
我们能够采用与阻止SQL注入相同的方式来阻止这种攻击:总是校验或者转义用户提交的内容。 |
5964天前 |
|
翻译 |
111#翻译 |
Djangos built-in mail functions (in ``django.core.mail`` ) simply do not allow newlines in
any fields used to construct headers (the from and to addresses, plus the subject). If you
try to use ``django.core.mail.send_mail`` with a subject that contains newlines, Django
will raise a ``BadHeaderError`` exception.
|
Django内建邮件功能(在 ``django.core.mail`` 中)根本不允许在用来构建邮件头部的字段中存在换行符(表单,to地址,还有主题)。如果您试图使用 ``django.core.mail.send_mail`` 来处理包含换行符的主题时,Django将会抛出BadHeaderError异常。 |
5930天前 |
|
翻译 |
112#翻译 |
If you do not use Djangos built-in mail functions to send email, youll need to make sure
that newlines in headers either cause an error or are stripped. You may want to examine the
``SafeMIMEText`` class in ``django.core.mail`` to see how Django does this.
|
如果你没有使用Django内建邮件功能来发送邮件,那么你需要确保包含在邮件头部的换行符能够引发错误或者被去掉。你或许想仔细阅读 ``django.core.mail`` 中的 ``SateMIMEText`` 类来看看Django是如何做到这一点的。 |
5930天前 |
|
翻译 |
113#翻译 |
Directory Traversal
```````````````````
|
目录遍历
``````````````````` |
5963天前 |
|
翻译 |
114#翻译 |
*Directory traversal* is another injection-style attack, wherein a malicious user tricks
filesystem code into reading and/or writing files that the Web server shouldnt have access
to.
|
*目录遍历* :是另外一种注入方式的攻击,在这种攻击中,恶意用户诱骗文件系统代码对Web服务器不应该访问的文件进行读取和/或写入操作。 |
5963天前 |
|
翻译 |
115#翻译 |
An example might be a view that reads files from the disk without carefully sanitizing the
file name:
|
例子可以是这样的,某个视图试图在没有仔细对文件进行防毒处理的情况下从磁盘上读取文件: |
2871天前 |
Honney |
翻译 |
118#翻译 |
Though it looks like that view restricts file access to files beneath ``BASE_PATH`` (by
using ``os.path.join`` ), if the attacker passes in a ``filename`` containing ``..`` (thats
two periods, a shorthand for the parent directory), she can access files above
``BASE_PATH`` . Its only a matter of time before she can discover the correct number of
dots to successfully access, say, ``../../../../../etc/passwd`` .
|
尽管一眼看上去,视图通过 ``BASE_PATH`` (通过使用 ``os.path.join`` )限制了对于文件的访问,但如果攻击者使用了包含 ``..`` (两个句号,父目录的一种简写形式)的文件名,她就能够访问到 ``BASE_PATH`` 目录结构以上的文件。要获取权限,只是一个时间上的问题( ``../../../../../etc/passwd`` )。 |
5963天前 |
|
翻译 |
119#翻译 |
Anything that reads files without proper escaping is vulnerable to this problem. Views that
*write* files are just as vulnerable, but the consequences are doubly dire.
|
任何不做适当转义地读取文件操作,都可能导致这样的问题。允许 *写* 操作的视图同样容易发生问题,而且结果往往更加可怕。 |
5963天前 |
|
翻译 |
120#翻译 |
Another permutation of this problem lies in code that dynamically loads modules based on
the URL or other request information. A well-publicized example came from the world of Ruby
on Rails. Prior to mid-2006, Rails used URLs like ``http://example.com/person/poke/1``
directly to load modules and call methods. The result was that a carefully constructed URL
could automatically load arbitrary code, including a database reset script!
|
这个问题的另一种表现形式,出现在根据URL和其他的请求信息动态地加载模块。一个众所周知的例子来自于Ruby on Rails。在2006年上半年之前,Rails使用类似于 ``http://example.com/person/poke/1`` 这样的URL直接加载模块和调用函数。结果是,精心构造的URL,可以自动地调用任意的代码,包括数据库的清空脚本。 |
2871天前 |
Stone |
翻译 |
121#翻译 |
The Solution
''''''''''''
|
解决方案
''''''''''''
|
5963天前 |
|
翻译 |
122#翻译 |
If your code ever needs to read or write files based on user input, you need to sanitize
the requested path very carefully to ensure that an attacker isnt able to escape from the
base directory youre restricting access to.
|
如果你的代码需要根据用户的输入来读写文件,你就需要确保,攻击者不能访问你所禁止访问的目录。 |
5963天前 |
|
翻译 |
123#翻译 |
Note
|
备注 |
5963天前 |
|
翻译 |
124#翻译 |
Needless to say, you should *never* write code that can read from any area of the disk!
|
不用多说,你 *永远* 不要在可以让用户读取的文件位置上编写代码! |
2871天前 |
Will |
翻译 |
125#翻译 |
A good example of how to do this escaping lies in Djangos built-in static content-serving
view (in ``django.views.static`` ). Heres the relevant code:
|
Django内置的静态内容视图是做转义的一个好的示例(在 ``django.views.static`` 中)。下面是相关的代码: |
5963天前 |
|
翻译 |
128#翻译 |
Django doesnt read files (unless you use the ``static.serve`` function, but thats protected
with the code just shown), so this vulnerability doesnt affect the core code much.
|
Django不读取文件(除非你使用 ``static.serve`` 函数,但也受到了上面这段代码的保护),因此这种危险对于核心代码的影响就要小得多。 |
2871天前 |
Morrie |
翻译 |
129#翻译 |
In addition, the use of the URLconf abstraction means that Django will *never* load code
youve not explicitly told it to load. Theres no way to create a URL that causes Django to
load something not mentioned in a URLconf.
|
更进一步,URLconf抽象层的使用,意味着不经过你明确的指定,Django *决不会* 装载代码。通过创建一个URL来让Django装载没有在URLconf中出现的东西,是不可能发生的。 |
5963天前 |
|
翻译 |
130#翻译 |
Exposed Error Messages
``````````````````````
|
暴露错误消息
``````````````````````
|
2871天前 |
Chiana |
翻译 |
131#翻译 |
During development, being able to see tracebacks and errors live in your browser is
extremely useful. Django has pretty and informative debug messages specifically to make
debugging easier.
|
在开发过程中,通过浏览器检查错误和跟踪异常是非常有用的。Django提供了漂亮且详细的debug信息,使得调试过程更加容易。 |
5963天前 |
|
翻译 |
132#翻译 |
However, if these errors get displayed once the site goes live, they can reveal aspects of
your code or configuration that could aid an attacker.
|
然而,一旦在站点上线以后,这些消息仍然被显示,它们就可能暴露你的代码或者是配置文件内容给攻击者。 |
5963天前 |
|
翻译 |
133#翻译 |
Furthermore, errors and tracebacks arent at all useful to end users. Djangos philosophy is
that site visitors should never see application-related error messages. If your code raises
an unhandled exception, a site visitor should not see the full traceback or *any* hint of
code snippets or Python (programmer-oriented) error messages. Instead, the visitor should
see a friendly This page is unavailable message.
|
还有,错误和调试消息对于最终用户而言是毫无用处的。Django的理念是,站点的访问者永远不应该看到与应用相关的出错消息。如果你的代码抛出了一个没有处理的异常,网站访问者不应该看到调试信息或者 *任何* 代码片段或者Python(面向开发者)出错消息。访问者应该只看到友好的无法访问的页面。 |
5963天前 |
|
翻译 |
134#翻译 |
Naturally, of course, developers need to see tracebacks to debug problems in their code. So
the framework should hide all error messages from the public, but it should display them to
the trusted site developers.
|
当然,开发者需要在debug时看到调试信息。因此,框架就要将这些出错消息显示给受信任的网站开发者,而要向公众隐藏。 |
5963天前 |
|
翻译 |
135#翻译 |
The Solution
''''''''''''
|
解决方案
''''''''''''
|
5963天前 |
|
翻译 |
136#翻译 |
Django has a simple flag that controls the display of these error messages. If the
``DEBUG`` setting is set to ``True`` , error messages will be displayed in the browser. If
not, Django will render return an HTTP 500 (Internal server error) message and render an
error template that you provide. This error template is called ``500.html`` and should live
in the root of one of your template directories.
|
Django有一个简单的标志符,来控制这些出错信息显示与否。如果 ``DEBUG`` 被设置为 ``True`` ,错误消息就会显示在浏览器中。否则,Django会返回一个 HTTP 500(内部服务器错误)的消息, 并显示你所提供的出错页面。这个错误的模板叫 ``500.html`` ,并且这个文件需要保存在你的某个模板目录的根目录中。 |
5930天前 |
|
翻译 |
137#翻译 |
Because developers still need to see errors generated on a live site, any errors handled
this way will send an email with the full traceback to any addresses given in the
``ADMINS`` setting.
|
由于开发者仍然需要在上线的站点上看到出错消息,这样的出错信息会向 ``ADMINS`` 设定选项自动发送email。 |
5963天前 |
|
翻译 |
138#翻译 |
Users deploying under Apache and mod_python should also make sure they have ``PythonDebug
Off`` in their Apache conf files; this will suppress any errors that occur before Django
has had a chance to load.
|
在Apache和mod_python下开发的人员,还要保证在Apache的配置文件中关闭 ``PythonDebug Off`` 选项,这个会在Django被加载以前去除出错消息。 |
5963天前 |
|
翻译 |
139#翻译 |
A Final Word on Security
````````````````````````
|
安全领域的总结
````````````````````````
|
5963天前 |
|
翻译 |
140#翻译 |
We hope all this talk of security problems isnt too intimidating. Its true that the Web can
be a wild and wooly world, but with a little bit of foresight, you can have a secure Web
site.
|
我们希望关于安全问题的讨论,不会太让你感到恐慌。Web是一个处处布满陷阱的世界,但是只要有一些远见,你就能拥有安全的站点。 |
5963天前 |
|
翻译 |
141#翻译 |
Keep in mind that Web security is a constantly changing field; if youre reading the
dead-tree version of this book, be sure to check more up to date security resources for any
new vulnerabilities that have been discovered. In fact, its always a good idea to spend
some time each week or month researching and keeping current on the state of Web
application security. Its a small investment to make, but the protection youll get for your
site and your users is priceless.
|
永远记住,Web安全是一个不断发展的领域。如果你正在阅读这本书的停止维护的那些版本,请阅读最新版本的这个部分来检查最新发现的漏洞。事实上,每周或者每月花点时间挖掘web应用安全,并且跟上最新的动态是一个很好的主意。小小的投入,却能收获保护你的站点和用户的无价的回报。 |
5963天前 |
|
翻译 |
142#翻译 |
Whats Next
``````````
|
接下来?
```````` |
5930天前 |
|
翻译 |
143#翻译 |
In the next chapter, well finally cover the subtleties of deploying Django: how to launch a
production site and how to set it up for scalability.
|
下一章中,我们会谈论到一些使用Django的细节问题:如何部署一个站点,并具有良好的伸缩性。 |
5963天前 |
|
翻译 |