Skip to content

Commit

Permalink
docs: Provide clarity in policy titles (#140)
Browse files Browse the repository at this point in the history
* docs: Provide clarity in policy titles

This commit adopts the following in an attempt to provide clarity in
policy titles and adopt some more standard RFC language.

- Critical/High rules => Must
- Medium/Low => Should

Additionally, it updates some of the policy language to be more clear.

Resolves: #139
See Also: [RFC-2119](https://www.rfc-editor.org/rfc/rfc2119)
See Also: [RFC-8174](https://www.rfc-editor.org/rfc/rfc8174)

* fix: metadata yaml format issue

Yaml is particular and needs spaces after colons. It can be hard to
track this down when it's in a comment block. It's even more difficult
when you are new to go and don't realize that the docstrings are pulled
from the compiled code and not the source on disk. Whoops...

* docs: Changed must to should

Per the conversation in [this PR](#140 (comment))
I changed instanced of `must` to `should` as all of this advice is guidance
that may be followed or not at the discretion of the implementation
teams that use this tool.

---------

Co-authored-by: noamd-legit <74864790+noamd-legit@users.noreply.github.com>
  • Loading branch information
derekmurawsky and noamd-legit authored Feb 8, 2023
1 parent a58ae91 commit ade77a9
Show file tree
Hide file tree
Showing 8 changed files with 318 additions and 264 deletions.
34 changes: 19 additions & 15 deletions policies/github/actions.rego
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package actions

# METADATA
# scope: rule
# title: GitHub Actions Is Not Restricted To Selected Repositories
# title: GitHub Actions Should Be Restricted To Selected Repositories
# description: By not limiting GitHub Actions to specific repositories, every user in the organization is able to run arbitrary workflows. This could enable malicious activity such as accessing organization secrets, crypto-mining, etc.
# custom:
# requiredEnrichers: [organizationId]
Expand All @@ -18,14 +18,15 @@ package actions
# - "5. Attacker receives all organization secrets and uses them maliciously"
# requiredScopes: [admin:org]
default all_repositories_can_run_github_actions = false

all_repositories_can_run_github_actions {
input.actions_permissions.enabled_repositories == "all"
input.actions_permissions.enabled_repositories == "all"
}

# METADATA
# scope: rule
# title: GitHub Actions Runs Are Not Limited To Verified Actions
# description: When using GitHub Actions, it is recommended to only use actions by Marketplace verified creators or explicitly trusted actions. By not restricting which actions are permitted allows your developers to use actions that were not audited and potentially malicious, thus exposing your pipeline to supply chain attacks.
# title: GitHub Actions Should Be Limited To Verified or Explicitly Trusted Actions
# description: It is recommended to only use GitHub Actions by Marketplace verified creators or explicitly trusted actions. By not restricting which actions are permitted, developers may use actions that were not audited and may be malicious, thus exposing your pipeline to supply chain attacks.
# custom:
# requiredEnrichers: [organizationId]
# remediationSteps: [Make sure you have admin permissions, Go to the org's settings page, Enter "Actions - General" tab, Under "Policies", 'Select "Allow enterprise, and select non-enterprise, actions and reusable workflows"', Check "Allow actions created by GitHub" and "Allow actions by Marketplace verified creators", Set any other used trusted actions under "Allow specified actions and reusable workflows", Click "Save"]
Expand All @@ -36,15 +37,16 @@ all_repositories_can_run_github_actions {
# - "1. Attacker creates a repository with a tempting but malicious custom GitHub Action"
# - "2. An innocent developer / DevOps engineer uses this malicious action"
# - "3. The malicious action has access to the developer repository and could steal its secrets or modify its content"
default all_github_actions_are_allowed = false
default all_github_actions_are_allowed = false

all_github_actions_are_allowed {
input.actions_permissions.allowed_actions == "all"
input.actions_permissions.allowed_actions == "all"
}

# METADATA
# scope: rule
# title: Default Workflow Token Permission Is Not Read Only
# description: Your default GitHub Action workflow token permission is set to read-write. When creating workflow tokens, it is highly recommended to follow the Principle of Least Privilege and force workflow authors to specify explicitly which permissions they need.
# title: Default Workflow Token Permission Should Be Read Only
# description: The default GitHub Action workflow token permission is set to read-write. When creating workflow tokens, it is highly recommended to follow the Principle of Least Privilege and force workflow authors to specify explicitly which permissions they need.
# custom:
# requiredEnrichers: [organizationId]
# remediationSteps:
Expand All @@ -57,15 +59,16 @@ all_github_actions_are_allowed {
# severity: MEDIUM
# requiredScopes: [admin:org]
# threat: In case of token compromise (due to a vulnerability or malicious third-party GitHub actions), an attacker can use this token to sabotage various assets in your CI/CD pipeline, such as packages, pull-requests, deployments, and more.
default token_default_permissions_is_read_write = false
default token_default_permissions_is_read_write = false

token_default_permissions_is_read_write {
input.token_permissions.default_workflow_permissions != "read"
input.token_permissions.default_workflow_permissions != "read"
}

# METADATA
# scope: rule
# title: Workflows Are Allowed To Approve Pull Requests
# description: Your default GitHub Actions configuration allows for workflows to approve pull requests. This could allow users to bypass code-review restrictions.
# title: Workflows Should Not Be Allowed To Approve Pull Requests
# description: The default GitHub Actions configuration allows for workflows to approve pull requests. This could allow users to bypass code-review restrictions.
# custom:
# requiredEnrichers: [organizationId]
# remediationSteps:
Expand All @@ -78,7 +81,8 @@ token_default_permissions_is_read_write {
# severity: HIGH
# requiredScopes: [admin:org]
# threat: Attackers can exploit this misconfiguration to bypass code-review restrictions by creating a workflow that approves their own pull request and then merging the pull request without anyone noticing, introducing malicious code that would go straight ahead to production.
default actions_can_approve_pull_requests = false
default actions_can_approve_pull_requests = false

actions_can_approve_pull_requests {
input.token_permissions.can_approve_pull_request_reviews
}
input.token_permissions.can_approve_pull_request_reviews
}
42 changes: 22 additions & 20 deletions policies/github/member.rego
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package member

# METADATA
# scope: rule
# title: Organization Has Too Many Owners
# description: Organization owners are highly privileged and could create great damage if being compromised, it's recommended to limit them to the minimum needed (recommended maximum 3 owners).
# title: Organization Should Have Fewer Than Three Owners
# description: Organization owners are highly privileged and could create great damage if they are compromised. It is recommended to limit the number of Organizational Admins to the minimum needed (recommended maximum 3 owners).
# custom:
# remediationSteps: [Make sure you have admin permissions, Go to the organization People page, Select the unwanted owners, Using the "X members selected" - change role to member]
# severity: MEDIUM
Expand All @@ -13,15 +13,16 @@ package member
# - "2. One of the developers has decided to collaborate with an evil ransomware gang, and uses his high privileges to add a malicious external collaborator"
# - "3. The malicious collaborator, being an owner, has a wide range of destructive operations he can do (e.g. remove security settings)"
default organization_has_too_many_admins = false

organization_has_too_many_admins {
admins := count({member | member := input.members[_]; member.is_admin == false})
admins > 3
admins := count({member | member := input.members[_]; member.is_admin == false})
admins > 3
}

# METADATA
# scope: rule
# title: Stale Member Found
# description: A member didn't do any action in the last 6 months. Stale members can pose a potential risk if they are compromised. Consider removing the user's access completely.
# title: Organization Members Should Have Activity In The Last 6 Months
# description: A member did not perform any action in the last 6 months. Stale members can pose a potential risk if they are compromised. Consider removing the user's access completely.
# custom:
# requiredEnrichers: [entityId, violatedUsers]
# remediationSteps: [Make sure you have admin permissions, Go to the org's People page, Select all stale members, Using the "X members selected" - remove members from organization]
Expand All @@ -31,17 +32,17 @@ organization_has_too_many_admins {
# threat:
# - "Stale members are most likely not managed and monitored, increasing the possibility of being compromised."
stale_member_found[mem] = true {
some member
mem := input.members[member]
mem.is_admin == false
isStale(mem.last_active, 6)
some member
mem := input.members[member]
mem.is_admin == false
isStale(mem.last_active, 6)
}

# METADATA
# scope: rule
# custom:
# title: Stale Admin Found
# description: A member with global admin permissions without any activity in the past 6 months. Admin users are extremely powerful and common compliance standards demand keeping the number of admins to a minimum. Consider revoking this member’s admin credentials by downgrading to regular user or removing the user completely.
# title: Organization Admins Should Have Activity In The Last 6 Months
# description: A member with organizational admin permissions did not perform any action in the last 6 months. Admin users are extremely powerful and common compliance standards demand keeping the number of admins to a minimum. Consider revoking this member’s admin credentials by downgrading to regular user or removing the user completely.
# custom:
# requiredEnrichers: [entityId, violatedUsers]
# remediationSteps: [Make sure you have admin permissions, Go to the org's People page, Select all stale admins, Using the "X members selected" - remove members from organization]
Expand All @@ -51,15 +52,16 @@ stale_member_found[mem] = true {
# threat:
# - "Stale admins are most likely not managed and monitored, increasing the possibility of being compromised."
stale_admin_found[mem] = true {
some member
mem := input.members[member]
mem.is_admin == true
isStale(mem.last_active, 6)
some member
mem := input.members[member]
mem.is_admin == true
isStale(mem.last_active, 6)
}

isStale(target_last_active, count_months) {
now := time.now_ns()
diff := time.diff(now, target_last_active)
# diff[1] the months index
diff[1] >= count_months
now := time.now_ns()
diff := time.diff(now, target_last_active)

# diff[1] the months index
diff[1] >= count_months
}
59 changes: 31 additions & 28 deletions policies/github/organization.rego
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import data.common.webhooks as webhookUtils

# METADATA
# scope: rule
# title: Webhook Configured Without A Secret
# description: Webhooks are not configured with an authenticated token to validate the origin of the request and could make your software vulnerable.
# title: Webhooks Should Be Configured With A Secret
# description: Webhooks are not configured with a shared secret to validate the origin and content of the request. This could allow your webhook to be triggered by any bad actor with the URL.
# custom:
# requiredEnrichers: [hooksList]
# severity: LOW
Expand All @@ -15,18 +15,18 @@ import data.common.webhooks as webhookUtils
# - "Not using a webhook secret makes the service receiving the webhook unable to determine the authenticity of the request."
# - "This allows attackers to masquerade as your organization, potentially creating an unstable or insecure state in other systems."
organization_webhook_no_secret[violated] = true {
some index
hook := input.hooks[index]
not webhookUtils.has_secret(hook)
violated := {
"name": hook.name,
"url": hook.url
}
some index
hook := input.hooks[index]
not webhookUtils.has_secret(hook)
violated := {
"name": hook.name,
"url": hook.url,
}
}

# METADATA
# scope: rule
# title: Webhook Configured Without SSL
# title: Webhooks Should Be Configured To Use SSL
# description: Webhooks that are not configured with SSL enabled could expose your software to man in the middle attacks (MITM).
# custom:
# requiredEnrichers: [hooksList]
Expand All @@ -37,19 +37,19 @@ organization_webhook_no_secret[violated] = true {
# - "If SSL verification is disabled, any party with access to the target DNS domain can masquerade as your designated payload URL, allowing it freely read and affect the response of any webhook request."
# - "In the case of GitHub Enterprise Server instances, it may be sufficient only to control the DNS configuration of the network where the instance is deployed, as an attacker can redirect traffic to the target domain in your internal network directly to them, and this is often much easier than compromising an internet-facing domain."
organization_webhook_doesnt_require_ssl[violated] = true {
some index
hook := input.hooks[index]
not webhookUtils.ssl_enabled(hook)
violated := {
"name": hook.name,
"url": hook.url
}
some index
hook := input.hooks[index]
not webhookUtils.ssl_enabled(hook)
violated := {
"name": hook.name,
"url": hook.url,
}
}

# METADATA
# scope: rule
# title: Two-Factor Authentication Is Not Enforced For The Organization
# description: The two-factor authentication requirement is not enabled at the organization level. Regardless of whether users are managed externally by SSO, it is highly recommended to enable this option, to reduce the risk of a deliberate or accidental user creation without MFA.
# title: Two-Factor Authentication Should Be Enforced For The Organization
# description: The two-factor authentication requirement is not enabled at the organization level. Regardless of whether users are managed externally by SSO, it is highly recommended to enable this option to reduce the risk of a deliberate or accidental user creation without MFA.
# custom:
# severity: HIGH
# remediationSteps: [Make sure you have admin permissions, Go to the organization settings page, Enter "Authentication security" tab, Under "Two-factor authentication", Toggle on "Require two-factor authentication for everyone in the <ORG> organization", Click "Save"]
Expand All @@ -59,27 +59,28 @@ organization_webhook_doesnt_require_ssl[violated] = true {
default two_factor_authentication_not_required_for_org = false

two_factor_authentication_not_required_for_org {
input.organization.two_factor_requirement_enabled == false
input.organization.two_factor_requirement_enabled == false
}

# METADATA
# scope: rule
# title: Non-Admins Can Create Public Repositories
# description: An organization allows non-admin members to create public repositories. Creating a public repository can be done by mistake, and may expose sensitive organization code, which, once exposed, may be copied, cached or stored by external parties. Therefore, it is highly recommended to restrict the option to create public repositories to admins only and reduce the risk of unintentional code exposure.
# title: Only Admins Should Be Able To Create Public Repositories
# description: The organization should be configured to prevent non-admin members creating public repositories. Creating a public repository may expose sensitive organization code, which, once exposed, may be copied, cached or stored by external parties. Therefore, it is highly recommended to restrict the option to create public repositories to admins only and reduce the risk of unintentional code exposure.
# custom:
# severity: MEDIUM
# remediationSteps: [Make sure you have admin permissions, Go to the organization settings page, Enter "Member privileges" tab, Under "Repository creation", Toggle off "Public", Click "Save"]
# requiredScopes: [read:org]
# threat:
# - "A member of the organization could inadvertently or maliciously make public an internal repository exposing confidential data."
default non_admins_can_create_public_repositories = false

non_admins_can_create_public_repositories {
input.organization.members_can_create_public_repositories == true
input.organization.members_can_create_public_repositories == true
}

# METADATA
# scope: rule
# title: Permissive Default Member Permissions Exist For New Repositories
# title: Default Member Permissions Should Be Restricted
# description: Default repository permissions configuration is not set in the organization, thus every new repository will be accessible by default to all users. It is strongly recommended to remove the default permissions and assign them on demand.
# custom:
# severity: HIGH
Expand All @@ -88,21 +89,23 @@ non_admins_can_create_public_repositories {
# threat:
# - "Organization members can see the content of freshly created repositories, even if they should be restricted."
default default_repository_permission_is_not_none = false

default_repository_permission_is_not_none {
input.organization.default_repository_permission != "none"
input.organization.default_repository_permission != "none"
}

# METADATA
# scope: rule
# custom:
# severity: MEDIUM
# title: Organization Not Using Single-Sign-On
# description: It is recommended to enable access to an organization via SAML single sign-on (SSO) by authenticating through an identity provider (IdP).
# title: Organization Should Use Single-Sign-On
# description: It is recommended to enable access to an organization via SAML single sign-on (SSO) by authenticating through an identity provider (IdP). This allows for central account control and for timely access revocations.
# custom:
# remediationSteps: [Make sure you have admin permissions, Go to the organization settings page, Enter "Authentication security" tab, Toggle on "Enable SAML authentication", Fill in the remaining SSO configuration as instructed on the screen, Click "Save"]
# requiredScopes: [admin:org]
# threat: Not using an SSO solution makes it more difficult to track a potentially compromised user's actions accross different systems, prevents the organization from defining a common password policy, and makes it challenging to audit different aspects of the user's behavior.
default organization_not_using_single_sign_on = false

organization_not_using_single_sign_on {
input.saml_enabled == false
input.saml_enabled == false
}
Loading

0 comments on commit ade77a9

Please sign in to comment.