Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/zizmor/src/audit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub(crate) mod secrets_inherit;
pub(crate) mod self_hosted_runner;
pub(crate) mod stale_action_refs;
pub(crate) mod template_injection;
pub(crate) mod timeout_minutes;
pub(crate) mod unpinned_images;
pub(crate) mod unpinned_uses;
pub(crate) mod unredacted_secrets;
Expand Down
62 changes: 62 additions & 0 deletions crates/zizmor/src/audit/timeout_minutes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use anyhow::Result;

use crate::{
finding::{
Confidence, Finding, Persona, Severity,
location::{Locatable as _, SymbolicLocation},
},
models::workflow::JobExt as _,
state::AuditState,
};

use super::{Audit, AuditLoadError, audit_meta};

pub(crate) struct TimeoutMinutes;

impl TimeoutMinutes {
fn build_finding<'doc>(
&self,
location: SymbolicLocation<'doc>,
annotation: &str,
job: &super::NormalJob<'doc>,
) -> Result<Finding<'doc>> {
let mut annotated_location = location;
annotated_location = annotated_location.annotated(annotation);
Self::finding()
.severity(Severity::Medium)
.confidence(Confidence::High)
.add_location(annotated_location)
.persona(Persona::Pedantic)
.build(job.parent())
}
}

audit_meta!(
TimeoutMinutes,
"timeout-minutes",
"missing timeout-minutes on jobs"
);

impl Audit for TimeoutMinutes {
fn new(_state: &AuditState<'_>) -> Result<Self, AuditLoadError> {
Ok(Self)
}

fn audit_normal_job<'doc>(
&self,
job: &super::NormalJob<'doc>,
) -> anyhow::Result<Vec<Finding<'doc>>> {
let mut findings = vec![];

// Check if timeout-minutes is missing
if job.timeout_minutes.is_none() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach looks right to me! Let's do the same for each step in the job as well 🙂

findings.push(self.build_finding(
job.location().primary(),
"job is missing timeout-minutes",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"job is missing timeout-minutes",
"missing timeout-minutes",

job,
)?);
}

Ok(findings)
}
}
5 changes: 3 additions & 2 deletions crates/zizmor/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
//! audits.

use std::{
collections::{BTreeMap, btree_map},
collections::{btree_map, BTreeMap},
fmt::Display,
process::ExitCode,
str::FromStr,
};

use anyhow::{Context, anyhow};
use anyhow::{anyhow, Context};
use camino::{Utf8Path, Utf8PathBuf};
use indexmap::IndexMap;
use serde::Serialize;
Expand Down Expand Up @@ -352,6 +352,7 @@ impl AuditRegistry {
register_audit!(audit::self_hosted_runner::SelfHostedRunner);
register_audit!(audit::known_vulnerable_actions::KnownVulnerableActions);
register_audit!(audit::unpinned_uses::UnpinnedUses);
register_audit!(audit::timeout_minutes::TimeoutMinutes);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this to the end, please -- right now these are declared in order of introduction, not alphabetically.

register_audit!(audit::insecure_commands::InsecureCommands);
register_audit!(audit::github_env::GitHubEnv);
register_audit!(audit::cache_poisoning::CachePoisoning);
Expand Down
8 changes: 8 additions & 0 deletions test-workflow.yml
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be moved under crates/zizmor/tests/integration/test-data and named timeout-minutes.yml or similar, once you're ready 🙂

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: Test Workflow
on: push

jobs:
test-job:
runs-on: ubuntu-latest
steps:
- run: echo "Hello World"