如何用预定的管道定期运行安全扫描

192 阅读8分钟

安全是应用程序开发的一个重要部分,但它可能被忽视,直到攻击者利用系统中的漏洞。安全漏洞的后果会损害应用程序的完整性,以及公司的声誉和收入。软件架构师和工程师需要特别注意他们所工作的系统的安全。

运行基于安全的测试并将安全自动化到CI/CD工作流程中是DevSecOps背后的灵感,这是DevOps方法在应用安全领域的延伸。

在这篇文章中,我将带领你完成应用程序中的自动化安全检查。我将向你展示如何在一个Web表单上运行一个测试,在URL字段中注入恶意的域名。该测试的目的是破坏Web表单。为了阻止攻击,Web表单已经被保护了,它的逻辑是检查用户是否试图输入一个恶意的域名。我将向你展示如何使用预定管道来定期运行安全测试。

前提条件

要继续学习本教程,你需要具备这些条件。

一旦你设置好了这些,你就可以开始了。

获取Webshrinker证书

Webshrinker是一个人工智能驱动的域名分类系统,由DNS安全公司DNSFilter拥有。Webshrinker能够识别威胁域,并根据其威胁类别对其进行标记。网络钓鱼、恶意软件和僵尸网络只是Webshrinker能够识别的三种威胁类型。

我们在项目中保护的表单在其URL字段中采用了一个完全合格的域名。它将域名发送到Webshrinker API,以进行威胁扫描。如果结果表明它是恶意的,Webshrinker会返回一个威胁标识符。该表格使用威胁标识符来拒绝处理该域名条目。

你将需要一个API密钥和API秘密来使用本演示中的Webshrinker。一旦你创建了一个账户,你可以通过进入API访问密钥页面并点击创建API密钥按钮来创建新的API凭证。这将生成你的API秘密和令牌。

你将在下一步骤中使用你的证书。

克隆和运行演示应用程序

第一步是在本地运行演示Web表单,并检查其行为。你可以在你系统的任何地方运行这个命令,从这个资源库中克隆该表单的代码。

git clone -b base-project --single-branch https://github.com/coderonfleek/scheduled-security-scan.git

一旦你在你的系统上有了代码,通过运行这个命令安装依赖性。

cd scheduled-security-scan
npm install

index.html 现在转到项目根部的6566 文件中的第几行,将占位符分别替换为你的API密钥和API秘密。

当依赖关系的安装完成后,用这个命令运行应用程序。

npm start

应用程序启动后,你可以在https://localhost:5000 ,查看网络表格。

在电子邮件字段中输入一个电子邮件地址。在URL字段中,输入一个安全域,如facebook.com ,然后点击提交。你将在表格的右侧得到一个安全的回应。

Regular domain test

现在,用这个基于威胁的域名测试表格的URL字段:selcdn.ru 。请不要在你的浏览器中直接输入这个域名。你将会得到一个威胁警报信息。

Malicious Domain test

添加安全测试

下一步是编写自动执行安全检查的测试。你将使用谷歌的Puppeteer添加一些自动化的功能测试。Puppeteer模拟了真实世界的用户填写表格的方式。

在项目的根部添加一个名为login.test.js 的新文件,并输入以下代码。

const puppeteer = require("puppeteer");

const user_email = "test@example.com";
const non_threat_site = "facebook.com";
const malicious_site = "selcdn.ru";
const phishing_site = "mail.glesys.se";
const expected_safe_site_message = "Entry clean, process form";
const expected_threat_site_message = "Threat Detected. Do not Process";

test("Check Non-threat Site Entry", async () => {
  const browser = await puppeteer.launch();
  try {
    const page = await browser.newPage();

    await page.goto("http://localhost:5000");

    await page.type("#userEmail", user_email);
    await page.type("#userSite", non_threat_site);
    await page.click("#submitButton");

    let messageContainer = await page.$("#infoDisplay");
    await page.waitForTimeout(4000);
    let value = await messageContainer.evaluate((el) => el.textContent);

    console.log(value);

    expect(value).toBe(expected_safe_site_message);
  } finally {
    await browser.close();
  }
}, 120000);

test("Check Malicious Site Entry", async () => {
  const browser = await puppeteer.launch();
  try {
    const page = await browser.newPage();

    await page.goto("http://localhost:5000");

    await page.type("#userEmail", user_email);
    await page.type("#userSite", malicious_site);
    await page.click("#submitButton");

    let messageContainer = await page.$("#infoDisplay");
    await page.waitForTimeout(4000);

    let value = await messageContainer.evaluate((el) => el.textContent);

    console.log(value);

    expect(value).toBe(expected_threat_site_message);
  } finally {
    await browser.close();
  }
}, 120000);

