Skip to main content

Credential finding · Software and cloud

Hardcoded Credentials (CWE-798): Rotate, Remove, or Document

Your scanner found hardcoded credentials (CWE-798). Why deleting the line isn't enough, and how to rotate, move the key to a vault, and keep it out of code.

What the scanner said

Use of Hard-coded CredentialsCWE-798Hard-coded credentials are security-sensitiveHardcoded secretsSecret scanning alert

Your scanner found a password, API key, token, or private key written directly into source code, a configuration file, a container image, or a CI setting. SonarQube reports it as Hard-coded credentials are security-sensitive (rule S2068), secret scanners such as Gitleaks and GitHub secret scanning flag the matching strings, and the weakness is CWE-798, Use of Hard-coded Credentials, which falls under A07 Authentication Failures in the OWASP Top 10:2025. Anyone who can read the code, its history, or the built artifact can use the key, and it usually stays valid long after the line is deleted.

Why it matters

Deleting the line doesn't take the key back. Git keeps every version, build artifacts and container images keep their own copies, and anyone who cloned or forked the repository has one too. A 2025 industry study of secrets in source code counted 23.8 million new secrets added to public GitHub repositories in 2024, and found that 70% of the secrets leaked in 2022 were still valid. Attackers search for them the same way scanners do.

Assessors treat it as a control failure on its own. PCI DSS 8.6.2 bars hard-coded passwords for application and system accounts that can be used for interactive login, whether in scripts, configuration files, or custom code. NIST 800-53 IA-5(7) asks that static authenticators stay out of applications and other static storage. A customer's security questionnaire asks the same thing in plainer words: where do your secrets live, and who can rotate them?

AI coding assistants and agents raise the stakes. They read the whole repository, .env files included, and an agent handed a broad key can use everything that key reaches.

The fix

Rotate first. Revoke the key where it was issued and create a new one before you touch the code. Then check the issuer's logs for use of the old key since the day it was committed. Rotation is what closes the risk; everything after it closes the finding.

Find every copy. Scan the full history across every branch, and the container images you ship, with a secret scanner. A key deleted from the latest commit still sits in history and in older images.

Move it into a vault. The application or pipeline reads the key at runtime from a secrets manager. Give each pipeline, script, or AI agent its own machine account, scoped to only the keys it needs, so a leaked token exposes one small set and can be revoked on its own. That's how we close this finding under Credential Management.

Clean the history if you need to. Once the key is rotated, a tool such as git filter-repo can strip it from history so scanners stop flagging it. Rewritten history means a force push and a fresh clone for everyone on the repository, and forks keep their copies, so rotation still does the real work.

Block the next one. Run the same scanner as a pre-commit hook and in CI, and turn on push protection where your Git host offers it, so a new key is stopped before it lands.

Verify. Confirm the issuer rejects the old key, rerun the scan across full history and your images, and keep the before and after output as the evidence that the finding is closed.

When you can't fix it

Sometimes the credential isn't yours to change. A controller, camera, or appliance ships with an account built into its firmware, which is why CWE-798 turns up so often in CISA's industrial control system advisories. A vendor product bundles its own key, or a legacy application reads a password from a file nobody can refactor yet. Your named owner chooses one treatment.

  • Remediate with the vendor's firmware update that removes the account or lets you change it, a replacement product, or a refactor, each with a dated plan.
  • Mitigate by making the built-in account unreachable. Restrict network access to the service that accepts it, put remote access behind an identity-gated path, and alert on any login with that account. For a password a legacy application reads from a file, lock the file to the service account, encrypt it at rest, and rotate it on a schedule if the application allows.
  • Accept with documented compensating controls: the device or application, why the credential can't change, the controls above, the owner, a review date, and a replacement date.

The post Compensating Controls for Legacy Systems covers which controls carry weight and how to write the record an assessor accepts.

Where it lands in the Risk Register

FindingTreatmentOwnerEvidence
Credential written into code, configuration, an image, or CI settingsRemediate, mitigate, or accept (the owner decides)Named by youThe issuer's revocation record, full-history and image scans before and after, and the vault access policy. Maps to NIST 800-53 IA-5(7), PCI DSS 8.6.2, and OWASP A07:2025.

Common questions

Is a hardcoded credential a vulnerability if the repository is private?

Yes. A private repository still gets cloned to laptops, CI runners, contractors, and AI tools, and one leaked token or mistaken visibility change exposes all of it. A 2025 industry study found plaintext secrets in 35% of the private repositories it scanned. Assessors flag it the same way either way.

Where do hardcoded credentials fall in the OWASP Top 10?

Under A07 Authentication Failures in the OWASP Top 10:2025, the same category as in 2021. The weakness is CWE-798, Use of Hard-coded Credentials, with CWE-259 covering hard-coded passwords specifically.

Is a .env file a safe place for secrets?

It keeps keys out of the code, and the file still sits on disk in plain text. Keep it out of Git, make sure the web server never serves it (an exposed .env file is a common web finding on its own), and have production read keys from a secrets manager at runtime.

What if the scanner flags something that isn't a credential?

Test fixtures, example values, and constants that only look like passwords trip these rules often. Record each one in the scanner's allowlist with a short reason and a named reviewer, so the exception is documented and the next real key still gets caught.

Related reading

Need the finding closed, or documented so it stays open with your assessor's acceptance?