Chinaunix首页 | 论坛 | 博客
  • 博客访问: 17911402
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911403
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911404
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911405
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911406
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911397
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911408
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911409
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911410
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911411
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911412
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911413
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911414
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911415
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911416
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911417
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911418
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911419
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911420
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911421
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911412
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911423
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911424
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911425
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911426
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911427
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911428
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911429
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911430
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911431
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911432
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911433
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911434
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911435
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911436
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911427
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911438
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911439
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911440
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911441
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911442
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911444
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911445
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911446
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911447
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911448
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911449
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911450
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911451
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911442
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911453
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。 确保PHP应用程序的安全[1]-剑心通明-ChinaUnix博客

  • 博客访问: 17911454
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-27 21:58:35

大家都知道安全性是重要的,但是行业中的趋势是直到最后一刻才添加安全性。既然不可能完全保护 Web 应用程序,那么为什么要费这个劲儿呢,不是吗?不对。只需采用一些简单的步骤就能够大大提高 PHP Web 应用程序的安全性。

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26210) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26209) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26208) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26207) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26206) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26205) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26204) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26203) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26202) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26201) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26200) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26199) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26198) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26197) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26196) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26195) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26194) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26193) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26192) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26191) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26190) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26189) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26188) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26187) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26186) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26185) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26184) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26183) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26182) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26181) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26180) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26179) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26178) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26177) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26176) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26175) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26174) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26173) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26172) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26171) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26170) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26169) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26168) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26167) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26166) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26165) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26164) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26163) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26162) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26161) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26160) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~

开始之前

在本教程中,您将学习如何在自己的 PHP Web 应用程序中添加安全性。本教程假设您至少有一年编写 PHP Web 应用程序的经验,所以这里不涉及 PHP 语言的基本知识(约定或语法)。目标是使您了解应该如何保护自己构建的 Web 应用程序。

本教程讲解如何防御最常见的安全威胁:SQL 注入、操纵 GETPOST 变量、缓冲区溢出攻击、跨站点脚本攻击、浏览器内的数据操纵和远程表单提交。





 


本教程是为至少有一年编程经验的 PHP 开发人员编写的。您应该了解 PHP 的语法和约定;这里不解释这些内容。有使用其他语言(比如 Ruby、Python 和 Perl)的经验的开发人员也能够从本教程中受益,因为这里讨论的许多规则也适用于其他语言和环境。




 



需 要一个正在运行 PHP V4 或 V5 和 MySQL 的环境。可以使用 Linux®、OS X 或 Microsoft® Windows®。如果是在 Windows 上,那么下载 WAMPServer 二进制文件,在机器上安装 Apache、MySQL 和 PHP。


安全性快速简介

Web 应用程序最重要的部分是什么?根据回答问题的人不同,对这个问题的答案可能是五花八门。业务人员需要可靠性和可伸缩性。IT 支持团队需要健壮的可维护的代码。最终用户需要漂亮的用户界面和执行任务时的高性能。但是,如果回答 “安全性”,那么每个人都会同意这对 Web 应用程序很重要。

但是,大多数讨论到此就打住了。尽管安全性在项目的检查表中,但是往往到了项目交付之前才开始考虑解决安全性问题。采用这种方式的 Web 应用程序项目的数量多得惊人。开发人员工作几个月,只在最后才添加安全特性,从而让 Web 应用程序能够向公众开放。

结果往往是一片混乱,甚至需要返工,因为代码已经经过检验、单元测试并集成为更大的框架,之后才在其中添加安全特性。添加安全性之后,主要组件可能会停止工作。安全性的集成使得原本顺畅(但不安全)的过程增加额外负担或步骤。

本教程提供一种将安全性集成到 PHP Web 应用程序中的好方法。它讨论几个一般性安全主题,然后深入讨论主要的安全漏洞以及如何堵住它们。在学完本教程之后,您会对安全性有更好的理解。

主题包括:

  • SQL 注入攻击
  • 操纵 GET 字符串
  • 缓冲区溢出攻击
  • 跨站点脚本攻击(XSS)
  • 浏览器内的数据操纵
  • 远程表单提交

Web 安全性 101

