SSH Private Key Committed to Version Control
What Is This Vulnerability?
An SSH private key file has been committed to a git repository. SSH keys provide direct authentication to servers, CI/CD systems, and code hosting platforms. An attacker with the private key can log into any server that trusts the corresponding public key, without needing a password, giving them full shell access.
Why It Happens
Developers sometimes store SSH keys in their project directory for deployment scripts or Docker builds and forget to add them to .gitignore. Automated provisioning scripts may generate key pairs in the working directory. Some Dockerfiles copy SSH keys for pulling private dependencies during the build process, and the key file ends up in the repository.
Example Code
FROM node:20-alpine
WORKDIR /app
COPY . .
COPY id_rsa /root/.ssh/id_rsa
RUN chmod 600 /root/.ssh/id_rsa
RUN npm install
RUN rm /root/.ssh/id_rsa
CMD ["node", "server.js"]FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN --mount=type=ssh npm install
COPY . .
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app .
CMD ["node", "server.js"]How Hackers Exploit It
Attackers extract the private key from the repository and use it to authenticate to any server where the matching public key is authorized. They gain full shell access, allowing them to steal data, install backdoors, pivot to internal networks, or disrupt services. Even if the key file is later removed from the repo, it remains in git history.
How to Fix It
Never place SSH private keys in your project directory. Add id_rsa, id_ed25519, and *.pem to your .gitignore. For Docker builds, use BuildKit SSH forwarding (RUN --mount=type=ssh) or multi-stage builds that do not include the key in the final image. If a key was committed, immediately revoke it by removing the public key from all authorized_keys files and generating a new key pair.