Source control servers, build servers and artefact repositories are often run with default settings, open registration, old versions and broad network exposure, which hands attackers an easy way into the software supply chain. OWASP lists this as CICD-SEC-7 Insecure System Configuration in the Top 10 CI/CD Security Risks. This guide covers what the risk includes, the hardening flaws OWASP names, concrete settings for GitLab, Jenkins and GitHub, a phased hardening programme, how to assess and measure it, and how it maps to NIST, CIS, ISO and MITRE frameworks. It is for platform and DevOps engineers who run CI/CD systems, and for security teams who review them. It goes deeper than the Top 10 CI/CD Security Risks overview.
Key takeaways
- CI/CD systems are production systems. OWASP asks defenders to look at the posture of each system in the pipeline (SCM, CI, artefact repository), not only at the code flowing through it.
- Defaults are rarely secure. OWASP notes that default configurations often need optimisation, and its references include a Bitbucket server on default credentials and a GitLab server open for self-registration.
- Patch or isolate, nothing in between. If a vulnerable component cannot be patched, OWASP says remove it or restrict access and its ability to perform sensitive operations.
- SaaS moves the work, it does not remove it. Hosted CI/CD removes OS hardening, but each service has its own security settings that the customer must configure.
- Debug access is privileged access. Anyone who can debug an execution node can read secrets in memory and act as the node's identity.
What it is and who it applies to
OWASP defines insecure system configuration as risks stemming from flaws in the security settings, configuration and hardening of the systems across the pipeline, which often produce "low hanging fruits" for attackers who want to extend their foothold. The impact is serious: a flaw in one CI/CD system can give unauthorised access or full control of the underlying OS, and from there an attacker can manipulate legitimate flows, obtain sensitive tokens, reach production and move laterally outside the CI/CD context.
The risk applies to:
- Self-managed platforms: Jenkins, TeamCity, GitLab self-managed, Bitbucket Data Center, Nexus, Artifactory and self-hosted runners, where the organisation owns patching, OS and network as well as application settings.
- SaaS platforms: GitHub, GitLab.com, Bitbucket Cloud and hosted CI, where organisation policies, authentication, runner and integration settings remain the customer's responsibility.
- Shadow and legacy systems: a forgotten build server or test Git instance that no one patches is exactly the kind of system OWASP's references describe.
CICD-SEC-7 overlaps with OWASP CI/CD Top 10 CICD-SEC-2 Inadequate Identity and Access Management Guide (who can sign in) and OWASP CI/CD Top 10 CICD-SEC-6 Insufficient Credential Hygiene Guide (the secrets the systems hold). This guide focuses on the platform settings and hardening that sit underneath both.
Structure and key requirements
The OWASP entry lists five example hardening flaws, an impact statement, four recommendations and seven real-world references. The table pairs each flaw with a control and an incident that shows it.
| OWASP hardening flaw | Control | Illustrative incident |
|---|---|---|
| Outdated version or missing security patches | Inventory with owner, vulnerability monitoring, patch or remove or restrict | TeamCity CVE-2023-42793 exploited on internet-facing servers |
| Overly permissive network access | Least network access: no direct internet exposure for admin interfaces, allowlisted egress | Stack Overflow TeamCity server accessible from the internet (OWASP reference) |
| Self-hosted system with administrative permissions on the OS | Run services and agents as unprivileged users; no builds on the controller | TeamCity exploitation, where attackers dumped credentials from compromised build hosts |
| Insecure configuration of authorisation, access control and logging | Periodic configuration review against a hardened baseline | GitLab server open to self-registration |
| Inadequate credential hygiene in the system itself | Remove default accounts, restrict and expire programmatic tokens | Bitbucket server left on default credentials |
The four OWASP recommendations are: maintain an inventory of systems and versions with a designated owner and continuous vulnerability checks; align network access with least access; periodically review all security-relevant configuration; and grant permissions on pipeline execution nodes by least privilege, with particular care over debug permissions.
Hardening settings by platform
| Platform | Setting (as named by the vendor) | Hardened value |
|---|---|---|
| GitLab self-managed | Allow new user accounts | Cleared; if sign-up is needed, set Email confirmation settings to Hard and list Domains allowed for new users |
| GitLab self-managed | Two-factor authentication (2FA), Two-factor grace period | Enforced for all users, grace period reduced from the 48-hour default |
| GitLab self-managed | Default project, snippet and group visibility | Private |
| GitLab self-managed | Enable Admin Mode; Global-allowed IP ranges | Enabled; restricted to known address ranges |
| GitLab self-managed | Outbound requests; Enforce DNS rebinding attack protection | Allow only named hosts; enabled |
| GitLab self-managed | Push rules: Reject unverified users, Prevent pushing secret files | Selected |
| Jenkins | Security Realm and Authorization Strategy | External directory with Matrix-based security; never "Anyone can do anything" or "Logged-in users can do anything" |
| Jenkins | Built-in node executors (Manage Jenkins, Nodes and Clouds) | 0, with builds on agents |
| Jenkins | Agent to Controller Access Control | Always on since 2.326; Jenkins strongly recommends never disabling it on older versions |
| GitHub organisation | Actions policies: allowed actions and reusable workflows | Allow only selected or organisation-owned actions |
| GitHub organisation | Self-hosted runner access per repository; workflow permissions | Runners limited to named repositories; workflows not allowed to create or approve pull requests (the default for new organisations) |
Platform-specific depth is in the GitLab Security Guide, the Jenkins Security Guide and the GitHub and GitHub Actions Security Guide.
Identity and NHI requirements
CI/CD systems are hubs of machine identity. A build server holds tokens for source control, credentials for artefact registries, cloud deployment roles and sometimes signing keys, and the server itself runs under an OS service account and often an instance role. A configuration flaw therefore exposes many non-human identities at once.
- Default and built-in accounts: remove or disable default administrator accounts at installation and assign a named owner to every remaining privileged account. The Nissan source code leak came from a Bitbucket server still using admin/admin.
- Service accounts that run the platform: run controllers, agents and runners as dedicated unprivileged OS users. Jenkins advises running agents as a separate OS user with no access to the Jenkins home directory and no
sudo. - Programmatic tokens issued by the platform: limit who can create API and personal tokens, set expiry, and review tokens with administrative scope. See the GitLab Tokens Security Guide.
- Deploy keys: GitLab's hardening guidance says not to use public deploy keys and to use project deploy keys instead.
- Debug and shell access to runners: OWASP warns that any user who can access an execution node in debug mode can expose secrets loaded into memory and use the node's identity. Treat debug and SSH access to runners as privileged access with approval and logging.
- Instance roles: a self-hosted runner's cloud instance role is available to every job on the host. Keep it minimal and block metadata access from build containers where the platform allows it. See the CI/CD Pipeline Identity Security Guide.
Implementation steps
- Build the inventory. List every SCM, CI, artefact and runner system, including test and legacy instances, with version, hosting model, internet exposure, owner and the credentials it holds. External attack surface scans often find servers the inventory missed.
- Close internet exposure first. Put administrative and user interfaces of self-managed systems behind VPN or zero trust access, and keep only the endpoints that must be public (for example webhooks) reachable through a reverse proxy with an allowlist.
- Patch to a supported version and set a patch SLA. Subscribe to vendor security advisories and check components against the CISA Known Exploited Vulnerabilities Catalog. For a known exploited CI/CD flaw, patch or isolate within days. Where no fix exists, follow OWASP: remove the component or restrict access and sensitive operations.
- Apply a hardened baseline. Write the baseline per platform (the settings table above is a starting point), apply it as code where the platform allows (Jenkins Configuration as Code, GitLab application settings API, GitHub organisation policies through Terraform or the API), and record approved exceptions.
- Remove privilege from the platform itself. Set Jenkins built-in node executors to 0, run agents and runners as unprivileged users, avoid mounting the Docker socket into jobs, and use ephemeral runners rebuilt for each job where possible.
- Lock down authentication and registration. SSO with MFA for all users, open registration disabled, Admin Mode or equivalent step-up for administrators, password-based Git access removed where SSH keys or tokens can replace it.
- Review configuration on a schedule. Compare live settings against the baseline monthly, and after every upgrade, because upgrades can introduce new settings with permissive defaults.
- Test and roll back safely. Apply changes to a staging instance first, then to production during a change window with a configuration backup. For settings that may break pipelines (agent permissions, network egress), run in a pilot group of projects before the whole estate.
Choosing between self-managed and SaaS
- SaaS fits when: the team is small, there is no dedicated platform engineering, and there is no hard requirement for on-premises source code. Hardening work then concentrates on organisation policies, SSO, runner settings and integrations.
- Self-managed fits when: regulation or air-gapped networks require it and a team can commit to patching within days. Without that commitment, a self-managed CI server becomes the outdated, internet-facing system in OWASP's examples.
- Hybrid (SaaS control plane, self-hosted runners): common for access to private networks; the runners then carry the OS hardening and network duties. GitHub advises that self-hosted runners should almost never be used for public repositories.
Evidence and assessment
An assessment should show that every CI/CD system is known, owned, patched, not needlessly exposed and configured to a baseline. Evidence includes the system inventory, vulnerability scan results, configuration-as-code repositories or settings exports, network diagrams or firewall rules, and access reviews for administrators and runner debug access.
| Metric | How to measure | Target direction |
|---|---|---|
| CI/CD systems with a named owner | Inventory entries with an owner divided by all entries | 100 percent |
| Patch latency for critical CI/CD vulnerabilities | Days from vendor advisory to patched or isolated | Within the SLA, days not weeks for known exploited flaws |
| Internet-exposed administrative interfaces | External scan and cloud security group review | Zero |
| Baseline drift | Settings that differ from the approved baseline at each review | Falling, every exception approved |
| Builds running on controllers or with root on the host | Executor and runner configuration review | Zero |
| Users with runner debug or shell access | Access review count | Small, named and reviewed quarterly |
Detection: log and alert on administrative setting changes, new user registrations, new administrators, new tokens with admin scope, new self-hosted runners, plugin installs, and authentication from unusual networks. On self-managed hosts, watch for credential dumping and new scheduled tasks; the joint advisory on the TeamCity CVE-2023-42793 exploitation describes attackers dumping registry hives and planting backdoors on build servers.
Mapping to other frameworks
| Framework | Reference | Relevance to CICD-SEC-7 |
|---|---|---|
| NIST CSF 2.0 | ID.AM-02, ID.RA-01, PR.PS-01, PR.PS-02, DE.CM-09 | Inventory of systems; vulnerabilities identified; configuration management; software maintained; monitoring of runtime environments |
| NIST SP 800-53 Rev. 5 | CM-2, CM-6, CM-7, CM-8, SI-2, RA-5, SC-7, AC-6 | Baseline, settings, least functionality, component inventory, flaw remediation, scanning, boundary protection, least privilege |
| CIS Controls v8.1 | Control 1 and 2 (inventory), Control 4 Secure Configuration of Enterprise Assets and Software, Control 7 Continuous Vulnerability Management, Control 12 Network Infrastructure Management | Know, harden, patch and segment CI/CD systems |
| ISO/IEC 27001:2022 Annex A | 8.8 Management of technical vulnerabilities, 8.9 Configuration management, 8.20 Networks security, 8.4 Access to source code | Patching, baselines, network controls, repository protection |
| MITRE ATT&CK | T1190 Exploit Public-Facing Application, T1078.001 Default Accounts, T1133 External Remote Services, T1213.003 Code Repositories, T1195.002 Compromise Software Supply Chain | Initial access to CI/CD systems and what follows |
| MITRE D3FEND | D3-CI Configuration Inventory, D3-SU Software Update | Defensive techniques behind inventory and patching |
The CISA and NSA Cybersecurity Information Sheet "Defending Continuous Integration/Continuous Delivery (CI/CD) Environments" covers the same ground from a government perspective and is a useful companion.
Common pitfalls
- Open registration on internal code platforms. In the Mercedes-Benz source code leak, a GitLab server allowed self-registration without email verification, and an outsider cloned more than 580 repositories.
- Default credentials left in place. The Nissan leak shows how one unchanged admin/admin login on an internet-facing Bitbucket server exposed about 20GB of source code.
- A forgotten authentication path. In the PHP Git server compromise, maintainers concluded the malicious pushes used HTTPS password authentication that bypassed the key-based access layer. Inventory every protocol that can write to a repository.
- Slow patching of internet-facing build servers. Unpatched, exposed TeamCity servers were compromised after CVE-2023-42793; the advisory found victims had little in common beyond running such a server.
- Public CI pages. The Homebrew token exposure came from a publicly reachable Jenkins instance. Anonymous read access to a CI server is a configuration finding.
- Assuming SaaS is hardened by default. OWASP is explicit that SaaS CI/CD still needs diligent configuration; permissive Actions policies and runner access settings are customer choices.
Practitioner checklist
- Inventory every SCM, CI, artefact and runner system with version, owner and exposure, including test and legacy instances.
- Remove direct internet access to administrative interfaces of self-managed CI/CD systems.
- Set and track a patch SLA, with days for known exploited CI/CD vulnerabilities.
- Write a hardened baseline per platform and apply it as code where possible.
- Disable open registration and default accounts; enforce SSO and MFA for all users.
- Run no builds on controllers; run agents and runners as unprivileged, ideally ephemeral, hosts.
- Treat runner debug and shell access as privileged access with approval and logging.
- Restrict allowed actions, plugins and integrations to an approved list.
- Review live configuration against the baseline monthly and after each upgrade.
- Alert on administrative setting changes, new administrators, new runners and new admin tokens.
Standards and references
- OWASP: CICD-SEC-7 Insecure System Configuration
- OWASP: Top 10 CI/CD Security Risks
- CISA: CISA and NSA Release Joint Guidance on Defending CI/CD Environments
- GitLab Docs: Hardening application settings
- Jenkins: Controller Isolation
- Jenkins: Securing Jenkins
- GitHub Docs: Disabling or limiting GitHub Actions for your organization
- GitHub Docs: Secure use reference for GitHub Actions
Related NHI Mgmt Group resources: Top 10 CI/CD Security Risks · CI/CD Security Guide · Jenkins Security Guide · GitLab Security Guide · OWASP CI/CD Top 10 CICD-SEC-6 Insufficient Credential Hygiene Guide