Join our Newsletter — 33% off our NHI Course
Home› Guides› D3-CS Credential Scrubbing: Removing Hard-Coded Secrets From Code…
Guide Authentication

D3-CS Credential Scrubbing: Removing Hard-Coded Secrets From Code and Proving It

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 12 November 2026 12 min read
On this page

A password, API key or private key written into source code is copied to every clone, fork, build artefact and backup of that code, and it stays in version control history after someone deletes the line. MITRE D3FEND names the countermeasure Credential Scrubbing (D3-CS) and defines it as "The systematic removal of hard-coded credentials from source code to prevent accidental exposure and unauthorized access." It sits under the Harden tactic as a child of Source Code Hardening, next to techniques such as Pointer Validation and Variable Initialization. This card covers what D3FEND says, how thin its ATT&CK mapping is, how scrubbing is done in practice, how to prove a codebase is clean, and where the control fails. It is written for application security engineers, platform teams and secrets owners; the wider programme is in the Secrets Management Guide.

Key takeaways

  • Scrubbing means revoke, replace, then remove. D3FEND's own considerations say credentials found in version control history must be disabled and replaced promptly; deleting the line or rewriting history without revoking leaves the secret valid in every existing copy.
  • D3FEND's ATT&CK link is thin. The ontology only says D3-CS hardens a Subroutine, and the D3FEND site infers a single related technique from that, T1505.001 SQL Stored Procedures. The real attacker behaviour it addresses is credential harvesting from code, which ATT&CK covers as T1552.001 Credentials In Files.
  • Prevention beats clean-up. Pre-commit hooks and server-side push protection stop new secrets; history scanning finds the old ones. Both are needed.
  • The replacement matters as much as the removal. Moving a key from code to a plaintext environment file in the same repository is not scrubbing. The credential has to come from a secrets manager or, better, be replaced by a federated identity with no static secret.
  • Verification is a scan result, not a policy. A codebase is scrubbed when a full-history scan with agreed rules returns no live findings, and every finding has a recorded revocation.

D3-CS at a glance

AttributeValue
D3FEND IDD3-CS (d3f:CredentialScrubbing)
TacticHarden
Parent techniqueSource Code Hardening (siblings: Domain Logic Validation, Integer Range Validation, Pointer Validation, Reference Nullification, Trusted Library, Variable Initialization, Variable Type Validation)
Digital artefactSubroutine (D3FEND relation: hardens Subroutine)
Weakness it addressesCWE-798 Use of Hard-coded Credentials (D3FEND see-also)
Attack pattern it addressesCAPEC-191 Read Sensitive Constants Within an Executable (D3FEND see-also)
D3FEND referenceOWASP Secrets Management Cheat Sheet
What it changesCredentials move out of source, configuration in the repository and compiled binaries into a managed store or are replaced by workload identity
Main limitationDoes nothing for credentials already copied out of the repository unless they are revoked

How it works

D3FEND's knowledge base article describes the technique in two sentences: identify and eliminate hard-coded credentials such as usernames, passwords, API keys and tokens from source code repositories, and manage them through environment variables, secret management tools or secure vaults instead. Its considerations add three practical points: audit source code regularly, disable and replace credentials found in version control history promptly, and back the change with role-based access control and rotation.

CWE-798 explains why the problem is wider than leakage. MITRE splits hard-coded credentials into two variants:

  • Inbound: the product checks incoming logins against a credential built into the code, often a default administrator account that is identical across every installation and cannot be changed without a patch. Anyone who reads one copy of the code or binary can log in to every deployment.
  • Outbound: the product embeds the credential it uses to reach another system, such as a database, a cloud API or a back-end service. Anyone who reads the code inherits that access.

CAPEC-191 describes the attacker side: searching a compiled program for passwords, keys and cryptographic constants with string extraction, disassembly or decompilation. That matters because a secret removed from today's source can still sit in last year's container image, mobile app build or installer.

D3FEND's choice of Subroutine as the artefact reflects that the credential lives inside code units. It also explains the single inferred ATT&CK relation discussed below.

Where identity fits

