<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://ranrayd.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://ranrayd.github.io/" rel="alternate" type="text/html" /><updated>2025-12-19T03:59:29+00:00</updated><id>https://ranrayd.github.io/feed.xml</id><title type="html">Ranray’s Blog</title><subtitle>一名网络安全从业者的个人博客，关联微信公众号——CyberOutShare</subtitle><entry><title type="html">使用Gitleaks对企业GitLab上万个项目进行Secret扫描</title><link href="https://ranrayd.github.io/enterprise/security/2025/12/15/gitleaks.html" rel="alternate" type="text/html" title="使用Gitleaks对企业GitLab上万个项目进行Secret扫描" /><published>2025-12-15T01:35:00+00:00</published><updated>2025-12-15T01:35:00+00:00</updated><id>https://ranrayd.github.io/enterprise/security/2025/12/15/gitleaks</id><content type="html" xml:base="https://ranrayd.github.io/enterprise/security/2025/12/15/gitleaks.html"><![CDATA[<p>本文记录“公司 GitLab 大规模密钥/敏感配置扫描”的落地实践，<br />
从安装 Gitleaks、单仓扫描，到面对上万项目时如何“先筛选、再分批、可中断可续跑”地完成审计闭环。</p>

<blockquote>
  <p>说明：文中所有 URL、Token、路径均已脱敏。请根据实际情况替换为真实环境。
