Framework/Configurations/SVT/ADO/ADO.Build.json
{
"FeatureName": "Build", "Reference": "aka.ms/azsktcp/Build", "IsMaintenanceMode": false, "Controls": [ { "ControlID": "ADO_Build_DP_No_PlainText_Secrets_In_Definition", "Description": "Secrets and keys must not be stored as plain text in build variables/task parameters.", "Id": "Build120", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckCredInBuildVariables", "Rationale": "Keeping secrets such as connection strings, passwords, keys, etc. in plain text can expose the credentials to a wider audience and can lead to credential theft. Marking them as secret protects them from unitended disclosure and/or misuse.", "Recommendation": "Refer: https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=vsts&tabs=yaml%2Cbatch#secret-variables", "Tags": [ "SDL", "TCP", "Automated", "DP" ], "Enabled": true }, { "ControlID": "ADO_Build_Config_Add_Static_Code_Analyzer", "Description": "Consider adding static code analysis step in your pipelines.", "Id": "Build130", "ControlSeverity": "High", "Automated": "No", "MethodName": "", "Rationale": "Static code analyzers ensure that many kinds of security vulnerabilities are detected in early stages of software/service development.", "Recommendation": "Refer: https://docs.microsoft.com/en-us/azure/devops/articles/security-validation-cicd-pipeline?view=vsts#ci-continuous-integration", "Tags": [ "SDL", "TCP", "Manual", "Config" ], "Enabled": true }, { "ControlID": "ADO_Build_DP_Store_SecretFiles_in_Secure_Library", "Description": "Secure Files library must be used to store secret files such as signing certificates, Apple Provisioning Profiles, Android KeyStore files, and SSH keys", "Id": "Build140", "ControlSeverity": "Medium", "Automated": "No", "MethodName": "", "Rationale": "The contents of the secure files are encrypted and can only be used during the build or release pipeline by referencing them from a task.", "Recommendation": "Refer https://docs.microsoft.com/en-us/azure/devops/pipelines/library/secure-files?view=vsts", "Tags": [ "SDL", "TCP", "Manual", "DP" ], "Enabled": true }, { "ControlID": "ADO_Build_DP_Review_Inactive_Build", "Description": "Inactive build pipelines must be removed if no more required.", "Id": "Build150", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckForInactiveBuilds", "Rationale": "Each additional build having access to repositories increases the attack surface. To minimize this risk ensure that only active and legitimate build pipelines are present in your environment.", "Recommendation": "Steps to remove inactive build pipelines : 1.Navigate to the build pipeline. --> 2. Select a build pipeline. --> 3. Select three dots (present at right top). --> 4. Click on Delete.", "Tags": [ "SDL", "Best Practice", "Automated", "DP", "AutomatedFix" ], "Enabled": true }, { "ControlID": "ADO_Build_AuthZ_Disable_Inherited_Permissions", "Description": "Do not allow inherited permission on build definitions.", "Id": "Build160", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckInheritedPermissions", "Rationale": "Disabling inherited permissions lets you finely control access to various operations at the build level for different stakeholders. This ensures that you follow the principle of least privilege and provide access only to the persons that require it.", "Recommendation": "To disable inheritance follow the steps given here: 1.Navigate to the build pipeline. 2. Select three dots (present at right top). 3. Click Manage Security 4. Add the service lead & service owner as Users with Allow permissions for each permission line item. 5. Disable Inheritance. 6. Add users/groups to your build definition and provide only required access. As best practice, All teams/groups must be granted minimum required permissions on build definition.", "Tags": [ "SDL", "TCP", "Automated", "AuthZ" ], "Enabled": true }, { "ControlID": "ADO_Build_SI_Review_Variables_Settable_At_Queue_Time", "Description": "Pipeline variables marked settable at queue time should be carefully reviewed.", "Id": "Build170", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckSettableAtQueueTime", "Rationale": "Pipeline variables that are marked settable at queue time can be changed by anyone who can queue a build. Such variables can be misused for code injection/data theft attacks from pipelines.", "Recommendation": "1. Navigate to the build pipeline. --> 2. Click on Edit. --> 3. Select variables. --> 4. For classic pipeline Uncheck 'settable at queue time' whereas for YAML pipeline uncheck 'Let users override this value when running this pipeline' for such variables --> 5. Save the build pipeline.", "Tags": [ "SDL", "TCP", "Automated", "SI" ], "Enabled": true }, { "ControlID": "ADO_Build_SI_Review_URL_Variables_Settable_At_Queue_Time", "Description": "Pipeline variables marked settable at queue time and containing URLs should be avoided.", "Id": "Build180", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckSettableAtQueueTimeForURL", "Rationale": "Pipeline variables that are marked settable at queue time can be changed by anyone who can queue a build. If these variables contain a URL then someone can change the URL to a server that they control and can intercept any secrets used to interact with the intended server by queueing a build.", "Recommendation": "1. Navigate to the build pipeline. --> 2. Click on Edit. --> 3. Select variables. --> 4. For classic pipeline Uncheck 'settable at queue time' whereas for YAML pipelines uncheck 'Let users override this value when running this pipeline' for such variables --> 5. Save the build pipeline.", "Tags": [ "SDL", "TCP", "Automated", "SI", "AutomatedFix" ], "Enabled": true }, { "ControlID": "ADO_Build_SI_Review_External_Sources", "Description": "Review external source code repositories before adding them to your pipeline.", "Id": "Build190", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckExternalSources", "Rationale": "Building code from untrusted external sources can allow an attacker to execute arbitrary code in your pipeline. Hence, all repositories added to the pipeline should be carefully reviewed.", "Recommendation": "Validate the external source code repository used in the pipeline definition for vulnerabilities.", "Tags": [ "SDL", "TCP", "Automated", "SI" ], "Enabled": true }, { "ControlID": "ADO_Build_SI_Dont_Use_Broadly_Editable_Task_Group", "Description": "Builds should not use task groups that are editable by a broad pool of users.", "Id": "Build200", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckTaskGroupEditPermission", "Rationale": "If a broad pool of users (e.g., Contributors) have edit permissions on a task group, then integrity of your pipeline can be compromised by a malicious user who edits the task group.", "Recommendation": "1. Navigate to the build pipeline. --> 2. Click on Tasks. --> 3. Right click on each task group and select 'Manage task group'. --> 4. Select 'Security' for the task group. --> 5. Ensure 'Edit task group' permission of Contributors is not set to 'Allow'. --> 6. Repeat this for any other groups that should not have edit access.", "Tags": [ "SDL", "TCP", "Automated", "SI", "MSW", "SkipYAML", "AutomatedFix" ], "Enabled": true }, { "ControlID": "ADO_Build_SI_Dont_Use_Broadly_Editable_Variable_Group", "Description": "Do not use variable groups that are editable by a broad group of users.", "Id": "Build210", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckVariableGroupEditPermission", "Rationale": "If a broad group of users (e.g., Contributors) have edit permissions on a variable group, then integrity of your pipeline can be compromised by a malicious user who edits the variable group.", "Recommendation": "1. Navigate to the build pipeline. --> 2. Click on Variables. --> 3. Click on each variable groups used in the pipeline. --> 4. Select 'Security' for the variable group. --> 5. Ensure Contributors have only reader access to the variable group. --> 6. Repeat this for any other groups that should not have edit access. ", "Tags": [ "SDL", "TCP", "Automated", "SI", "MSW", "AutomatedFix" ], "Enabled": true }, { "ControlID": "ADO_Build_AuthZ_Limit_Pipeline_Access", "Description": "Limit scope of access for build pipeline to the current project.", "Id": "Build220", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckBuildAuthZScope", "Rationale": "If pipelines use project collection level tokens, a vulnerability in components used by one project can be leveraged by an attacker to attack all other projects. This is also in keeping with the principle of least privilege.", "Recommendation": "1. Navigate to the build pipeline. --> 2. Click on Options. --> 3. Set 'Build job authorization scope' to 'Current Project'.", "Tags": [ "SDL", "TCP", "Automated", "AuthZ", "SkipYAML", "AutomatedFix" ], "Enabled": true }, { "ControlID": "ADO_Build_AuthZ_Restrict_Broader_Group_Access", "Description": "Do not allow build pipeline to have excessive permissions by a broad group of users.", "Id": "Build230", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckBroaderGroupAccess", "Rationale": "If a broad group of users (e.g., Contributors) have excessive permissions on a pipeline, a malicious user can abuse these permissions to compromise security of the pipeline.", "Recommendation": "1. Navigate to the build pipeline. --> 2. Click on Security. --> 3. Ensure 'Excessive' permissions of broader groups is not set to 'Allow'. Refer to detailed scan log (Build.LOG) for broader groups and excessive permissions list. --> 4. Repeat this for any other groups that should not have excessive permissions.", "Tags": [ "SDL", "TCP", "Automated", "AuthZ", "MSW", "AutomatedFix" ], "Enabled": true }, { "ControlID": "ADO_Build_DP_Dont_Make_Secrets_Available_To_Forked_Builds", "Description": "Do not make secrets available to builds for fork of public repository.", "Id": "Build240", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckForkedBuildTrigger", "Rationale": "For GitHub public repositories, it is possible that people from outside the organization can create forks and run builds on the forked repo. In such a case, if this setting is wrongly left enabled, outsiders can get access to build pipeline secrets that were meant to be internal.", "Recommendation": "1. Navigate to the build pipeline using resource link --> 2. Triggers --> 3. Pull request validation --> 4. Forks --> 5. Uncheck 'Make secrets available to builds of forks'.", "Tags": [ "SDL", "TCP", "Automated", "DP", "MSW", "AutomatedFix" ], "Enabled": true }, { "ControlID": "ADO_Build_DP_Do_Not_Use_Forked_Repo_With_Self_Hosted_Agent", "Description": "Do not allow build pipeline to build code from forked repository on self-hosted agent.", "Id": "Build250", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckForkedRepoOnSHAgent", "Rationale": "If you use GitHub open-source projects, anyone with a GitHub account can fork your repository and propose contributions back. Since pipelines are associated with a repository and not with specific branches, you must assume the code and YAML files are untrusted. (https://docs.microsoft.com/en-us/azure/devops/pipelines/security/repos?view=azure-devops)", "Recommendation": "1. Navigate to build pipeline definition --> 2. Ensure the pipeline does not build code from a forked repository. --> 3. Ensure the pipeline doesn't build code on a self-hosted agent.", "Tags": [ "SDL", "TCP", "Automated", "DP" ], "Enabled": true }, { "ControlID": "ADO_Build_DP_Disable_CI_On_External_Sources", "Description": "Do not run continuous integration or scheduled builds on untrusted code from external or public GitHub repositories.", "Id": "Build260", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckCIScheduledBuildTrigger", "Rationale": "Build agents posess a token scoped to either current project or project collection. This token is available to builds triggered via the Continuous Integration and Scheduled Build mechanisms. If an adversary pushed a malicious commit to the upstream public GitHub repo, they can exfiltrate the token and use it to move laterally throughout the ADO organization (or Project).", "Recommendation": "1. Navigate to the build pipeline. -> 2. Triggers -> 3. Disable 'Continuous integration' and 'Scheduled' build.", "Tags": [ "SDL", "TCP", "Automated", "DP" ], "Enabled": true }, { "ControlID": "ADO_Build_AuthZ_Restrict_Access_To_OAuth_Token_For_Agent_Jobs", "Description": "Do not allow agent jobs to access OAuth token unless explicitly required.", "Id": "Build270", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckAccessToOAuthToken", "Rationale": "Malicious task or extensions can use Oauth access token for stealing project details like builds,releases,agent pools etc.", "Recommendation": "For classic pipeline: 1. Navigate to the build pipeline --> 2. Edit the pipeline --> 3. Go to Agent Job (Run on Agent) --> 4. Disable the field 'Allow scripts to access the OAuth token'. For YAML pipeline: Do not use System.AccessToken variable. ", "Tags": [ "SDL", "TCP", "Automated", "DP" ], "Enabled": true }, { "ControlID": "ADO_Build_DP_Configure_YAML_CI_Triggers", "Description": "Use CI triggers to allow YAML CI only from select branches.", "Id": "Build280", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckYAMLCITrigger", "Rationale": "If YAML CI is enabled, malicious users having contribute/'create branch' access to the repository belonging to YAML file of the pipline, will be able to push malicious code and trigger the pipeline from the corrupted branch even if they do not have the permission to queue the pipeline. This will enable them to bypass user permissions to access all protected resources this pipeline has access to. To avoid exposure to the risk, one should enable CI only on select branches.", "Recommendation": "1. Navigate to the build pipeline --> 2. Go to 'Edit' --> 3. Click on 'Triggers' from the three dots on upper right corner --> 4. Click on 'Override the YAML continuous integration trigger from here'. Add only protected branches in the branch filter.", "Tags": [ "SDL", "TCP", "Automated", "DP", "SkipClassic" ], "Enabled": true }, { "ControlID": "ADO_Build_DP_Verify_Default_Branch", "Description": "Default branch in YAML pipeline should always be protected", "Id": "Build290", "ControlSeverity": "Medium", "Automated": "Yes", "MethodName": "CheckYAMLDefaultBranch", "Rationale": "The YAML pipeline content in the default branch is used to determine the pipeline definition in case of scheduled runs and repository trigger runs. If the default branch is not protected, malicious users can push changes to this branch, edit the pipeline and access all resources the pipeline has access to. To prevent this, ensure that the default branch has branch protection policies enabled.", "Recommendation": "1. Navigate to project settings --> 2. Select 'Repositories' under 'Repos' --> 3. Select the repository which has YAML file --> 4. From the 'Policies' tab select the branch which is the default branch in the pipeline from 'Branch Policies' --> 5. Enable any branch policy suitable according to your use case.", "Tags": [ "SDL", "TCP", "Automated", "DP", "SkipClassic" ], "Enabled": true } ] } |