Almost every credential found in code belongs to a non-human identity: a service account password, a cloud access key, a database user, a webhook token or an application client secret. Scrubbing is therefore an NHI lifecycle event. Each finding should be traced to the identity that owns it, so the owner can be asked to rotate, the identity's permissions can be reviewed, and the identity can be retired if the code no longer needs it. The hardest finding to close is an orphaned key with no owner, which is why scrubbing works best alongside an NHI inventory.

ATT&CK techniques and D3-CS

Relationship type: inferred only. The D3FEND ontology gives D3-CS no direct ATT&CK mapping. The D3FEND site (knowledge graph 1.6.0, checked November 2026) infers one related technique through the shared Subroutine artefact and labels such relations "inferred and experimental".

ATT&CK IDTechniqueSource of the relationHow it relates to scrubbing
T1505.001SQL Stored ProceduresD3FEND inferred, via SubroutineWeak. A stored procedure is a subroutine an attacker adds for persistence; scrubbing does not stop that. The shared artefact, not shared purpose, creates the link
T1552.001Credentials In FilesNHI Mgmt Group view, not a D3FEND mappingThe direct target: adversaries search local files and shared file systems, including source and configuration files, for stored credentials
T1213.003Code RepositoriesNHI Mgmt Group view, not a D3FEND mappingAdversaries collect data from code repositories; hard-coded secrets make that collection an access path
T1078Valid AccountsNHI Mgmt Group view, not a D3FEND mappingThe follow-on step when a harvested secret is used to authenticate

For the attacker view of the harvesting step, see the MITRE ATT&CK T1552 Unsecured Credentials Guide. The ATT&CK mitigation that carries the same developer intent is covered in M1013 Application Developer Guidance; D3FEND notes against M1013 that a future release will define a taxonomy of Source Code Hardening techniques.

Where it is implemented

Implementation classWhat it doesWhere it actsLimits
Pre-commit and IDE scanningBlocks a commit locally when a secret pattern matches. Gitleaks, for example, supports the pre-commit framework and a gitleaks:allow line commentDeveloper workstationDevelopers can skip local hooks; it only sees new changes
Server-side push protectionRejects a push that contains a recognised secret. GitHub push protection covers command line pushes, web UI commits, file uploads and REST API requestsSource control platformWriters can bypass with a reason; coverage depends on the pattern type and the provider
History and CI scanningScans the full commit history, branches and pull requests; can use a baseline so only new findings fail the buildCI pipeline, scheduled jobsA baseline hides old findings unless someone works through them
Artefact and image scanningSearches built images, packages and binaries for embedded credentials, the CAPEC-191 pathRegistry, release pipelineObfuscated or encrypted constants are hard to detect
Secrets manager and runtime injectionSupplies the replacement credential at run time through a mounted file, a sidecar or the platformRuntimeNeeds the application changed to read it
Workload identity federationRemoves the static credential entirely; the workload proves its identity with a short-lived platform tokenCloud and CI platformsNot every target system supports it

The OWASP Secrets Management Cheat Sheet, D3FEND's reference, recommends running more than one detection tool and correlating results, using one standard test secret per type to cut false positives, and building signatures for connection strings, API keys, private keys, session tokens and cloud credentials. On injection it prefers orchestrator-mounted files or a sidecar that fetches from a secrets manager, and advises against environment variables unless nothing else is possible, because they are visible to all processes and appear in logs and dumps. Platform specifics are in the Git Secret Scanning Guide and How to enable GitHub secret scanning push protection.

