Discuz教程网

[应用中心] Discuz! 应用中心插件审核规范

[复制链接]
authicon dly 发表于 2016-3-23 15:16:15 | 显示全部楼层 |阅读模式
一 基本信息1.1 LOGO

LOGO 的规范请参考这个通知:http://open.discuz.net/?ac=announce&id=57

常出现的问题是:

  • 禁止单色或者简单渐变背景加文字的LOGO
  • 禁止一个LOGO用于多个应用(同应用不同分支、扩展的除外)

1.2 应用截图

开发者至少需要上传一幅应用截图。如果插件拥有后台设置,提交的截图中应该包含后台部分。

对于仅使用嵌入点实现功能的插件,应该截图展示启用插件后的效果。

对于搭配模板使用的插件,应该上传使用了该插件的模板截图。

1.3 应用介绍

应用介绍不能为空,原则上也不能过于简单,如只有一句话描述。

应用介绍应当主要介绍当前插件,不允许出现大部分内容都是其它插件广告的情况。

对于验证码、验证问答等某些插件而言,开发者应当说明安装插件后,还需要在后台的何处进行何种设置才能启用插件,否则某些站长可能会因为不会使用、安装插件后无效果而产生疑问。

如果当前插件依赖其它插件、模板、扩展才能使用,必须清楚的注明。

1.4 文件打包

文件打包前,开发者应清理插件目录中的无关文件,包括 IDE 项目文件、版本管理相关文件、Windows 缩略图缓存(Thumb.db 等),以及未被使用的 PHP、HTML、图片文件等。

插件目录及所有子目录中都应该包含一个空白的 index.htm 文件。

文件命名原则上只使用小写英文字母,不建议文件名包含中文,不允许文件名中包含任何特殊字符。

1.5 提交审核

插件分支的常见用途是用来区分“免费版”、“收费版”等。同一类型版本的不同版本号(如“1.0 免费版”、“1.1 免费版”)更新时,不应该创建新的分支,而应该在同一个分支下(“免费版”)进行更新。

不允许使用不同分支来区分同一版本、不同编码的情况(如“免费版 GBK”、“免费版 UTF-8”),这种情况下应该使用语言包来解决。

提交审核时应该正确选择编码(尤其是同时支持 GBK 和 UTF-8),切勿随意勾选。

应当慎重选择支持的 Discuz! 版本。从 X2.5 起,新引入了 C::t() 数据层,且不再支持 $_G[gp_xxx]。如果代码中使用了这些特性,插件不支持 X2,不能勾选。

如果插件主要功能是调用第三方 API,在提交审核时应该提供测试账号和密码。

二 代码规范2.1 文件开头

PHP 标签应该使用 <?php,慎用 <? 和 <?=。

所有 *.inc.php 文件都必须检测 IN_DISCUZ 常量是否已经定义。如果该文件是后台模块,则应该检测 IN_ADMINCP 常量(后台模块可同时检测 IN_DISCUZ、IN_ADMINCP,或单独仅检测 IN_ADMINCP)。

请注意,所有的 *.inc.php 都可通过 plugin.php?id=xxx:yyy 方式进行访问。如果某文件是嵌入模块(如嵌入“个人设置”、“论坛管理”等),必须额外检测当前环境是否是嵌入环境(如检测 CURSCRIPT 是否为 home 保证当前确实是被 home.php 引入)。

所有 *.class.php 文件都必须检测 IN_DISCUZ 常量。

对于其它 PHP 文件,除 API 和第三方 SDK 外,必须检测 IN_DISCUZ 常量。不需检测 IN_DISCUZ 常量的情况有:没有使用 Discuz! 提供的任何类和函数;手动载入 class_core.php 并初始化 Discuz! 环境。

install.php、uninstall.php、upgrade.php 必须检测 IN_ADMINCP 常量。

2.2 文件结尾

