安全源代码

1. 概览

安全源代码技术是一组可用于提高源代码安全性的实践。这些技术有助于识别和修复源代码中的漏洞,防止未经授权访问源代码,并保护源代码免遭修改。

一些常见的安全源代码技术包括:

  • Linting:Linting 是指检查源代码是否存在错误和风格问题的过程。这是通过使用 lint 工具完成的,该工具是一种用于分析源代码并识别潜在问题的程序。Lint 工具可用于检查各种错误,包括语法错误、语义错误、样式错误和安全漏洞。
  • 静态应用安全保障测试 (SAST):SAST 是一种安全测试,用于分析源代码、二进制代码或字节码,以识别安全漏洞。SAST 工具可用于查找各种编程语言(包括 Go、Java、Python、C++ 和 C#)中的漏洞。
  • 许可扫描:许可扫描是指识别软件应用中使用的第三方软件组件的许可的过程。这一点非常重要,因为这有助于确保应用符合许可条款,从而避免法律问题。

这些技术可用于在软件开发生命周期的所有阶段提高源代码的安全性。通过 Linting 可以在开发过程中尽早发现错误;通过 SAST 可以在代码编译或部署之前发现漏洞;通过许可扫描可以确保应用符合许可条款。

使用这些技术有助于提高源代码的安全性并降低安全漏洞的风险。

学习内容

本实验将重点介绍用于保护软件源代码的工具和技术。

  • 执行 lint 检查
  • 静态应用安全测试
  • 许可扫描

本实验中使用的所有工具和命令都将在 Cloud Shell 中执行。

2. 设置和要求

自定进度的环境设置

  1. 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个。

b35bf95b8bf3d5d8.pnga99b7ace416376c4.pngbd84a6d3004737c5.png

  • 项目名称是此项目参与者的显示名称。它是 Google API 尚未使用的字符串。您可以随时更新。
  • 项目 ID 在所有 Google Cloud 项目中是唯一的,并且是不可变的(一经设置便无法更改)。Cloud 控制台会自动生成一个唯一字符串;通常情况下,您无需关注该字符串。在大多数 Codelab 中,您都需要引用项目 ID(通常用 PROJECT_ID 标识)。如果您不喜欢生成的 ID,可以再随机生成一个 ID。或者,您也可以尝试自己的项目 ID,看看是否可用。完成此步骤后便无法更改该 ID,并且此 ID 在项目期间会一直保留。
  • 此外,还有第三个值,即部分 API 使用的项目编号,供您参考。如需详细了解所有这三个值,请参阅文档。
  1. 接下来,您需要在 Cloud 控制台中启用结算功能,以便使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。若要关闭资源以避免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除整个项目。Google Cloud 的新用户符合参与 $300 USD 免费试用计划的条件。

启动 Cloud Shell Editor

本实验经过设计和测试,可与 Google Cloud Shell 编辑器搭配使用。如需访问编辑器,请执行以下操作:

  1. 前往 https://console.cloud.google.com 访问您的 Google 项目。
  2. 点击右上角的 Cloud Shell 编辑器图标

8560cc8d45e8c112.png

  1. 系统会在窗口底部打开一个新窗格
  2. 点击“打开编辑器”按钮

9e504cb98a6a8005.png

  1. 编辑器将打开,右侧显示资源管理器,中央区域显示编辑器
  2. 屏幕底部还应显示一个终端窗格
  3. 如果终端未打开,请使用 `ctrl+`` 组合键打开新的终端窗口

环境设置

将 GOPATH 设置为单个目录,以简化本实验中使用的命令。

export GOPATH=$HOME/gopath

创建一个目录来存放我们的工作

mkdir -p workspace
cd workspace

克隆源代码库

git clone https://gitlab.com/gcp-solutions-public/shift-left-security-workshop/source-code-lab.git
cd source-code-lab
export WORKDIR=$(pwd)

3. Lint 检查

Linting 用于检查与语法相关的常见样式错误或缺陷。Linting 通过在多个团队中提供通用语法模式来协助安全工作,从而加快代码审核速度,促进知识共享并提高代码清晰度。

此外,Linting 还会识别可能导致常见漏洞(例如不当或效率较低的库或核心 API 使用)的常见语法错误。

安装 staticcheck 关联工具

 go get honnef.co/go/tools/cmd/staticcheck@latest

在项目根目录中运行 Go Linter (staticcheck)

 staticcheck

查看输出

main.go:42:29: unnecessary use of fmt.Sprintf (S1039)

您之所以会收到此错误,是因为 http.ListenAndServe() 接受的是字符串,而当前代码使用的是 Sprintf,但未将变量传递给字符串

查看命令退出状态。

echo $?

在这种情况下,由于该命令导致了错误,因此退出状态将为 1 或更大。这是可在 CI/CD 流水线中使用的一种方法,用于确定工具的成功/失败。

修改 main.go 文件,并修正代码:

  • 在 main() 方法中,通过添加前导斜杠(//) 注释掉 LINTING - Step 1 下方的代码行。
  • 移除 main() 方法中 LINTING - Step 2 下方两行代码开头的斜杠,以取消对这两行代码的注释。

在项目根目录中重新运行 staticcheck

staticcheck

该命令不应返回任何结果(即空行)。

检查命令的退出状态。

  echo $?

在这种情况下,由于该命令未导致错误,因此退出状态将为 零。

4. 静态应用安全测试

AST/静态安全测试 - 提供静态代码分析,以查找常见弱点和风险 ( CWE)

安装 AST 工具 (gosec)

    export GOSEC_VERSION="2.15.0"
    curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | \
          sh -s -- -b $(go env GOPATH)/bin v${GOSEC_VERSION}

针对源代码运行 gosec 并使用政策文件

gosec -conf policies/gosec-policy.json -fmt=json ./...

输出应类似于以下内容

{
    "Golang errors": {},
    "Issues": [
        {
            "severity": "HIGH",
            "confidence": "LOW",
            "cwe": {
                "ID": "798",
                "URL": "https://cwe.mitre.org/data/definitions/798.html"
            },
            "rule_id": "G101",
            "details": "Potential hardcoded credentials",
            "file": "/home/random-user-here/shift-left-security-workshop/labs/source-code-lab/main.go",
            "code": "31: \t// STEP 2: Change this and the reference below to something different (ie, not \"pawsword\" or \"password\")\n32: \tvar pawsword = \"im-a-cute-puppy\"\n33: \tfmt.Println(\"Something a puppy would use: \", username, pawsword)\n",
            "line": "32",
            "column": "6"
        }
    ],
    "Stats": {
        "files": 1,
        "lines": 89,
        "nosec": 0,
        "found": 1
    }
}

该工具已发现潜在问题:Potential hardcoded credentials

5. 许可扫描

许可对安全性至关重要,因为它们可能会在法律上要求您公开可能不想公开的源代码。这种概念称为“版权保护许可,如果您使用具有这些许可的依赖项,则需要公开源代码。

安装 golicense

mkdir -p /tmp/golicense
wget -O /tmp/golicense/golicense.tar.gz https://github.com/mitchellh/golicense/releases/download/v0.2.0/golicense_0.2.0_linux_x86_64.tar.gz
pushd /tmp/golicense
tar -xzf golicense.tar.gz
chmod +x golicense
mv golicense $(go env GOPATH)/bin/golicense
popd

构建二进制文件

go build

使用不允许“BSD-3-Clause”许可的当前政策文件运行许可检查

golicense policies/license-policy.hcl hello-world

注意:此操作应失败,并显示类似如下的输出:

 🚫 rsc.io/sampler    BSD 3-Clause "New" or "Revised" License
 🚫 rsc.io/quote      BSD 3-Clause "New" or "Revised" License
 🚫 golang.org/x/text BSD 3-Clause "New" or "Revised" License

修改政策文件 policies/license-policy.hcl,将“BSD-3-Clause”从 deny 列表移至 allow 列表。

重新运行许可检查

golicense policies/license-policy.hcl hello-world

注意:此命令应成功执行,并生成类似如下的输出:

    ✅ rsc.io/quote      BSD 3-Clause "New" or "Revised" License
    ✅ rsc.io/sampler    BSD 3-Clause "New" or "Revised" License
    ✅ golang.org/x/text BSD 3-Clause "New" or "Revised" License

6. 恭喜

恭喜,您已完成此 Codelab!

您学到的内容

  • 用于保护源代码的工具和技术

—

上次更新时间:2023 年 3 月 23 日