这是主动攻击吗?
不是。它只发送普通的 GET、HEAD 和 OPTIONS 请求,进行 TLS 握手(包括尝试 TLS 1.0 和 1.1),通过 Cloudflare 的 DNS over HTTPS 查询 DNS,并对 12 个端口做简单的 TCP 连接。不利用任何漏洞,不提交任何表单,也不修改任何内容。
我可以扫描任何网站吗?
只能扫描你拥有或已获授权测试的网站。未经许可扫描第三方基础设施在你所在地可能是违法的。
为什么一项检查显示"未检查"?
因为它无法完成 - 通常是因为该源没有任何响应。它会被诚实地报告,而不会被记为通过。
我可以导出报告吗?
可以,导出为 Markdown 或 JSON,有效期一小时:报告在这一小时内保存在服务器缓存中以便下载,之后过期。两种导出都不使用模型。使用记录只保存发现数量和等级,不保存域名。
它会检测哪些文件和端口?
文件:23 个固定路径,包括 /.git/HEAD, /.git/config, /.env, /.env.local, /.env.production, /.aws/credentials, /id_rsa, /backup.zip, /backup.sql, /dump.sql, /wp-config.php.bak, /phpinfo.php, /server-status, /actuator/env;只有当响应与该文件特有的签名相符时才会报告。若已发布 /.well-known/security.txt,则计为加分项。端口:对 21 FTP, 23 Telnet, 25 SMTP, 3306 MySQL, 5432 PostgreSQL, 6379 Redis, 27017 MongoDB, 9200 Elasticsearch, 3389 RDP, 5900 VNC, 11211 Memcached, 8080 发起普通 TCP 连接,绝不尝试登录。可从外网访问的数据库端口(MySQL、PostgreSQL、Redis、MongoDB、Elasticsearch)或 Telnet 会被评为严重。
SPF 和 DMARC 检查会标记哪些问题?
两条记录都从公共 DNS 读取,即使网站不发邮件也会检查,因为缺少它们,任何人都能发送冒充你域名的邮件。没有 SPF 记录为中危;含 +all 的 SPF 记录允许互联网上任何服务器发信,为高危。_dmarc 下没有 DMARC 记录为中危;p=none(或没有 p= 标签)只做监控,为低危;p=quarantine 或 p=reject 通过。完全不发邮件的域名可以发布 v=spf1 -all。
会检查哪些安全响应头,什么值才算通过?
检查首页响应中的六个响应头。缺失时,HSTS 和 Content-Security-Policy 为高危,X-Content-Type-Options 和 X-Frame-Options 为中危,Referrer-Policy 和 Permissions-Policy 为低危。Strict-Transport-Security 的 max-age 至少要 15552000(180 天):更短为低危,max-age=0 为中危。如果 script-src 允许 'unsafe-inline'、策略允许 'unsafe-eval',或 default-src、script-src 中有单独的 * 通配符,Content-Security-Policy 会被标为已削弱(中危)。X-Content-Type-Options 必须正好是 nosniff。X-Frame-Options 应为 DENY 或 SAMEORIGIN,如果 CSP 已设置 frame-ancestors 则不需要。Referrer-Policy 只有在 unsafe-url 或 no-referrer-when-downgrade 时才会被标记。Permissions-Policy 只要存在即可。每个缺失或偏弱的响应头都附有一条 curl -sI 命令,方便你自己核对。
它如何检查 Cookie 属性(Secure、HttpOnly、SameSite)?
它读取首页响应中的每个 Set-Cookie 响应头(最多 12 个 Cookie),逐个检查 Secure、HttpOnly 和 SameSite。缺少 Secure 或 HttpOnly 为中危;只缺 SameSite 为低危;SameSite=None 但没有 Secure 会被单独指出,因为浏览器会拒绝这种 Cookie。三项齐全即通过。常见修复是 Secure; HttpOnly; SameSite=Lax(Django 中为 SESSION_COOKIE_SECURE、SESSION_COOKIE_HTTPONLY 和 SESSION_COOKIE_SAMESITE)。扫描不会登录,所以看不到只在登录后才设置的 Cookie。可以用这条命令自己核对:curl -sI https://your-site/ | grep -i set-cookie
CORS 检查如何进行,什么情况下是严重?
它向首页发送一个带 Origin: https://scanner-probe.example 的 GET 请求,读取响应中的 Access-Control-Allow-Origin 和 Access-Control-Allow-Credentials。没有 Access-Control-Allow-Origin 响应头,或返回一个不回显测试来源的固定来源,即通过。回显测试来源并同时返回 Access-Control-Allow-Credentials: true 为严重,因为已登录用户访问的任何网站都能读取其响应。回显来源但不带凭据为中危。通配符 * 为低危,若同时允许凭据则为中危(浏览器会拒绝这种组合)。只检测首页,也不发送 OPTIONS 预检请求,所以请单独检测 API 路由:curl -sI -H "Origin: https://scanner-probe.example" https://your-site/api/ | grep -i access-control
TLS 检查测试哪些内容(证书到期、TLS 1.0 和 1.1)?
它连接 443 端口,验证证书链和主机名。无法通过验证的证书为高危,已过期的证书还会额外标为严重,剩余不足 15 天的为中危;否则会把主体、颁发者、到期日期和 SAN 名称作为通过项列出。协商出的协议必须是 TLS 1.2 或 TLS 1.3,更旧的版本为高危。随后它分别单独尝试一次 TLS 1.0 握手和一次 TLS 1.1 握手:服务器接受其中任何一个都会得到中危结果,因为两者都已被 RFC 8996 废弃。如果扫描器自身的 OpenSSL 无法提供旧版本,则不报告任何内容,而不是去猜测。nginx 的修复方法是 ssl_protocols TLSv1.2 TLSv1.3; 可以用以下命令自行查看日期:echo | openssl s_client -connect your-site:443 -servername your-site 2>/dev/null | openssl x509 -noout -dates
它会检查 HTTP 是否重定向到 HTTPS 吗?
会。它在不跟随重定向的情况下请求 http://your-site/。以 301 或 308 跳转到 https:// 地址即为通过。以 302、303 或 307 跳转到 HTTPS 为低危,因为浏览器不会记住临时重定向,每次新的访问都会先发出一个未加密的请求。通过未加密 HTTP 直接提供页面(2xx 响应)为高危。如果 80 端口完全没有响应,只作为提示信息,不算失败。nginx 的修复方法是 server { listen 80; return 301 https://$host$request_uri; },然后添加 Strict-Transport-Security。可以用以下命令自行检查:curl -I http://your-site/
它会标记哪些 HTTP 方法(TRACE、PUT、DELETE)?
它向你的首页发送一次 OPTIONS 请求,读取 Allow 响应头;没有 Allow 时读取 Access-Control-Allow-Methods。声明了 TRACE、TRACK、PUT 或 DELETE 为中危;只有 PATCH 或 CONNECT 为低危;只有标准读取方法即为通过。如果服务器两个响应头都不发送,则不报告任何内容。声明了某个方法并不能证明它真的可用,所以修改之前先确认。TRACE 可能把请求头(包括 Cookie)原样回显给调用方(Cross-Site Tracing)。nginx 默认拒绝 TRACE;Apache 需设置 TraceEnable Off。把 PUT 和 DELETE 限制在确实需要它们的 API 路由上,并放在身份验证之后。可以用以下命令自行检查:curl -X OPTIONS -i https://your-site/
它如何检测目录列表("Index of /")?
它请求 7 个路径:/, /static/, /assets/, /uploads/, /images/, /files/ 和 /backup/。某个路径以 HTTP 200 返回、且页面标题或主标题以 "Index of /" 开头时,报告为中危(CWE-548),因为目录列表会暴露没有任何链接指向的文件,例如备份、导出文件和旧版本。如果都没有,检查即为通过;如果无法访问网站,则报告为未执行。nginx 的修复方法是 autoindex off;(这本就是默认值,所以要查找显式写出的 autoindex on),Apache 是 Options -Indexes,然后把所有敏感文件移出网站根目录。可以用以下命令自行检查:curl -s https://your-site/uploads/ | head -20
它能发现混合内容和通过 HTTP 提交的表单吗?
能,针对首页。它按服务器返回的原样读取 HTML(不执行 JavaScript),列出 src 或 href 以 http:// 开头的每个 script、link、iframe 或 img 标签。只要其中有 .js 或 .css 文件,结果就是中危,因为在传输途中被替换的脚本或样式表会在你的 HTTPS 页面里运行;只有图片和框架为低危;一个都没有则通过(CWE-311)。action 以 http:// 开头的表单报告为高危(CWE-319),因为在其中输入的一切,包括密码,都以明文发送。修复方法是把这些 URL 改为 https:// 或改成相对路径,并添加 Content-Security-Policy: upgrade-insecure-requests 响应头作为兜底。自己检查:curl -s https://your-site/ | grep -Eo "(src|href|action)=.http://[^ >]*"
它在 robots.txt 和 security.txt 中检查什么?
robots.txt:它获取 /robots.txt,如果返回 HTTP 200 且是文本文件,就读取前 8000 个字符中的 Disallow 行。包含 admin, internal, private, backup, config, staging, test, api, secret, dev 等词的 Disallow 路径报告为低危(CWE-200):robots.txt 是公开的,只是请守规矩的爬虫不要访问,列出这些路径等于替它们做广告。请用登录保护它们,并用 noindex 让页面不进入搜索结果。security.txt:它请求 RFC 9116 规定的位置 /.well-known/security.txt,文件中有 Contact: 行时计为加分。没有该文件不扣分。RFC 9116 还要求 Expires: 字段,扫描不检查它,所以两者都要发布,例如 Contact: mailto:security@your-site, Expires: 2027-06-30T23:00:00Z。自己检查:curl -s https://your-site/.well-known/security.txt
CAA 检查看什么?如何添加 CAA 记录?
它通过 Cloudflare 的 DNS-over-HTTPS 查询你输入的主机名的 CAA 记录(RFC 8659)。找到记录则检查通过,证据中最多显示 5 条;一条都没有则报告 "No CAA record",严重程度为低,因为这时任何公共证书颁发机构都可以为该名称签发证书。CAA 记录列出你实际使用的 CA,例如 your-site. IN CAA 0 issue "letsencrypt.org",再加上 0 iodef "mailto:security@your-site" 用于接收报告。每个使用的 CA 加一行 issue;如果通配符证书要由另一家 CA 签发,再加一行 issuewild。自己核对:dig CAA your-site
为什么扫描 www 或子域名时提示没有 CAA、SPF 或 DMARC?
每项 DNS 检查都针对你输入的确切名称,所以 www.example.com 按 www.example.com 查询,而不是 example.com,而这三种记录的继承方式各不相同。CAA:证书颁发机构在 www.example.com 上找不到 CAA 记录时,会向上查到 example.com 并使用那里的记录(RFC 8659 第 3 节),因此子域名上的 "No CAA record" 可能是误报。DMARC:接收方会回退到组织域名的策略,该策略可以用 sp= 为子域名单独设置(RFC 9989,已取代 RFC 7489),因此 _dmarc.www.example.com 没有记录时,通常已由 _dmarc.example.com 覆盖。SPF:没有继承(RFC 7208),所以 "No SPF record" 对该名称是准确的;不发邮件的主机名可以发布 v=spf1 -all。DNS 查询失败也会显示为没有记录。请同时扫描不带 www 的主域名,或用 dig CAA example.com 和 dig TXT _dmarc.example.com 确认