对于纯 PHP 文件,推荐文件结尾不使用 ?> 标签。

如果文件结尾使用了 ?> 标签,在标签后不允许存在任何多余的字符,包括空格、回车在内的空白。

2.3 代码风格

所有的 PHP、JS、HTML 文件代码风格应该干净整洁、可读性好,易于审核人员阅读和检查。使用 jQuery 等第三方库的压缩版本可例外。

提交的源代码不允许自行进行加密和混淆。

三 插件规范3.1 数据表规范

开发者尽量仅使用 MyISAM 和 Memory 两种数据表,不使用事务功能。

设计数据表时,应正确设计字段类型,如:存储时间原则上使用 int 类型保存时间戳;定长字符串(如 md5 哈希值)使用 char 而非 varchar 等。

开发者应当合理设置数据表的索引,尤其是作为查询条件的字段。

3.2 安装和卸载

安装时创建数据表语句不应指定数据表编码(Discuz! 会自动将 TYPE=MyISAM 转换为 ENGINE=MyISAM DEFAULT CHARSET=xxx)。

卸载时,应当删除插件安装时建立的所有数据表和字段,完全清理插件使用过程中产生的文件(如保存的用户上传文件)。

如果开发者认为插件数据价值较大,可在卸载时向用户询问是否保留数据。如果用户保留数据,下次安装插件时,不能出现无法安装的情况,如产生数据表已存在等错误。

3.3 多编码支持

开发者应当使用语言包机制实现多编码支持。对于手动使用 diconv() 手动对中文进行转码的方式,目前不禁止,但并不提倡。

如果插件文件(包括 PHP、JS、模板)中出现了中文字符且并未进行转码,在上传插件提交审核时禁止勾选多种编码支持。

3.4 效率优化

开发者在设计插件时,在保证功能完整和安全性的前提下,应多考虑代码的运行效率。

最常见的低效率代码是在循环中执行 SQL 语句,如下面的代码:

  1. foreach($data as $id) {    C::t('#xxx#yyy')->delete_by_id($id);}
复制代码

在大多数场景下,循环内的 SELECT 和 DELETE 语句均可通过使用 WHERE IN 语句进行优化,使原本的执行多次查询优化为一次。

在使用全局嵌入点时必须考虑效率问题:决不允许在循环中执行 SQL 查询;查询条件对应的字段原则上必须建立索引;尽量使用缓存。

某些插件需要在嵌入点访问远程 URL,原则上不允许进行这种行为,因为如果访问 URL 耗时较长,会直接拖慢整个页面的加载速度。这种情况应该将远程访问的行为单独放在一个 PHP 脚本中进行,并在嵌入点中使用 script 标签访问,将原本的操作优化为异步进行。

开发者应该充分利用缓存功能,并尽可能降低数据库的查询次数,达到效率优化的目的。

3.5 内置函数

开发者应当使用以下 Discuz! 内置函数来取代 PHP 原生函数,提高代码的兼容性:

  • 使用dfsockopen() 访问远程 URL,而非使用 file_get_contents() 或手动创建 CURL 对象
  • 使用 updatemembercount() 更新用户的积分,而非手动执行 SQL 语句更新 pre_common_member_count 表
  • 使用 dhtmlspecialchars() 过滤 HTML 字符,防止在 PHP 5.4.0 或更高版本的服务器中出现问题
  • 使用 daddslashes() 过滤入库的字符串,正确处理数组变量
  • 使用 diconv() 转换编码
  • 使用 cutstr() 而非 substr() 切割字符串,避免中文字符被错误切割
四 安全规范4.1 include/require

如果使用 include/include_once/require/require_once 动态的引入文件,必须保证路径的合法性,例如下面的代码:

  1. $mod = $_GET['mod'];require_once DISCUZ_ROOT.'./source/plugin/xxx/module/'.$mod.'.php';
复制代码

变量 $mod 未经过滤就被直接使用,存在重大的安全隐患。