这个文件包含两个测试案例。第一个测试是检查像facebook.com 这样的非威胁域名是否被系统阻止。这可以使你的安全实现不至于过度热心地阻止普通的域名。

第二个测试用例通过使用一个恶意域名样本来检查恶意条目。如果表单阻止了这个域名,测试就通过了。如果恶意域名没有被阻止,则测试失败。

保存文件并在你的终端中进入项目的根目录。确保应用程序在另一个shell中运行;测试需要它来成功运行。运行这个命令。

npm run test

一旦测试运行完成,你的CLI中就会有像这样的结果。

MACs-MBP-2:scheduled-security-scan mac$ npm run test

> xss-attack@1.0.0 test /Users/mac/Documents/CircleCiProjects/2022/scheduled-security-scan
> jest

  console.log
    Entry clean, process form

      at Object.<anonymous> (login.test.js:26:13)

 PASS  ./login.test.js (109.034 s)
  ✓ Check Non-threat Site Entry (80318 ms)
  ✓ Check Malicious Site Entry (8210 ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        120.252 s
Ran all test suites.
  console.log
    Threat Detected. Do not Process

      at Object.<anonymous> (login.test.js:54:13)

开发人员可能会被诱惑去写符合他们代码能力的测试。作为一个最佳实践,一定要把开发和测试团队分开。这种做法可以让测试团队写出详尽的测试,并保护开发人员不受自己的影响。

添加管道配置脚本

为了使测试过程自动化,我们可以使用CircleCI建立一个持续集成(CI)管道。

为了设置CI管道,你需要一个管道配置脚本。你可以把这个脚本添加到一个.circleci/config.yml 文件中。在项目的根部创建该文件,然后输入。

version: 2.1
jobs:
  build:
    working_directory: ~/repo
    docker:
      - image: cimg/node:14.18-browsers
    steps:
      - checkout
      - run:
          name: Update NPM
          command: "sudo npm install -g npm"
      - restore_cache:
          key: dependency-cache-{{ checksum "package-lock.json" }}
      - run:
          name: Install Dependencies
          command: npm install
      - save_cache:
          key: dependency-cache-{{ checksum "package-lock.json" }}
          paths:
            - ./node_modules
      - run:
          name: Run the application
          command: node server.js
          background: true
      - run:
          name: Run tests
          command: npm run test

这个配置脚本。

  • 拉入一个安装有浏览器和Node.js的Docker镜像
  • 更新npm ,并安装所需的项目依赖性
  • 在后台运行应用程序,以便Cypress测试能够加载它
  • 运行测试

保存文件并将项目推送至GitHub

接下来,将该仓库添加为CircleCI项目。

Add Project - CircleCI

Select Branch - CircleCI

一旦项目在CircleCI上设置好了,测试就会立即运行。当构建完成后,你会得到一个成功的构建状态。

Build Success - CircleCI

点击构建链接,查看构建细节。

Build Details - CircleCI

在CircleCI上设置一个预定的管道

通常情况下,你的CI管道只在你设置管道时使用的远程代码库有新的提交时运行。为了从安全扫描(如我们编写的测试)中获得最大收益,即使没有推送新代码,应用程序的安全状态也应该被更新。

这意味着我们的管道需要定期运行,就像cron 工作一样,以准确报告应用程序的安全状态。为了保持效率,最好不要将安全测试与检查错误或验证应用程序功能的功能测试混在一起。

为了让您的安全测试自动和按计划运行,CircleCI的计划管道技术是一个不错的选择。

通过CircleCI的计划管道,你可以配置你的管道在特定的一天或一周内的所有日子在特定的时间运行。

在本教程中,我们将设置我们的管道在一周的每一天每五分钟运行一次。为这个项目设置的时间间隔并不是基于任何实际情况、详细考虑或最佳做法。它只是为了演示管道在演示期间定期运行。

要配置你的管道按时间表运行,进入CircleCI,选择项目设置,然后选择触发器

在触发器页面,点击添加预定触发器,显示触发器表格。填写表格,配置管道每天每5分钟运行一次。

Set up trigger - CircleCI

点击保存触发器,你的触发器将被创建。

回到管道页面并等待至少五分钟。您的管道将被CircleCI系统所触发。

Scheduled Runs

每次运行之间的5分钟间隔表明配置已经完全生效。

总结

在本教程中,我已经演示了如何使用CircleCI的计划管道对您的应用程序运行定期安全扫描。而不是等待新的代码构建,你可以让系统不断地运行安全检查,并在某些东西被破坏或容易被入侵时报告。

安全扫描只是可以部署预定管道的众多用例之一。日志和数据归档等清理任务也是配置预定管道的最佳选择。与你的团队分享你所学到的东西,并开始尝试使用预定管道。