织梦防止直接访问data目录

问题背景

织梦 DedeCMS 的 /data/ 目录是站点的"心脏",存放数据库配置 common.inc.php、缓存、上传文件配置、备份 SQL、关键词库、模板缓存等敏感文件。一旦该目录被直接 HTTP 访问,攻击者可以下载 common.inc.php 拿到数据库账号密码,下载备份 SQL 拿到全站数据,等同站点沦陷。因此禁止 data 目录直接访问是织梦安全加固的头号任务。

原因分析

data 目录为什么必须存在

织梦核心代码 /include/common.inc.php 中通过 DEDEDATA 常量定位 data 目录,运行时大量读写该目录。如果直接删除 data,站点立即报错。

默认配置的漏洞

nginx 默认配置不会主动屏蔽 data 目录;Apache 在没配置 .htaccess 时也不会拦截。所以开箱即用的织梦站点,/data/common.inc.php 是可以直接被 HTTP 请求的(虽然 PHP 会被解析而不返回源码,但 /data/backupdata/*.sql 这种非 PHP 文件会被直接下载)。

解决步骤

方案一:nginx 屏蔽(推荐)

location ~* ^/data/ {
    deny all;
    return 403;
}
# 同时禁止 .inc、.sql、.bak 等敏感后缀
location ~* \.(inc|sql|bak|log|cache)$ {
    deny all;
}

方案二:Apache .htaccess

/data/ 目录下新建 .htaccess

Order allow,deny
Deny from all
# Apache 2.4+
# Require all denied

方案三:data 目录外移(最安全)

把 data 目录移到 web root 之外,从根上消除 HTTP 访问可能。步骤:

  1. /var/www/dedecms/data 移动到 /var/www/data_dedecms
  2. 修改 /include/common.inc.php,定义 DEDEDATA 指向新路径
  3. 修改织梦后台"系统设置 → 站点根目录"等参数
  4. 确保 PHP 进程对目录有读写权限
// /include/common.inc.php
define('DEDEDATA', '/var/www/data_dedecms/');

方案四:data 目录改名

把 data 改为不易猜到的名字,如 _cfg_8a3f

// 修改 common.inc.php
define('DEDEDATA', DEDEROOT.'/_cfg_8a3f/');
// 同时修改 /dede/ 后台多处硬编码 data 路径

改名只能延缓攻击,建议与方案一/三组合使用。

方案五:Nginx + PHP 双保险

即使 nginx 漏配,PHP 也不应让 data 目录被解析:

location ~ ^/data/.*\.php$ {
    deny all;
}

配置示例汇总

推荐组合:方案一(nginx 屏蔽)打底 + 方案三(data 外移)治本。外移后即使 nginx 规则被误删,攻击者也无法通过 HTTP 访问到 data 目录。

注意事项

  • data 目录中有 cacheuploadtmp 等子目录需要 PHP 写权限,外移后记得 chown 修正属主。
  • 修改 DEDEDATA 后织梦后台部分功能可能报"目录不可写",需要检查并设置 755 权限。
  • 不要把 data 改名为 configbackup 等常见词,反而更易被扫描器命中。
  • 站点使用 CDN 时,CDN 缓存可能短期保留旧的 200 响应,需主动刷新缓存。
  • 定期扫描 /data/*.sql/data/*.zip 等备份文件,及时清理。

实施建议

建议把 data 目录加固作为织梦上线 checklist 的强制项,与"删除 install 目录""关闭 register_globals""修改 dede 后台目录"一起执行。每月用在线扫描工具(如 360 网站安全检测、阿里云先知)对站点做一次渗透测试,确认 data 目录及敏感文件均返回 403。长期看,升级到支持 data 外移的织梦版本(5.8+)或迁移到更现代的 CMS 是治本之策,但在此之前,多层防护足以把风险降到可控水平。