开发者必须添加相应的过滤代码(如 in_array($mod, array ('index', 'del'))),保证类似情况下,$mod 是合法的。

4.2 SQL 注入

避免 SQL 注入漏洞的原则是所有数据在入库前都必须进行过滤,如数字型 ID 执行 intval(),字符串数据执行 daddslashes()。

为避免代码逻辑复杂而导致部分地方遗漏过滤,建议使用数据层功能,将对某一数据表的操作都封装为类方法,统一进行过滤。

同时,尽量不要使用类似下面手动生成 SQL 执行的代码:

  1. DB::fetch_all("SELECT * FROM ".DB::table('mytable')." WHERE id='$id'");
复制代码

而是使用替换占位符:

  1. DB::fetch_all("SELECT * FROM %t WHERE id=%d", array('mytable', $id));
复制代码

同时还需要注意,如果查询条件是 LIKE 语句,还应该额外过滤 % 和 _ 字符。

二次入库导致的 SQL 注入问题常被人忽视,如下列代码:

  1. foreach(DB::fetch_all("SELECT name FROM ".DB::table('mytable1')) as $result) {    DB::query("UPDATE ".DB::table('mytable2')." SET xxx=xxx+1 WHERE name='".$result['name']."'");}
复制代码

此处由于 $result['name'] 是从数据库中查询得到,未经过滤就再次代入到 SQL 语句中,依旧存在 SQL 注入漏洞,而且较为隐蔽,开发者应当正确处理这种情况。

4.3 CSRF

无论前台或后台功能,只要涉及数据变更操作(如插入、修改和删除),都必须检测请求来源,避免 CSRF 跨站请求伪造攻击。

如下列代码存在安全隐患:

  1. if(empty($_GET['delsubmit'])) {    include template('xxx');} else {    DB::delete('mytable', array('id' => $_GET['id']));}
复制代码

请求来源的检测可通过调用 submitcheck() 或手动检测 FORMHASH,上述代码 if(empty($_GET['delsubmit'])) { 可改造为:

  1. if(!submitcheck('delsubmit')) {
复制代码

  1. if(FORMHASH != $_GET['formhash']) {
复制代码


4.4 XSS

插件将数据库中的字符串类型数据显示在页面之前,如果没有经过 dhtmlspecialchars() 过滤,则存在 XSS 跨站脚本攻击漏洞。

开发者应当意识到 XSS 漏洞的危害,在数据直接输出前进行过滤。应注意,数据输出除了直接显示外,还包括 <input type="text" value="$data" /> 和<textarea>$data</textarea> 等情况。

五 其它说明

严禁发布包含色情、赌博及其它违反国家法律内容的插件,严禁在插件中包含病毒、木马、后门及其它恶意代码,如有发现,严肃处理。

不允许发布单机 Flash 游戏、网页游戏类、在线后台服务器文件管理类的插件;发布支付类插件必须通过企业认证;不允许发布功能过于简单、界面过于粗糙的插件;不允许发布应用中心已有多款类似且无明显创新的插件。

开发者应当明确为用户提供服务的时间(如 7x24、5x8 等)、时效(如 2 小时内)、方式(如 QQ、论坛等)、期限(商业用户)等。

更多要求请阅读:http://open.discuz.net/?ac=document&page=audit

审核人员不是插件测试人员,请开发者在提交上传插件前自行完成插件的测试。插件在审核时,会随机分配给不同的审核人员。不同的审核人员有不同的习惯(如有的发现一个问题就打回,有的打回时多寻找问题),请开发者理解。


原文:http://open.discuz.net/?ac=document&page=audit_plugin




上一篇:零售企业自建商城网站已是大势所趋
下一篇:柒瑞赛事竞猜 年度版6plush 价值489元(2016.03.23更新)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1314学习网 ( 浙ICP备10214163号 )

GMT+8, 2019-9-22 07:57

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表