Um momento
0xB0Lesson 12 of 14

Keeping projects secure

Protect accounts, dependencies, secrets and workflows with 2FA, Dependabot, secret scanning, code scanning, rulesets and hardened Actions.

28 min 7-question quiz 2 code exercises
By the end of this lesson you can
  • Secure accounts with two-factor authentication and passkeys
  • Use Dependabot, secret scanning with push protection, and code scanning
  • Harden branches with rulesets and workflows with pinned actions and least privilege

An open-source game might not seem like a target, but attackers love popular repositories: compromise one, and you can ship malware to everyone who installs it. GitHub’s Security tab gathers the defenses:

FeatureProtects against
Two-factor authentication / passkeysa stolen password taking over a maintainer’s account
Dependabot alertsdependencies with known vulnerabilities (from the GitHub Advisory Database)
Dependabot updatesfalling behind - it opens PRs that bump vulnerable or outdated dependencies
Secret scanning + push protectioncommitted tokens and keys; push protection blocks the push before the secret lands
Code scanning (CodeQL)vulnerabilities in your own code, like SQL injection, flagged on PRs
Branch protection / rulesetsunreviewed or untested code reaching main, force pushes, deleted history
SECURITY.md + private vulnerability reportingresearchers announcing a vulnerability publicly before it’s fixed
.github/dependabot.yml
1version: 2
2updates:
3  - package-ecosystem: pip
4    directory: "/"
5    schedule:
6      interval: weekly
7  - package-ecosystem: github-actions   # keep the actions in workflows up to date too
8    directory: "/"
9    schedule:
10      interval: weekly

Hardening GitHub Actions

Workflows run code with access to your secrets and repository, so they’re a favorite target. The essentials:

  • Pin third-party actions to a full commit SHA: uses: some/action@8f4b7f84... instead of @v2. Tags can be moved to point at malicious code - this has happened. (Add the version as a comment; Dependabot can still update pinned SHAs.)
  • Least privilege: set permissions: at the top of every workflow, starting from contents: read.
  • Beware pull_request_target: it runs with secrets and write access in the context of the base repository, even for PRs from forks. Never check out and run the PR’s code in it.
  • Don’t interpolate untrusted input into scripts: run: echo "${{ github.event.issue.title }}" lets anyone who opens an issue inject shell commands. Pass it through an environment variable instead.

Try it

Audit this workflow

A contributor proposed this workflow to welcome new issue authors. Click every line that’s a security problem, then check what you missed.

.github/workflows/welcome.yml (1 of 1)Flags found 0/0

Click every part that looks suspicious. There are 4.

name: Welcome on: issues: types: [opened] permissions: write-all jobs: greet: runs-on: ubuntu-latest steps: - uses: cool-bots/greeter@main - run: echo "Thanks for ${{ github.event.issue.title }}!" - run: curl -H "Authorization: ${{ secrets.ADMIN_TOKEN }}" https://stats.example.com/new-issue
the safe version
1name: Welcome
2on:
3  issues:
4    types: [opened]
5permissions:
6  issues: write
7jobs:
8  greet:
9    runs-on: ubuntu-latest
10    steps:
11      - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea  # v7.0.1
12        env:
13          TITLE: ${{ github.event.issue.title }}
14        with:
15          script: |
16            await github.rest.issues.createComment({
17              ...context.repo,
18              issue_number: context.issue.number,
19              body: `Thanks for reporting "${process.env.TITLE}"! A maintainer will take a look.`,
20            })

Key takeaways

  • Turn on 2FA (or passkeys) - maintainer accounts are the keys to everyone’s installs.

  • Dependabot alerts and updates handle vulnerable dependencies; secret scanning with push protection stops leaked tokens.

  • Rulesets and branch protection keep unreviewed, untested code out of main.

  • Harden workflows: pin actions to SHAs, use least-privilege permissions, and never interpolate untrusted input into scripts.

Lesson quiz

7 questions · pass with 5 correct · up to 50 XP

Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.

Practice: automate GitHub chores with Python

Real GitHub work involves lots of small automation: matching CODEOWNERS, expanding build matrices, bumping versions, reading the API. Write those helpers in Python and run them against sample inputs - locally in your browser, with no GitHub account needed.

Exercise 1

Audit the actions

+25 XP

The input is a workflow file. Find every uses: reference and classify it, printing owner/repo@ref: CATEGORY in order:

  • local - starts with ./
  • docker - starts with docker://
  • pinned - the ref is a full 40-character hex commit SHA
  • trusted tag - an unpinned tag or branch on an action owned by actions or github
  • UNPINNED - any other third-party action on a tag or branch

Finally print N unpinned third-party actions (or all clear) - and permissions: missing if the file has no permissions: key at all.

  • The welcome workflow
  • Hardened
main.py
Loading editor…

Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.

Exercise 2

Triage Dependabot alerts

+25 XP

Each input line is an alert as JSON: {"package": ..., "severity": "critical"|"high"|"medium"|"low", "vulnerable": "<2.3.4", "fixed_in": "2.3.4"|null, "state": "open"|"dismissed"|"fixed"}. For open alerts only, print them most severe first (ties by package name) as CRITICAL pillow: update to 10.3.0 or HIGH tinyparse: no fix yet, then a summary open: 1 critical, 2 high, 0 medium, 0 low.

  • This week
main.py
Loading editor…

Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.

Questions about this lesson

Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.

Loading posts…

Gostou da aula? 😆👍
Apoie nosso trabalho com uma doação: