CWE-530: Exposure of Backup File to an Unauthorized Control Sphere
Overview
Backup file exposure occurs when backup, temporary, editor swap, archive, or old deployment files are left in a location that unauthorized users can access. These files often bypass normal application routing and access control because the web server serves them as static files.
Examples include .bak, .old, .orig, ~, .swp, .tmp, .zip, .tar.gz, copied configuration files, exported databases, and backup copies of source files such as index.php.bak.
Relationship to Other CWEs
This page's MITRE parent, CWE-552, has no page here, so the bullets below reach the corpus through its grandparents. MITRE records no direct relationship between CWE-530 and any page in this corpus.
- CWE-530 (this page) - a backup, swap, archive or old deployment file left where an unauthorized party can fetch it, usually served as a static file that never passes through the application's access control
- CWE-552 (Files or Directories Accessible to External Parties) - the Base this page sits under, for any file reachable by someone who should not reach it. No page here
- CWE-668 (Exposure of Resource to Wrong Sphere) - one of CWE-552's two parents and the Class this whole branch hangs from; the right level when the exposed resource is not a file
- CWE-285 (Improper Authorization) - CWE-552's other parent. Relevant because the defect here is usually that the file bypasses authorization entirely rather than that a check decided wrongly
- CWE-538 (Insertion of Sensitive Information into Externally-Accessible File or Directory) - the near-twin by subject and easily confused with this page. The split is how the file got there: CWE-538 is the application writing sensitive data to a reachable location, CWE-530 is a copy of something legitimate left behind where it can be fetched
- CWE-732 (Incorrect Permission Assignment for Critical Resource) - where the file is meant to exist but its permissions are wrong, rather than the file having no business being there at all
OWASP Classification
A01:2025 - Broken Access Control
Risk
Medium to High: Exposed backup files can disclose secrets and implementation details. A single backup of a configuration file may contain database credentials, signing keys, cloud tokens, or administrative endpoints. A backup of source code can reveal vulnerabilities, hidden routes, authorization logic, or hardcoded credentials.
Remediation Steps
Core Principle: Never place backup or temporary files inside a public web root or object storage prefix; block access to backup extensions and remove these files during deployment.
Remove Backup and Temporary Files Before Deployment
# Run from the release artifact or staging directory before publishing
find . -name "*.bak" -delete
find . -name "*.old" -delete
find . -name "*.orig" -delete
find . -name "*~" -delete
find . -name "*.swp" -delete
find . -name "*.tmp" -delete
find . -name ".DS_Store" -delete
Treat this as a build or release step, not a manual cleanup task.
Keep Backups Outside the Web Root
Store backups in locations that are not served by the web server:
- Dedicated backup storage with access control
- Private object storage buckets
- Encrypted backup repositories
- Infrastructure-managed snapshots
- Directories outside
/var/www,public/,htdocs/, or equivalent web roots
Backups should have separate retention, access logging, and encryption policies.
Configure Web Server Deny Rules
Apache:
<FilesMatch "(\.bak|\.old|\.orig|\.save|\.swp|\.tmp|~|\.zip|\.tar|\.tar\.gz)$">
Require all denied
</FilesMatch>
Nginx:
These rules are defense in depth. They should not be the only control because a missing extension or new backup convention can bypass them.
Exclude Development Artifacts From Release Packages
Use packaging rules that include only the files required to run the application. Exclude:
- Backup and editor-generated files
.git,.svn,.hg, and other version control directories.env, local config, and secrets files- Test databases and local exports
- Build caches and temporary directories
Container builds should copy only compiled or runtime artifacts into the final image.
FROM node:24 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
RUN npm prune --omit=dev
FROM node:24-slim
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/server.js"]
The exclusion list above is enforced by .dockerignore, not by the multi-stage split. COPY . . copies whatever the build context contains, so without this file .git, .env and every editor backup land in the builder layer. That layer is still readable in the build cache and in any registry that holds intermediate stages, even though the final stage copies only dist/.
# .dockerignore - alongside the Dockerfile
.git
.svn
.hg
.env
.env.*
*.bak
*.old
*.orig
*~
*.swp
node_modules
npm ci installs devDependencies because the build step needs them; npm prune --omit=dev in the builder stage strips them again so the node_modules copied into the final image holds runtime dependencies only. If the build needs no devDependencies at all, npm ci --omit=dev and drop the prune.
Scan for Exposed Backup Files
Regularly check production and staging for common backup names:
/index.php.bak/config.php~/.env.old/database.sql/backup.zip/www.tar.gz/web.config.orig
Automated checks should run after deployment and against public endpoints, not only inside the repository.