Safeguard
Open Source

npm copyfiles: A Security Review and Safe Usage Guide

copyfiles is a tiny cross-platform file-copy CLI that a lot of build scripts rely on. Here is its security profile and how to use the npm copyfiles package carefully.

Marcus Chen
DevSecOps Engineer
5 min read

The npm copyfiles package is a small, build-time-only utility for copying files across platforms, and its security risk comes almost entirely from the glob patterns you feed it, not from the tool itself. copyfiles exists to solve one annoyance: cp and its flags differ between Unix and Windows, which breaks cross-platform build scripts. This review looks at what it does, the path-handling pitfalls worth knowing, and how to keep it scoped so it never ends up in a production artifact.

What copyfiles is for

copyfiles copies files matched by one or more glob patterns into a destination directory, and it works the same on macOS, Linux, and Windows. That portability is the whole selling point. A typical package.json script uses it to move static assets into a build output folder:

{
  "scripts": {
    "copy-assets": "copyfiles -u 1 \"src/assets/**/*\" dist"
  }
}

The -u 1 flag strips one leading path segment so src/assets/logo.png lands at dist/assets/logo.png rather than dist/src/assets/logo.png. You install it as a dev dependency, because a file-copy helper has no reason to exist in your shipped runtime:

npm install --save-dev copyfiles

When you audit a repo, the first thing to confirm is that copyfiles npm sits under devDependencies. A build tool in the production dependency list is dead weight and one more package your deployed image trusts for nothing.

The glob-pattern pitfalls

Because copyfiles is driven by globs and destination paths, the risks are about what those patterns match, not about remote input. Two mistakes recur.

Overly broad patterns copy things you did not mean to ship. A pattern like "**/*" will happily sweep up .env files, .git internals, private keys left in the working tree, and node_modules if you are not careful. That is how secrets end up baked into a dist folder and then into a container image. Be specific:

{
  "scripts": {
    "copy-assets": "copyfiles -u 1 \"src/assets/**/*.{png,svg,css}\" dist"
  }
}

Scope patterns to the file types you actually want, and keep a review step or a .dockerignore and .gitignore that would catch a stray secret even if the glob is too greedy.

Untrusted or dynamic paths. If a build script builds a copyfiles command from a variable that itself comes from an environment value or a CI parameter, you can end up reading from or writing to a location you did not intend. Keep the source and destination paths static in the script, or validate them if they must be dynamic. Treat directory-traversal style inputs the same way you would anywhere else: reject .. segments that would escape the intended tree.

Supply-chain considerations

copyfiles is a small package, but small does not mean safe by default. A single-maintainer build utility that runs on every developer's machine and in CI is exactly the kind of target a supply-chain attacker likes, because a malicious postinstall script would execute widely. The defenses are the ordinary ones:

  • Commit a lockfile so the exact version is reproducible and a compromised patch release cannot land silently.
  • Review the dependency's own tree; a build tool with a surprising new transitive dependency deserves a look before you upgrade.
  • Run continuous SCA scanning so any advisory against copyfiles or a package below it is reported automatically rather than discovered during an incident.

If you want to trim risk further, ask whether you need copyfiles at all. For simple cases, a short Node script using the built-in fs module, or your bundler's own asset handling, removes a dependency entirely. Fewer packages in the build path means fewer maintainers to trust.

A safe-usage checklist

Before you rely on npm copyfiles in a pipeline, confirm each of these:

  1. It is installed under devDependencies.
  2. Glob patterns are scoped to specific file types, never a bare **/* that could sweep secrets.
  3. Source and destination paths are static, or validated if they must be computed.
  4. .gitignore and any container ignore file would still exclude secrets even if a glob is too broad.
  5. A lockfile is committed and SCA runs in CI.

None of this is heavy. copyfiles is a convenience, and the goal is to keep it a convenience rather than the reason a private key ends up in a public image.

FAQ

Is the npm copyfiles package safe to use?

Yes, for build scripts. copyfiles is a small, build-time-only file-copy utility with no runtime or network surface. The risk is in overly broad glob patterns and ordinary supply-chain hygiene, both of which you control.

Can copyfiles accidentally copy secrets?

It can if you point it at a broad pattern like **/*, which will match .env files, keys, and other sensitive content in the working tree. Scope patterns to explicit file types and keep ignore files that would exclude secrets as a backstop.

Should copyfiles be a dependency or devDependency?

A devDependency. It only runs during builds. Placing copyfiles npm under production dependencies adds a package your deployed runtime trusts for no reason.

Do I really need copyfiles?

Not always. For simple asset copying, a short Node script using the fs module or your bundler's built-in asset handling can replace it and remove a dependency from your build path entirely.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.