• --:)欢迎访问锋网源码(:--
  • 首页
  • RSS订阅
  • 常用软件
  • 网页模板
  • 网站运作
  • 锋网学院
  • 繁體中文

  • 学院首页
  • 新闻资讯
  • 网站运营
  • 网站开发
  • 美工设计
  • 数据库类
  • 服务器类
  • 网络应用
  • 操作系统
  • 软件教学
编程开发   认证考试   网络安全   文章搜索: 高级搜索
会员登录/控制面版 您的位置: 学院首页 >> 编程开发 >> Perl教程 >> 文章内容
 

精彩推荐

 
 

本类推荐文章

 
 

本类阅读排行

  • LINUX
  • 用Perl饼来替换文件中的字符..
  • PERL下的正则表达式
  • Perl小技巧:文件操作
  • 构建一个Perl/CGI投票系统
  • Perl的经典用法:读入多个记录..
  • 如何使用strict和warnings
  • Perl简介
  • Perl的经典用法:用正则表达式..
  • 使用Perl连接Mysql数据库
  • 用Perl来分析并生成中文Exce..
  • 《极限编程》前言及第一章
  • PerlCookbook2介绍
  • Perl简单模块指南
  • 使用Maypole进行快速Web应用..
  • 受限制环境安装Perl模块方法
  • proftpdlog文件实时分析,动..
  • Perl的经典用法:读入段落
  • ADODB与PearDB的兼容部分
 
 

构建一个Perl/CGI投票系统

  • 日期:2007-10-20     人气:     出处:     作者:
  • 字体大小:
  • 小
  • 中
  • 大

许多Web部署的应用程序都是在精心设计的数据库驱动的服务器端开发框架中编写的,例如PHP和Java™servlet,但是对于一些简单的程序(例如,整个数据库要能够存放在Web服务器的RAM中)来说,使用加锁的DMB文件和PerlMLDBM模块可以很容易地实现数据持久性。本文将给出一个基于Web的投票系统的真实的例子,重点介绍如何利用最小的外部模块、如何舍弃基于客户机的cookie以及如何利用CGI属性的优点。

软件正日益变得更加复杂,这并不是什么秘密;我们也看到一些额外的层次被添加到系统中,以保持软件组件的模块化。最重要的结果是,这些系统现在更易于维护,而且可扩展性也更好;但是有时这些技术有过多的重复,会导致软件的过度设计。在另外一些情况下,开发开发人员宁愿选择一些过度复杂但却非常有名的技术,也不愿意集成一些简单但却不太熟悉的技术。

不管怎样,如果所有人都有一把锤子,那么每个问题看起来都不过像一颗钉子而已。

我最近被请求为一所大学的学生组织设计一个小程序,以统计选举票数。这是一个非常简单的项目,每周处理的学生请求不会超过500个;之后该程序会立即统计并发布结果。

由于这个项目对服务级别的要求很低,因此使用一个外部数据库来处理查询并没有什么好处。相反,使用脚本可以直接快速读写数据结构。不过,我仍然希望能够将一些经过良好设计的功能封装在一起,而不是采用一些像意大利面那样,将杂乱的代码拼装在一起。我希望可以采用一个经过仔细考虑的自成体系的设计,该设计将提供一些简化的部署。

CGI的考虑:简单性与复杂性
Perl看来是这个项目的首选语言——在很多平台上似乎都受到支持,此外,在Perl的知识库CPAN中,还有很多方便的库可以使用。

对于底层架构来说,CGI(CommonGatewayInterface)是第一种广泛用来扩展Web服务器从而提供交互内容的方法。开发人员通常会鼓吹一些新的标准,例如JSP、.NET、mod_perl、PHP和ISAPI,这些技术也的确可以弥补CGI的一些不足。但是在这个项目中,我们只需要对几百个用户计算投票数,这样一个CGI脚本很难构成一个大型的应用程序,因为所有的投票信息都可以放到Web服务器的系统RAM中。在用户每次提交一个读写数据的请求时,这可以将要查询的整个表装入内存中。

还有,通过将逻辑数据分隔成3个不同的物理文件,可以实现填写选票、确认选票和统计结果的逻辑顺序;这样做可以最大限度地减少打开已加锁的文件。

如果一个事务在很偶然的情况下因为加锁的文件而失败了,那么这并不会产生实际的问题。不管一个事务是由于网络问题还是加锁文件而失败的,结果都是相同的:用户只需再等待一会儿即可,选票随后很有可能对其中的一次尝试进行统计。我们应该记住这种行为,然而,对于不同的应用程序来说,情况并非总是如此,因此可能无法处理并发事务。

对于这个项目来说,CGI提供了以下几个优点:

SASL身份验证
很多服务提供商都只允许转发那些来自使用SASL身份验证的客户机的邮件。SASL(SimpleAuthenticationandSecurityLayer)是用来对基于连接的协议添加身份验证支持的一种方法,其中有一种协议包含了一个标识用户身份的命令,并让该用户对服务器进行身份验证,从而对保护后续的协议交互进行协商。如果双方经过协商同意使用,那么就会在协议和连接之间插入一个安全层。

在使用SASL认证时,您有两个选择:可以将这个脚本指向一台可以转发使用正确证书的电子邮件的机器,或者使用PerlNet::SMTP_authandAuthen::SASL模块重新编写这个脚本,与外部SMTP服务器直接进行联系。(第二种方法的速度较慢。)

细节:不太安全的投票
调用$castBallot->dumpHTMLentrys()方法会回显一个详细的信息,指出谁投票给了谁。实际上,我要注释掉这个调用,在选举结束之后使用Linuxat批处理命令来关闭Web服务器。

当服务器关闭之后,您可以注释掉这一部分,并重新启动Web服务器,将其临时设置为只监听localhost的地址。然后,通过单击一个之前提交的链接,可以将完整的结果回显给所有用户,并且可以通过向一个专用的免费电子邮件帐号发送一个副本,来收集完整的结果。

注意,在这个例子下,每个选票都不会被统计两次。在那些确定需要保密的情况中,可以使用一个简短的JavaScript函数来隐藏结果。诚然,有些人可能希望完全采用匿名投票,但是由于俱乐部的选举通常都是通过举手表决的,因此这很难实现安全的投票。

在考虑这种工作流程模式时,我意识到使用基于GET的验证链接以及使用非加密验证链接的必要性,这样可以进行一些实验,读取这些链接,并基于指定的电子邮件地址和一些已知的验证链接来构建一些错误的确认投票。为了防止这种事情的发生,同时为了仍然能够通过非加密链接进行简单的调试,我决定在验证步骤中添加一、两项内容:为每个预选票添加一个惟一的标识符。

这个标识符是基于操作系统中正在执行的脚本的集成标识符(PID)的。为了让预测验证预选票的URL更加困难,我们可以再使用一个随机数。我之所以关心这个问题,是因为会有一些恶意的用户可能会对非常直观的URL模式进行破解,从而试图构建一些虚假的验证选票。这是代码的一部分,它不会直接转换为一个mod_perl版本,因为它要依赖于正在运行的Perl的PID,以及另外一个随机数。如果这个表单是从一个重用的mod_perl实例中生成的,那么在两次调用之间,PID可能并不需要改变。

然后,我又意识到能使这个链接更具迷惑性的方法是使用一个MD5生成的哈希值,从而有效地隐藏所有投票者的信息。这具有双向受益的优点:既可以使它很难被伪造,同时还维护了基于mod_perl的脚本的可移植能力。缺点是代码有些难以调试,因为需要对客户机与服务器之间交换的信息进行监视。

细节:文件布局
安装过程要求Web服务器上有三种类型的目录:

  • 一个可写的目录,用来保存用户提交的选票。
  • 一个位置,CGI需要在这里运行。
  • 一个位置,用来保存静态数据(例如CSS,logo图像,以及包含更详细指令的文件)。
  • 还要注意的是,这种权限可以进行修改,这样,Web服务器就可以向这个目录中写入DBM文件的内容了。

    清单2显示了在Web服务器上创建典型目录的过程。

    清单2.在Web服务器上设置目录
    $iduid=500(allan)gid=500(allan)groups=10(wheel),48(apache),500(allan)$sudomkdir/var/www/db/var/www/javascript//var/www/css/$sudochmod2775/var/www/db$sudochmod2755/var/www/javascript//var/www/css/$sudochownapache.apache/var/www/db/

    严格来说,只有cgi-bin(/var/www/cgi-bin)和DBM(/var/www/db)目录是绝对必需的,因为它们分别保存了脚本的可执行文件和投票数据。清单1中给出的文件布局是专用于Linux的,Web服务器进程的用户和组名可能有所不同,但实质上都需要在文件系统的适当地方放上几个Web服务器可以访问的组件。在将支持文件复制到各自的目录中之后,要确保对Web服务器的配置文件(例如httpd.conf)中的别名进行了正确更新。

    在创建清单2中所给出的目录之后,将ZIP文件中展开的内容复制到您的系统的类似目录中。其中最重要的是,ballot、DraftBallot.pm、BallotBox.pm和CastBallot.pm文件都需要位于cgi-bin目录中。我们只需要使用3个非标准的Perl模块;安装过程如清单3所示(更详细的信息,请参阅模块的README文件)。

    清单3.安装Perl模块
    $sudoperl-MCPAN-e'installMLDBM'$sudoperl-MCPAN-e'installMLDBM::Sync'$sudoperl-MCPAN-e'installMIME::Lite'

    细节:静态DNS与动态DNS
    虽然我可以用一个静态IP地址在拥有已分配的域的站点中建立这种服务,但是我觉得动态DNS应该可以提供一些安全上的好处。通常,如果一个服务器没有静态IP地址,那么来自Web上的访问流量就不可能太大,动态DNS让我们可以在另外一个顶级域名之上临时建立一个可解析的机器名。这样我们就可以在Internet上快速出现,并快速消失,将遭受黑客攻击的风险降至最低。最好的方法是,这种服务是免费的。

    还需要指出的是,将服务器配置为监听一个非标准的大一些的端口(例如8000)是很明智的,因为很多ISP都阻塞了端口80上的连接请求。客户机(投票者)通常可以从一个知名的静态地址(例如学校提供的主页)上的链接重定向到投票服务器上。在投票完成之后,提供Web服务的服务器就可以从Web上完全消失了,无需关闭或重新配置这台服务器。其中并没有任何缺点可以影响到所引用的页面(这台服务器是由其他人进行管理的)。在一些对政策敏感的环境中,这种考虑尤其重要。(有关使用动态DNS的更详细内容,请参阅参考资料一节的内容。)

    细节:GET有害吗?
    浏览器可以使用GET和POST方法将数据传递到所引用的页面中,从而对状态进行维护;也可以通过传递给服务器上的消息头中包含的cookie信息对状态进行维护。为了确认一张选票是从一个真实的人(至少是从一个有效的电子邮件帐号中)那里发出的,应该先将预选票发送到一个电子邮件地址进行确认。此外,cc:或bcc:消息也可以在以后引用。正如我前面介绍的一样,实现这种功能的最直接的方法是向投票者发送一个HTTPGET结构化的链接。当然,有些作者会宣称用来更新记录的GET方法并不好用。但是在这种情况下,任何这之后单击某一个链接的用户都只会接收一条更新消息,并且可以从这条消息了解每个候选人的目前有效选票,因此,这是无害的。

    其他可用的改进
    在使用这个脚本时,还要考虑其他一些安全问题,我们也应该考虑这些问题。任何允许外部实体来输入数据的程序都容易受到恶意的攻击,例如缓冲区溢出和嵌入式控制字符。反之,使用专用的程序来读写本地DBM文件至少具有以下优点:在没有SQL后门的地方,是不可能存在SQL插入攻击的。

    在您同意需要对到达的数据进行过滤之后,我要将变量$CGI::DISABLE_UPLOADS和$CGI::POST_MAX设置为非常严格的值。另外我建议采用如下设置:

  • 将传入的所有意料之外字符的所有变量都转换成字符串,并将其截断为合理的限制长度。
  • 脚本中保存了很多运行时数据。这样做的优点是不需要部署很多的文件,并设置它们的权限。缺点是用户可能不想编辑代码,代码变得更加不够清晰。一种折衷的方法是利用诸如DATA伪文件句柄之类的不完善系统在脚本的末尾保存数据。
  • 文件加锁是一个非常棘手的问题,很多时候都存在竞争条件。看起来我所找到的任何一种所谓的文件加锁的正确指南,之后又都进行了更新。我试图最大限度地缩短打开文件的时间,并充分利用为MLDBM模块提供的机制。
  • Perl模块并没有放到CGI之外自己的路径中,因此从理论上来说,我们只能在cgi-bin目录中执行它。建议我们不要将这些模块设置为可执行的。
  • PHP是Linux平台上广泛存在的一种工具,因此如果需要重新实现这个系统,我考虑将这个脚本移植到PHP中。然而,我不确定是否有一个与MLDBM模块等效的PHP模块。
  • 有些人认为投票表单的布局不合理,因为第一个候选人是默认值。
  • 我没有使用perldoc,我本来应该使用它的。
  • 结束语
    假如有机会构建一个这样的系统,同时试着保持它的简单性并使其自成一体,那么该系统可以使我能够研究一些非常有用的Perl模块。我发现为这样一个简单的项目定义特性和开发功能规范的过程既很有趣又是一种享受。我希望本文中在构建这种系统时的一些考虑事项可以为您实现类似的项目提供一些帮助。

    相关文章
    • QQ帮你突破网吧硬盘访问限制
    • 局域网内盗用IP的安全问题
    • 邮件安全攻略:只要糖衣不要炮弹
    • 手机病毒的分类及其防范措施
    • 如何防止黒客远程盗取QQ密码
    • 始料未及,谁在控制电脑重新启动
    • 网络常见木马的手工清除方法
    • 魔高一尺 道高一丈
    • 防火墙日志记录让蠕虫病毒无处可逃
    • 提防他人动用电脑另有妙招
    相关软件

    • 网友评论:
    • 查看所有评论
    • 我要发表评论
     

    关于本站 | 广告联系 | 版权声明 | 网站地图 | 加入收藏 | 帮助中心 |

    Copyright © 2006-2007 fwvv.net  程序支持:木翼  皖ICP备06004916号  

    感谢:点击网络 联网科技 天盈信息 中国E速网 59互联  提供服务器及带宽赞助