所有涉及脚本，均可访问 [https://github.com/RanrayD/gitleaks]获取</p>
</blockquote>

<hr />

<h2 id="1-背景与目标">1. 背景与目标</h2>

<p>在企业 GitLab 中，密钥泄露常见于以下场景：</p>

<ul>
  <li><strong>硬编码的凭据 (Hardcoded Credentials)</strong>
    <ul>
      <li>云服务商 AK/SK (AWS, Aliyun, Tencent Cloud, Azure, GCP)</li>
      <li>数据库连接字符串 (JDBC URL, ODBC DSN) 中包含的明文密码</li>
      <li>内部服务调用的 API Token / Secret / Auth Header</li>
      <li>测试代码中遗留的“临时”账号密码或 Mock 数据</li>
    </ul>
  </li>
  <li><strong>配置文件误提交 (Configuration Files)</strong>
    <ul>
      <li><code class="language-plaintext highlighter-rouge">.env</code>, <code class="language-plaintext highlighter-rouge">.env.production</code> 等环境变量文件</li>
      <li><code class="language-plaintext highlighter-rouge">application.yml</code>, <code class="language-plaintext highlighter-rouge">config.json</code>, <code class="language-plaintext highlighter-rouge">settings.py</code> 等包含敏感信息的配置文件</li>
      <li>容器编排文件 (Kubernetes Secret manifests, Docker Compose) 中明文写入的密钥</li>
      <li>Maven <code class="language-plaintext highlighter-rouge">settings.xml</code>, npm <code class="language-plaintext highlighter-rouge">.npmrc</code>, pip <code class="language-plaintext highlighter-rouge">pip.conf</code> 中包含的私有仓库认证信息</li>
    </ul>
  </li>
  <li><strong>加密相关文件 (Encryption &amp; Certificates)</strong>
    <ul>
      <li>私钥文件 (RSA, DSA, EC Private Keys, <code class="language-plaintext highlighter-rouge">.pem</code>, <code class="language-plaintext highlighter-rouge">.key</code>)</li>
      <li>证书文件 (Keystore <code class="language-plaintext highlighter-rouge">.jks</code>, <code class="language-plaintext highlighter-rouge">.p12</code>, <code class="language-plaintext highlighter-rouge">.pfx</code>) 及其密码</li>
      <li>对称加密的密钥 (AES Key) 或盐值 (Salt)</li>
    </ul>
  </li>
  <li><strong>第三方服务集成 (Third-party SaaS)</strong>
    <ul>
      <li>Slack Webhook URL, Discord Webhook</li>
      <li>Stripe / PayPal 支付密钥</li>
      <li>OpenAI API Key, DingTalk/WeChat Robot Token</li>
    </ul>
  </li>
  <li><strong>历史记录与日志 (Git History &amp; Logs)</strong>
    <ul>
      <li>密钥曾经提交过，即使后来在最新 commit 中删除，仍存在于 Git 历史 (<code class="language-plaintext highlighter-rouge">.git</code> 目录) 中</li>
      <li>调试日志 (Debug Log), 崩溃转储 (Dump files) 中包含的敏感内存数据</li>
    </ul>
  </li>
</ul>

<p>本次审计目标：</p>

<ul>
  <li>使用 <strong>Gitleaks</strong> 对 GitLab 项目进行 Secret 扫描</li>
  <li>支持 <strong>单仓扫描</strong> 与 <strong>大规模批量扫描</strong></li>
  <li>扫描前先按“最近提交时间”筛选出近期活跃项目（例如 <code class="language-plaintext highlighter-rouge">2025-07-01</code> 之后有提交）</li>
  <li>自动化分批运行，<strong>可随时中断</strong>，下次从进度继续，不从头再来</li>
</ul>

<hr />

<h2 id="2-开始前的先决条件非常重要">2. 开始前的先决条件（非常重要）</h2>

<p>在动手之前，至少确认以下条件：</p>

<ul>
  <li><strong>项目可视权限</strong>：你的账号能看到目标群组/项目（建议使用具备全局可视或审计权限的账号）</li>
  <li><strong>合法的访问 Token</strong>：用于调用 GitLab API / 克隆仓库
    <ul>
      <li>建议使用最小权限原则：如果仅做读取，优先使用只读 Token（如 <code class="language-plaintext highlighter-rouge">read_api</code> / <code class="language-plaintext highlighter-rouge">read_repository</code>，以实际 GitLab 权限模型为准）</li>
    </ul>
  </li>
  <li><strong>网络可达性</strong>：能从扫描机器访问 GitLab Web（<code class="language-plaintext highlighter-rouge">https://gitlab.example.com</code>）与 Git 端口（HTTP/HTTPS）</li>
  <li><strong>合规/授权</strong>：确保已获得公司内部合规授权（避免“越权扫描”）</li>
</ul>

<hr />

<h2 id="3-环境与依赖">3. 环境与依赖</h2>

<p>本文以 Windows 为例（PowerShell）。其他系统同理。</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">Python 3.10+</code>（用于自动化脚本）</li>
  <li><code class="language-plaintext highlighter-rouge">git</code>（用于拉取仓库）</li>
  <li><code class="language-plaintext highlighter-rouge">gitleaks</code>（主扫描工具，本文使用二进制方式）</li>
</ul>

<p>建议单独准备一个工作目录，例如：</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">D:\sec-tools\gitleaks\</code></li>
  <li>其中放置：<code class="language-plaintext highlighter-rouge">gitleaks.exe</code>、<code class="language-plaintext highlighter-rouge">gitlab_scanner.py</code>、输出目录 <code class="language-plaintext highlighter-rouge">reports\</code></li>
</ul>

<hr />

<h2 id="4-安装-gitleakswindows-二进制">4. 安装 Gitleaks（Windows 二进制）</h2>

<p>1）从官方 Releases 下载对应平台的 zip（示例：<code class="language-plaintext highlighter-rouge">gitleaks_8.x.x_windows_x64.zip</code>）。</p>

<p>2）解压后将 <code class="language-plaintext highlighter-rouge">gitleaks.exe</code> 放入工作目录，例如：</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">D:\sec-tools\gitleaks\gitleaks.exe</code></li>
</ul>

<p>3）验证安装：</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">.</span><span class="n">\gitleaks.exe</span><span class="w"> </span><span class="nx">version</span><span class="w">
</span></code></pre></div></div>

<p>若输出版本号（如 <code class="language-plaintext highlighter-rouge">8.30.0</code>），即安装成功。</p>

<hr />

<h2 id="5-基础用法单仓扫描默认规则">5. 基础用法：单仓扫描（默认规则）</h2>

<h3 id="51-克隆仓库建议全量克隆确保扫描历史">5.1 克隆仓库（建议全量克隆，确保扫描历史）</h3>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">git</span><span class="w"> </span><span class="nx">clone</span><span class="w"> </span><span class="nx">https://gitlab.example.com/group/project.git</span><span class="w">
</span></code></pre></div></div>

<h3 id="52-扫描并输出报告">5.2 扫描并输出报告</h3>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">.</span><span class="n">\gitleaks.exe</span><span class="w"> </span><span class="nx">detect</span><span class="w"> </span><span class="nt">--source</span><span class="w"> </span><span class="o">.</span><span class="nx">\project</span><span class="w"> </span><span class="nt">--report-format</span><span class="w"> </span><span class="nx">json</span><span class="w"> </span><span class="nt">--report-path</span><span class="w"> </span><span class="o">.</span><span class="nx">\report.json</span><span class="w">
</span></code></pre></div></div>

<p>说明：</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">detect</code>：扫描模式</li>
  <li><code class="language-plaintext highlighter-rouge">--source</code>：扫描目标目录（建议指向仓库根目录，含 <code class="language-plaintext highlighter-rouge">.git</code>）</li>
  <li><code class="language-plaintext highlighter-rouge">--report-format json</code> / <code class="language-plaintext highlighter-rouge">--report-path</code>：落盘报告，便于留存审计证据</li>
</ul>

<hr />

<h2 id="6-自定义检测规则关键词内部-token-格式">6. 自定义检测规则（关键词/内部 Token 格式）</h2>

<p>Gitleaks 支持通过 TOML 配置自定义规则。常见场景：</p>

<ul>
  <li>你们内部 Token 有固定前缀/格式（如 <code class="language-plaintext highlighter-rouge">COMP-TOKEN-...</code>）</li>
  <li>想对特定文件名或路径做额外检测</li>
</ul>

<h3 id="61-配置文件示例">6.1 配置文件示例</h3>

<p>创建 <code class="language-plaintext highlighter-rouge">gitleaks.toml</code>（示例）：</p>

<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">title</span> <span class="p">=</span> <span class="s">"Company Custom Rules"</span>

<span class="nn">[[rules]]</span>
<span class="py">id</span> <span class="p">=</span> <span class="s">"company-internal-token"</span>
<span class="py">description</span> <span class="p">=</span> <span class="s">"Detected internal token"</span>
<span class="py">regex</span> <span class="p">=</span> <span class="s">'''COMP-TOKEN-[A-Za-z0-9_-]{20,}'''</span>
<span class="py">tags</span> <span class="p">=</span> <span class="p">[</span><span class="s">"internal"</span><span class="p">,</span> <span class="s">"critical"</span><span class="p">]</span>
</code></pre></div></div>

<h3 id="62-使用自定义规则扫描">6.2 使用自定义规则扫描</h3>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">.</span><span class="n">\gitleaks.exe</span><span class="w"> </span><span class="nx">detect</span><span class="w"> </span><span class="nt">--source</span><span class="w"> </span><span class="o">.</span><span class="nx">\project</span><span class="w"> </span><span class="nt">--config</span><span class="w"> </span><span class="o">.</span><span class="nx">\gitleaks.toml</span><span class="w"> </span><span class="nt">--report-format</span><span class="w"> </span><span class="nx">json</span><span class="w"> </span><span class="nt">--report-path</span><span class="w"> </span><span class="o">.</span><span class="nx">\report.json</span><span class="w">
</span></code></pre></div></div>

<p>提示：</p>

<ul>
  <li>自定义规则应尽量减少误报（正则尽量贴合真实 Token 格式）</li>
  <li>对“关键字”类型的规则要谨慎：纯关键字匹配会产生大量噪声，建议结合格式、长度、前后缀等约束</li>
</ul>

<hr />

<h2 id="7-面对上万项目推荐策略筛选--分批--可续跑">7. 面对上万项目：推荐策略（筛选 + 分批 + 可续跑）</h2>

<p>当 GitLab 项目达到上万级别时，直接全量扫描通常不现实：</p>

<ul>
  <li>时间成本高（仓库数量 × 拉取时间 × 扫描时间）</li>
  <li>IO 压力大</li>
  <li>误报处理压力大</li>
</ul>

<p>实践中更推荐先做<strong>范围收敛</strong>：例如“最近半年有提交/发布活动的项目优先”。</p>

<p>本文采用的策略：</p>

<ol>
  <li><strong>先筛选</strong>：只保留最近提交时间在 <code class="language-plaintext highlighter-rouge">2025-07-01</code> 之后的项目（可改为你需要的日期）</li>
  <li><strong>把筛选结果落盘</strong>：输出为一个 CSV（包含扫描所需字段 + 最近提交时间）</li>
  <li><strong>再从 CSV 读取进行扫描</strong>：分批扫描（每 20 个一组）</li>
  <li><strong>进度保存</strong>：每处理完一个项目写入进度文件，可 <code class="language-plaintext highlighter-rouge">Ctrl+C</code> 中断，下次续跑</li>
  <li><strong>结果落盘</strong>：每个项目一个 JSON 报告，便于后续工单/整改跟踪</li>
</ol>

<hr />

<h2 id="8-自动化批量筛选并汇总符合条件的项目清单不执行扫描">8. 自动化：批量筛选并汇总“符合条件的项目清单”（不执行扫描）</h2>

<p>本实践脚本位于（示例）：</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">D:\sec-tools\gitleaks\gitlab_scanner.py</code></li>
</ul>

<h3 id="81-使用环境变量传入-token避免硬编码">8.1 使用环境变量传入 Token（避免硬编码）</h3>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$</span><span class="nn">env</span><span class="p">:</span><span class="nv">GITLAB_TOKEN</span><span class="o">=</span><span class="s2">"***REDACTED***"</span><span class="w">
</span></code></pre></div></div>

<h3 id="82-自动分批拉取并汇总每批-500-个">8.2 自动分批拉取并汇总（每批 500 个）</h3>

<p>以下命令会：</p>

<ul>
  <li>每批获取 500 个项目（脚本内部会按 GitLab API <code class="language-plaintext highlighter-rouge">per_page=100</code> 分页组合）</li>
  <li>计算每个项目默认分支最近提交时间</li>
  <li>只把符合 <code class="language-plaintext highlighter-rouge">--cutoff-date</code> 的项目写入汇总文件</li>
  <li><strong>中间过程不扫描</strong></li>
</ul>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">python</span><span class="w"> </span><span class="o">.</span><span class="nx">\gitlab_scanner.py</span><span class="w"> </span><span class="nt">--export-filtered-all</span><span class="w"> </span><span class="nt">--cutoff-date</span><span class="w"> </span><span class="nx">2025-07-01</span><span class="w">
</span></code></pre></div></div>

<p>输出文件（示例）：</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">reports\filtered_projects_since_20250701_all.csv</code></li>
</ul>

<p>字段：</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">project_id,name,path_with_namespace,web_url,default_branch,http_url_to_repo,last_commit_time</code></li>
</ul>

<blockquote>
  <p>磁盘占用说明：CSV 为纯文本，体积很小；真正占空间的是仓库克隆目录，而筛选阶段不克隆仓库，因此不会产生大量磁盘占用。</p>
</blockquote>

<hr />

<h2 id="9-从汇总-csv-开始扫描20-个为一组">9. 从汇总 CSV 开始扫描（20 个为一组）</h2>

<h3 id="91-推荐自动连续跑非交互">9.1 推荐：自动连续跑（非交互）</h3>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$</span><span class="nn">env</span><span class="p">:</span><span class="nv">GITLAB_TOKEN</span><span class="o">=</span><span class="s2">"***REDACTED***"</span><span class="w">
</span><span class="n">python</span><span class="w"> </span><span class="o">.</span><span class="nx">\gitlab_scanner.py</span><span class="w"> </span><span class="nt">--scan-from-filtered</span><span class="w"> </span><span class="nt">--filtered-projects-file</span><span class="w"> </span><span class="o">.</span><span class="nx">\reports\filtered_projects_since_20250701_all.csv</span><span class="w"> </span><span class="nt">--batch-size</span><span class="w"> </span><span class="nx">20</span><span class="w"> </span><span class="nt">--no-prompt</span><span class="w"> </span><span class="nt">--progress-file</span><span class="w"> </span><span class="o">.</span><span class="nx">\reports\scan_progress_since_20250701_all.txt</span><span class="w">
</span></code></pre></div></div>

<p>说明：</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">--batch-size 20</code>：每组 20 个项目</li>
  <li><code class="language-plaintext highlighter-rouge">--no-prompt</code>：不需要每批回车确认，自动连续跑</li>
  <li><code class="language-plaintext highlighter-rouge">--progress-file ...</code>：指定进度文件（非常关键）</li>
</ul>

<h3 id="92-如何中断如何续跑">9.2 如何中断？如何续跑？</h3>

<ul>
  <li><strong>中断</strong>：在运行脚本的终端按 <code class="language-plaintext highlighter-rouge">Ctrl + C</code></li>
  <li><strong>续跑</strong>：再次执行同一条命令，并保持使用同一个 <code class="language-plaintext highlighter-rouge">--progress-file</code> 路径，脚本会从上次进度继续</li>
  <li><strong>强制从头开始</strong>：增加 <code class="language-plaintext highlighter-rouge">--reset-progress</code> 或删除进度文件</li>
</ul>

<hr />

<h2 id="10-扫描报告与落盘位置">10. 扫描报告与落盘位置</h2>

<p>默认输出目录（示例）：</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">D:\sec-tools\gitleaks\reports\</code></li>
</ul>

<p>报告文件命名示例：</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">batch_1_projectName_12345_report.json</code></li>
</ul>

<p>这样能避免不同项目重名导致报告覆盖。</p>

<p>当 Gitleaks 发现疑似泄漏时，报告里常见字段包括：</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">File</code> / <code class="language-plaintext highlighter-rouge">Line</code>：命中位置</li>
  <li><code class="language-plaintext highlighter-rouge">RuleID</code>：命中规则</li>
  <li><code class="language-plaintext highlighter-rouge">Secret</code> / <code class="language-plaintext highlighter-rouge">Match</code>：命中内容（注意脱敏处理）</li>
</ul>

<p>建议在审计落地中建立以下处置流程：</p>

<ul>
  <li>分级：高危（有效凭据/生产配置）&gt; 中危（疑似 Token/弱口令）&gt; 低危（误报/测试样例）</li>
  <li>处置：立即吊销/轮换 → 排查影响面 → 添加扫描规则/白名单 → 复扫验证</li>
</ul>

<hr />

<h2 id="11-进阶海量报告的自动化合并-json-to-csv">11. 进阶：海量报告的自动化合并 (JSON to CSV)</h2>

<p>当扫描了数千个项目后，你会得到数千个 JSON 文件。逐个查看效率极低，推荐将其聚合为一个 CSV 表格，便于在 Excel 中进行筛选、透视和分发。</p>

<p>我们提供了一个专用脚本 <code class="language-plaintext highlighter-rouge">gitleaks_reports_to_csv.py</code> 来完成此任务。</p>

<h3 id="111-功能特点">11.1 功能特点</h3>

<ul>
  <li><strong>自动遍历</strong>：递归扫描 <code class="language-plaintext highlighter-rouge">reports</code> 目录下的所有 <code class="language-plaintext highlighter-rouge">.json</code> 报告</li>
  <li><strong>字段提取</strong>：自动提取 <code class="language-plaintext highlighter-rouge">File</code>, <code class="language-plaintext highlighter-rouge">RuleID</code>, <code class="language-plaintext highlighter-rouge">Author</code>, <code class="language-plaintext highlighter-rouge">Date</code>, <code class="language-plaintext highlighter-rouge">Message</code>, <code class="language-plaintext highlighter-rouge">Entropy</code>, <code class="language-plaintext highlighter-rouge">Match</code> 等关键字段</li>
  <li><strong>Excel 兼容</strong>：输出的 CSV 使用 <code class="language-plaintext highlighter-rouge">utf-8-sig</code> 编码，<strong>解决 Excel 打开中文乱码问题</strong></li>
</ul>

<h3 id="112-使用方法">11.2 使用方法</h3>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">python</span><span class="w"> </span><span class="o">.</span><span class="nx">\gitleaks_reports_to_csv.py</span><span class="w"> </span><span class="nt">--reports-dir</span><span class="w"> </span><span class="o">.</span><span class="nx">\reports</span><span class="w"> </span><span class="nt">--output</span><span class="w"> </span><span class="o">.</span><span class="nx">\reports\gitleaks_findings.csv</span><span class="w">
</span></code></pre></div></div>

<p>运行后，你将得到一个 <code class="language-plaintext highlighter-rouge">gitleaks_findings.csv</code> 文件。你可以直接用 Excel 打开它，对 <code class="language-plaintext highlighter-rouge">RuleID</code> 进行数据透视，快速识别高频误报或高危泄露。</p>

<hr />

<h2 id="12-常见问题与排障">12. 常见问题与排障</h2>

<h3 id="121-windows-清理目录时出现-winerror-32文件占用">12.1 Windows 清理目录时出现 <code class="language-plaintext highlighter-rouge">WinError 32</code>（文件占用）</h3>

<p>在 Windows 上，<code class="language-plaintext highlighter-rouge">.git</code> 目录可能被索引/杀软短暂占用，导致删除失败。</p>

<p>实践处理：</p>

<ul>
  <li>清理逻辑增加重试与指数退避（脚本可实现）</li>
  <li>即使清理失败，也不要让脚本崩溃（避免整批扫描中断）</li>
</ul>

<h3 id="122-api-分页与-per_page-上限">12.2 API 分页与 <code class="language-plaintext highlighter-rouge">per_page</code> 上限</h3>

<p>GitLab API 常见限制：</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">per_page</code> 最大通常为 <code class="language-plaintext highlighter-rouge">100</code></li>
</ul>

<p>因此当你希望“每批 500 个”时，需要脚本内部拉取 5 页来凑满一批。</p>

<hr />

<h2 id="13-安全注意事项务必遵守">13. 安全注意事项（务必遵守）</h2>

<ul>
  <li>Token 不要硬编码在脚本/文档里，推荐用环境变量：<code class="language-plaintext highlighter-rouge">$env:GITLAB_TOKEN="..."</code>（或 CI 的 Secret）</li>
  <li>不要在终端输出、截图、报告中泄露真实密钥</li>
  <li>报告文件建议受控存储（加密盘/权限隔离/最小可见范围）</li>
  <li>对命中的真实凭据，优先采取“吊销/轮换”，而不是仅删除代码</li>
</ul>

<hr />

<h2 id="14-快速操作清单复制即用">14. 快速操作清单（复制即用）</h2>

<p><strong>A. 汇总筛选（不扫描）</strong></p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$</span><span class="nn">env</span><span class="p">:</span><span class="nv">GITLAB_TOKEN</span><span class="o">=</span><span class="s2">"***REDACTED***"</span><span class="w">
</span><span class="n">python</span><span class="w"> </span><span class="o">.</span><span class="nx">\gitlab_scanner.py</span><span class="w"> </span><span class="nt">--export-filtered-all</span><span class="w"> </span><span class="nt">--cutoff-date</span><span class="w"> </span><span class="nx">2025-07-01</span><span class="w">
</span></code></pre></div></div>

<p><strong>B. 从汇总文件开始扫描（20 个一组，自动续跑）</strong></p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$</span><span class="nn">env</span><span class="p">:</span><span class="nv">GITLAB_TOKEN</span><span class="o">=</span><span class="s2">"***REDACTED***"</span><span class="w">
</span><span class="n">python</span><span class="w"> </span><span class="o">.</span><span class="nx">\gitlab_scanner.py</span><span class="w"> </span><span class="nt">--scan-from-filtered</span><span class="w"> </span><span class="nt">--filtered-projects-file</span><span class="w"> </span><span class="o">.</span><span class="nx">\reports\filtered_projects_since_20250701_all.csv</span><span class="w"> </span><span class="nt">--batch-size</span><span class="w"> </span><span class="nx">20</span><span class="w"> </span><span class="nt">--no-prompt</span><span class="w"> </span><span class="nt">--progress-file</span><span class="w"> </span><span class="o">.</span><span class="nx">\reports\scan_progress_since_20250701_all.txt</span><span class="w">
</span></code></pre></div></div>

<p><strong>C. 中断/续跑</strong></p>

<ul>
  <li>中断：<code class="language-plaintext highlighter-rouge">Ctrl + C</code></li>
  <li>续跑：重复执行 B（同一个 <code class="language-plaintext highlighter-rouge">--progress-file</code>）</li>
</ul>

<p><strong>D. 报告合并 (JSON -&gt; CSV)</strong></p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">python</span><span class="w"> </span><span class="o">.</span><span class="nx">\gitleaks_reports_to_csv.py</span><span class="w"> </span><span class="nt">--reports-dir</span><span class="w"> </span><span class="o">.</span><span class="nx">\reports</span><span class="w"> </span><span class="nt">--output</span><span class="w"> </span><span class="o">.</span><span class="nx">\reports\gitleaks_findings.csv</span><span class="w">
</span></code></pre></div></div>

<hr />

<p>至此，你就拥有了一个可复用的企业级 Secret 扫描工作流：<strong>先收敛范围，再批量扫描，结果可追溯，进度可续跑</strong>。如后续希望进一步降低误报（例如引入自定义规则、白名单、或二次校验），建议在现有规则基础上逐步迭代，不要一开始就写大量“纯关键字”规则。</p>]]></content><author><name></name></author><category term="Enterprise" /><category term="Security" /><summary type="html"><![CDATA[本文记录“公司 GitLab 大规模密钥/敏感配置扫描”的落地实践， 从安装 Gitleaks、单仓扫描，到面对上万项目时如何“先筛选、再分批、可中断可续跑”地完成审计闭环。]]></summary></entry></feed>