安全源代码

1. 概览

安全源代码技术是指可用于提高源代码安全性的一系列做法。这些技术有助于识别和修复源代码中的漏洞,防止他人未经授权访问源代码,以及防止源代码遭到修改。

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

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

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

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

学习内容

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

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

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

2. 设置和要求

自定进度的环境设置

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

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.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 Editor 搭配使用,并经过测试。要访问该编辑器,请按以下步骤操作:

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

8560cc8d45e8c112

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

9e504cb98a6a8005

  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 请求

lint 检查用于检查与语法相关的常见基于样式的错误或缺陷。lint 可通过在多个团队之间提供通用语法模式来帮助提高安全性,从而加快代码审核、知识共享和代码的清晰度。

此外,lint 还可以识别可能会导致常见漏洞的常见语法错误,例如库或核心 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 $?

在本例中,由于该命令没有导致错误,因此退出状态将为 0

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. 许可扫描

许可对于安全非常重要,因为它可以法律要求您公开您可能不想公开的源代码。其概念称为copyleft"许可要求您公开源代码。

安装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 日