在讨论 实现安全性的细节之前,最好从比较高的角度讨论 Web 应用程序安全性。本节介绍安全哲学的一些基本信条,无论正在创建何种 Web 应用程序,都应该牢记这些信条。这些思想的一部分来自 Chris Shiflett(他关于 PHP 安全性的书是无价的宝库),一些来自 Simson Garfinkel(参见 参考资料),还有一些来自多年积累的知识。

关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据。外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据。在采取措施确保安全之前,来自任何其他来源(比如 GET 变量、表单 POST、数据库、配置文件、会话变量或 cookie)的任何数据都是不可信任的。

例如,下面的数据元素可以被认为是安全的,因为它们是在 PHP 中设置的。



                    
$myUsername = 'tmyer';
$arrayUsers = array('tmyer', 'tom', 'tommy');
define("GREETING", 'hello there' . $myUsername);

但是,下面的数据元素都是有瑕疵的。



                    
$myUsername = $_POST['username']; //tainted!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //tainted!
define("GREETING", 'hello there' . $myUsername); //tainted!

为什么第一个变量 $myUsername 是有瑕疵的?因为它直接来自表单 POST。 用户可以在这个输入域中输入任何字符串,包括用来清除文件或运行以前上传的文件的恶意命令。您可能会问,“难道不能使用只接受字母 A-Z 的客户端(JavaScript)表单检验脚本来避免这种危险吗?”是的,这总是一个有好处的步骤,但是正如在后面会看到的,任何人都可以将任何表单下载 到自己的机器上,修改它,然后重新提交他们需要的任何内容。

解决方案很简单:必须对 $_POST['username'] 运行清理代码。如果不这么做,那么在使用 $myUsername 的任何其他时候(比如在数组或常量中),就可能污染这些对象。

对用户输入进行清理的一个简单方法是,使用正则表达式来处理它。在这个示例中,只希望接受字母。将字符串限制为特定数量的字符,或者要求所有字母都是小写的,这可能也是个好主意。



                    
$myUsername = cleanInput($_POST['username']); //clean!
$arrayUsers = array($myUsername, 'tom', 'tommy'); //clean!
define("GREETING", 'hello there' . $myUsername); //clean!



function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace("/[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}






已经知道了不能信任用户输入,还应该知道不应该信任机器上配置 PHP 的方式。例如,要确保禁用 register_globals。如果启用了 register_globals,就可能做一些粗心的事情,比如使用 $variable 替换同名的 GETPOST 字符串。通过禁用这个设置,PHP 强迫您在正确的名称空间中引用正确的变量。要使用来自表单 POST 的变量,应该引用 $_POST['variable']。这样就不会将这个特定变量误会成 cookie、会话或 GET 变量。

要 检查的第二个设置是错误报告级别。在开发期间,希望获得尽可能多的错误报告,但是在交付项目时,希望将错误记录到日志文件中,而不是显示在屏幕上。为什么 呢?因为恶意的黑客会使用错误报告信息(比如 SQL 错误)来猜测应用程序正在做什么。这种侦察可以帮助黑客突破应用程序。为了堵住这个漏洞,需要编辑 php.ini 文件,为 error_log 条目提供合适的目的地,并将 display_errors 设置为 Off。




一些开发人员使用奇怪的语法,或者将语句组织得很紧凑,形成简短但是含义模糊的代码。这种方式可能效率高,但是如果您不理解代码正在做什么,那么就无法决定如何保护它。

例如,您喜欢下面两段代码中的哪一段?



                    
//obfuscated code
$input = (isset($_POST['username']) ? $_POST['username']:'');

//unobfuscated code
$input = '';

if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = '';
}

在第二个比较清晰的代码段中,很容易看出 $input 是有瑕疵的,需要进行清理,然后才能安全地处理。




本教程将用示例来说明如何保护在线表单,同时在处理表单的 PHP 代码中采用必要的措施。同样,即使使用 PHP regex 来确保 GET 变量完全是数字的,仍然可以采取措施确保 SQL 查询使用转义的用户输入。

纵深防御不只是一种好思想,它可以确保您不会陷入严重的麻烦。

既然已经讨论了基本规则,现在就来研究第一种威胁:SQL 注入攻击。

阅读(26159) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~