Implementation steps

  1. Stop the inflow first. Turn on server-side push protection for all repositories and offer a pre-commit hook. Restrict who may bypass (GitHub's delegated bypass is one way) and route bypass alerts to the security team.
  2. Baseline the history. Run a full-history scan of every repository, including archived ones and forks you control, with the same rule set. Save the result as the baseline so CI fails only on new findings while the backlog is worked.
  3. Triage by live access. For each finding, decide whether the credential is still valid and what it can reach. Live production credentials go first, test fixtures last.
  4. Revoke and replace. Follow the OWASP order: revoke, rotate, then delete. Issue the replacement through the secrets manager or switch the workload to federation, deploy, and confirm the old credential no longer authenticates.
  5. Remove it from the code. Change the code to read the credential at run time. Rewrite history only when the exposure itself is the risk, such as personal data or a secret that cannot be rotated. GitHub's documentation recommends git-filter-repo 2.47 or later with its --sensitive-data-removal option and warns that existing clones and forks keep the old commits; see How to Remove Secrets From Git History.
  6. Fix the inbound variant. For products that ship a built-in login, replace it with a first-use setup that forces a unique credential, as CWE-798 recommends.
  7. Roll back safely. Keep the old credential disabled rather than deleted for a short window (for example seven days, an NHI Mgmt Group suggestion, not a standard) so a missed consumer can be found from its failed authentications and moved before final deletion.

How to verify it works

  • Full-history scan: a scheduled scan of all repositories and all branches returns no unresolved findings outside approved test secrets.
  • Revocation proof: for every closed finding, the record shows the revocation date and a failed authentication test with the old value.
  • Seeded test: push an approved canary secret format to a test repository and confirm push protection blocks it and the bypass path raises an alert.
  • Artefact scan: scan current release images and binaries, not only source, to confirm old builds are not still shipping a credential.
  • Bypass review: review push protection bypasses monthly; "I'll fix it later" bypasses leave an open alert on GitHub and should be tracked to closure.
MetricExample target (NHI Mgmt Group suggestion, not a standard)Why it matters
Repositories covered by push protection100% of active repositoriesShows the inflow is controlled
Median time from finding to revocation for live credentialsUnder 24 hoursExposure time is the risk, not the code change
Open baseline findingsFalling every monthShows the historical backlog is being worked, not hidden
Push protection bypasses later confirmed as real secretsTracked and trending downShows whether bypass rights are used responsibly
Findings with an identified owning identityClose to 100%Unowned keys cannot be rotated safely

Limits, bypasses and failure patterns

  • Deleting the line and calling it fixed: the secret remains in history, clones, forks and CI logs. The Toyota T-Connect Key Exposure 2022 involved an access key that sat in public source code for about five years; only revocation ends that kind of exposure.
  • Private repository complacency: scrubbing is often scoped to public code. The Uber Breach 2016 began with an AWS key in a private repository.
  • Moving the secret next door: replacing a literal with an .env file or a CI variable file committed to the same repository changes nothing. See Environment Variables and .env Files.
  • Pattern blind spots: scanners find structured keys well and human-chosen passwords poorly. OWASP warns about balancing entropy against known formats; GitHub lists AI-detected generic secrets as a public preview feature.
  • Allowlist creep: inline allow comments and ignore files added to unblock a build become permanent exceptions. Review them like any other exception.
  • Binaries left behind: CAPEC-191 shows attackers read constants from compiled code. Old mobile builds, installers and images keep the credential after the source is clean.

Framework mapping

FrameworkReferenceRelevance
NIST SP 800-53 Rev 5IA-5(7) No Embedded Unencrypted Static AuthenticatorsThe control that directly prohibits credentials embedded in applications and scripts
NIST SP 800-53 Rev 5IA-5 Authenticator Management, SA-11 Developer Testing and Evaluation, SA-15 Development Process, Standards, and ToolsRotation of replaced credentials; secret scanning as a developer test and tooling requirement
NIST CSF 2.0PR.AA-01, PR.PS-06Managing credentials for services; secure software development practice
OWASP ASVS 5.0V13.3.1, V13.3.2, V13.3.4Backend secrets held in a secrets management solution, least privilege access to them, expiry and rotation
ISO/IEC 27001:2022 Annex AA.8.28 Secure coding, A.5.17 Authentication informationSecure coding practice and handling of authentication information
MITRECWE-798, CAPEC-191, D3-CSWeakness, attack pattern and countermeasure

Practitioner checklist

  • Enable server-side push protection on every active repository and limit who can bypass.
  • Run a full-history scan of all repositories, including archived ones, and keep the baseline.
  • Revoke and replace every live finding before touching history.
  • Record the owning identity, revocation date and failed-authentication test for each finding.
  • Replace static credentials with workload identity federation where the target supports it.
  • Scan release images, packages and binaries, not only source.
  • Replace built-in default logins with a forced first-use credential.
  • Review allowlist entries and bypasses monthly.

Standards and references

Related NHI Mgmt Group resources: Secrets Management Guide · Git Secret Scanning Guide · How to Remove Secrets From Git History · MITRE ATT&CK T1552 Unsecured Credentials Guide · MITRE D3FEND Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 12 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org