turbot/steampipe-mod-github-compliance

Control: 3.1.7 Ensure dependencies are pinned to a specific, verified version

Description

Pin dependencies to a specific version. Avoid using the "latest" tag or broad version.

Rationale

When using a wildcard version of a package, or the "latest" tag, the risk of encountering a new, potentially malicious package increases. The "latest" tag pulls the last package pushed to the registry. This means that if an attacker pushes a new, malicious package successfully to the registry, the next user who pulls the "latest" will pull it and risk attack. This same rule applies to a wildcard version. Assuming one is using version v1.*, it will install the latest version of the major version 1, meaning that if an attacker can push a malicious package with that same version, those using it will be subject to possible attack. By using a secure, verified version, use is restricted to this version only and no other may be pulled, decreasing the risk for any malicious package.

Audit

For every dependency in use, ensure it is pinned to a specific version.

Remediation

For every dependency in use, pin to a specific version.

Usage

Run the control in your terminal:

powerpipe control run github_compliance.control.cis_supply_chain_v100_3_1_7

Snapshot and share results via Turbot Pipes:

powerpipe login
powerpipe control run github_compliance.control.cis_supply_chain_v100_3_1_7 --share

SQL

This control uses a named query:

with repositories as (
select
name_with_owner,
url
from
github_my_repository
order by
name_with_owner
),
pipelines as (
select
name,
repository_full_name,
pipeline
from
github_workflow
where
repository_full_name in (select name_with_owner from repositories)
),
unpinned_task_count as (
select
count(*) filter (where step ->> 'type' = 'task' and (step -> 'task' ->> 'version_type')::text != 'commit' ) as unpinned_task_count,
count(*) filter (where step ->> 'type' = 'task' and (step -> 'task' ->> 'version_type')::text = 'commit' ) as pinned_task_count,
p.repository_full_name
from
pipelines as p,
jsonb_array_elements(pipeline -> 'jobs') as job,
jsonb_array_elements(job -> 'steps') as step
group by
repository_full_name
)
select
-- Required Columns
r.url as resource,
case
when u.unpinned_task_count > 0 then 'alarm'
else 'ok'
end as status,
case
when u.unpinned_task_count > 0 then unpinned_task_count::text || ' task(s) are not pinned.'
when u.repository_full_name is null then 'No build task(s) in the repository.'
else 'All task(s) are pinned.'
end as reason,
-- Additional Dimensions
r.name_with_owner
from
repositories as r
left join unpinned_task_count as u on r.name_with_owner = u.repository_full_name;

Tags