A vibe-coded app is not automatically dangerous, but you should treat it as code nobody has reviewed, because that is usually what it is. Before you install one, spend ten minutes on install scripts, dependencies, network behaviour and maintainer history, run it first in a container or VM that holds no credentials, and only then pin the exact version you checked.
That advice holds for any unfamiliar tool, AI written or not. What changes with vibe-coded software is the base rate: more projects, written faster, by one person, with less review and a higher chance of abandonment. Below: what to check, the commands, how to sandbox a tool, what an AI audit misses, and how a company should approve developer tools.
Key takeaways
- AI-written code is not malicious by nature. The measurable problems are weaker security defaults, hallucinated dependencies and, above all, missing human review. Malice is still a human choice.
- You usually cannot tell whether a project was vibe coded, so treat every unfamiliar tool the same way: as unreviewed code from a stranger.
- The fastest risk signals are install time scripts, dependency count, where the release binary came from, network calls, and how many people maintain the project.
- Run the first launch somewhere disposable: a container with networking switched off, Windows Sandbox, or a VM with no shared folders and no SSH agent. Never on a machine holding cloud keys or tokens.
- An AI assistant can speed up a source review, but it reads one commit, cannot see what the release binary does, and can be steered by text planted in the repository.
- Abandonment is a security problem, not just a support problem: nobody patches the tool's vulnerable dependencies, and its release channel may end up controlled by someone else.
- Companies need a short, tiered allowlist process with a named owner, version pinning and clear triggers for a second review, not a blanket ban.
Why so many people are asking this now
In October 2026 an Ask HN thread, "Are you hesitant to install vibe-coded apps?", collected the familiar worries: projects that go quiet after a burst of commits, codebases too large to read, and apps with no programmer behind them. Suggested defences included asking an AI tool to audit the source, running apps in a VM and checking the author's history. One commenter made the key point: you often cannot tell whether an app was vibe coded, so assume it was.
A week earlier, another Ask HN thread asked how to check desktop apps for malicious code. The answers were isolation, network monitoring and keeping the main machine limited to well known software, with one reply noting that reputable closed source software can ship a bad release too.
So the real question is not "was this written by an AI?" It is "has anyone I trust looked at this, and what can it reach if they have not?"
Is AI-written code more dangerous to install than human-written code, or just less reviewed?
Mostly less reviewed, with a few specific failure modes on top. It helps to separate three different risks, because they need different defences.
Risk 1: the code is insecure by accident
There is real evidence that code produced with AI help tends to carry security weaknesses unless someone checks it.
- In "Asleep at the Keyboard?" (Pearce and colleagues, IEEE Symposium on Security and Privacy 2022), researchers prompted an early AI pair programmer with 89 scenarios tied to high risk weakness types and produced 1,689 programs. They judged roughly 40% of them to be vulnerable.
- In "Do Users Write More Insecure Code with AI Assistants?" (Perry, Srivastava, Kumar and Boneh, ACM CCS 2023), participants with access to an AI assistant wrote significantly less secure code than those without it, and were also more likely to believe their code was secure. Participants who trusted the assistant less and worked harder on their prompts produced fewer vulnerabilities.
Both studies used models that are now several generations old. The finding that ages well is the combination of weaker code and higher confidence, which describes many vibe-coded tools. For you as the installer, accidental insecurity matters most when the tool listens on a network port, parses untrusted files, stores credentials or runs with elevated privileges.
Risk 2: the dependencies are wrong or do not exist
Code generating models sometimes invent package names. "We Have a Package for You!" (Spracklen and colleagues, USENIX Security 2025) analysed 576,000 code samples from 16 models and found an average hallucinated package rate of at least 5.2% for commercial models and at least 21.7% for open models, with 205,474 unique invented names. An attacker who registers one of those names on a public registry gets installed by anyone who runs the generated code without checking. Researchers and practitioners have started calling this slopsquatting.
Vibe-coded apps also tend to carry more dependencies than they need, and every extra package is more install time code and more exposure to the next compromised release. More on that in Do AI coding agents add vulnerable dependencies?
Risk 3: the code is malicious on purpose
This is the fear behind most of the questions, and it is the one where AI authorship matters least. A model does not decide to steal your SSH keys. A person does, whether they write the payload by hand, ask a model to write it, or slip it into a dependency. One Hacker News commenter put it plainly: a malicious human developer is a bigger risk than prompt injection.
One new twist: if the author's agent read untrusted content while building the app, that content could in principle have steered it into adding something the author never noticed. OWASP calls this indirect prompt injection. It is still a review failure, which is why the defences below focus on review and isolation rather than on guessing how the code was written.
The honest summary
| Question | Human-written, reviewed project | Vibe-coded, single author project |
|---|---|---|
| Can it be malicious? | Yes, through a bad maintainer, a stolen token or a compromised dependency | Yes, through the same routes, plus unreviewed agent output |
| Likely to have accidental security bugs? | Depends on practices; reviews catch some | Higher, and more confident about it |
| Invented or unnecessary dependencies? | Rare | More common |
| Will someone fix a reported vulnerability? | Usually, if the project is active | Often unclear |
| Can you tell which kind it is? | Sometimes | Often not |
Because of the last row, treat every unfamiliar tool as the right hand column until it earns its way left.
What can an installed app actually do to you?
A tool you install and run as yourself can, by default, do anything your user account can do.
- At install time. npm runs
preinstall,installandpostinstallscripts for every package that defines them, and compiles packages with abinding.gypfile vianode-gyp rebuild. pip's own documentation says a default install "involves running arbitrary code from distributions". Rust runsbuild.rsand procedural macros at compile time. Go has no install hooks. - At first launch. Read files in your home directory, including
~/.ssh,~/.aws,~/.config, browser profiles,.envfiles and shell history. - Over the network. Send whatever it read to any host, and download more code later.
- Over time. Add a launch agent, a systemd user unit, a cron entry or a shell profile line so it runs again after reboot. Auto update itself from a channel the author, or whoever takes the account over, controls.
The Shai-Hulud npm worm, which CISA warned about on 23 September 2025, showed how far install time code reaches. According to CISA it compromised more than 500 packages, harvested GitHub tokens and cloud API keys, and used stolen npm credentials to publish poisoned versions of other packages. Installing was enough.
What quick checks reveal risk?
These checks take ten to twenty minutes and catch the obvious problems. They will not catch a careful backdoor; that is what isolation is for.
The ten minute checklist
| Signal | What looks fine | What should slow you down | How to check |
|---|---|---|---|
| Install scripts | None, or a documented native build | preinstall or postinstall that downloads, decodes or runs a remote script | npm view <pkg> scripts, read setup.py or pyproject.toml |
| Dependency count | A handful of direct dependencies, all well known | Hundreds of transitive packages for a small tool; names you cannot find | npm ls --all, pip install --dry-run --report, go list -m all |
| Release artifact | Built in public CI, with a checksum or provenance attestation | A binary uploaded by hand, no checksums, no build workflow | gh release view, gh attestation verify |
| Network calls | Only the endpoints the README describes | Hard coded IPs, paste sites, webhook URLs, telemetry with no opt out | grep the source; watch traffic in a sandbox |
| Maintainers | Several people, real history, other projects | One account created recently, one giant initial commit | git shortlog -sne, gh repo view, npm view <pkg> maintainers |
| Activity | Commits and releases in the last few months, issues answered | A burst of commits then silence, open security issues ignored | Scorecard Maintained, issue tracker |
| Security policy | SECURITY.md with a contact | No way to report a vulnerability | Look in the repo root |
| License | A clear, widely used open source license | No license, or a license that conflicts with your use | gh repo view --json licenseInfo |
| Permissions asked | Only what the feature needs | Full disk access, accessibility control, admin rights for a simple tool | The installer prompts, the app manifest |
The OpenSSF "Concise Guide for Evaluating Open Source Software" is the long version of this table. It asks about activity and releases in the past 12 months, multiple maintainers ideally from different organisations, suspicious install scripts or recent commits, and whether the software misbehaves in an isolated environment.
Check install scripts
For an npm package, look at the scripts before you install:
# Show the lifecycle scripts the published version declares
npm view some-tool@1.4.2 scripts
# Download the exact tarball without running anything, then read it
npm pack some-tool@1.4.2
tar -xzf some-tool-1.4.2.tgz
cat package/package.json
ls package/
npm pack writes the tarball without running lifecycle scripts. Compare it with the GitHub repository: files the repository does not have, especially minified or obfuscated JavaScript, deserve a closer look.
If you already have a project checked out and want to install without running any dependency scripts:
npm ci --ignore-scripts
# List installed packages that declare install time scripts
find node_modules -name package.json -not -path "*/node_modules/*/node_modules/*" \
-exec jq -r 'select(.scripts.preinstall or .scripts.install or .scripts.postinstall) | .name' {} + 2>/dev/null
Per the npm config docs, with ignore-scripts set, npm test and npm run still run the script you name but not its pre and post scripts. Some packages genuinely need install scripts to compile native code, so the list above is what you read, not what you remove.
For Python, avoid building from source until you have read the source:
# Download wheels only, no dependencies, no code execution
pip download --no-deps --only-binary :all: some-tool==1.4.2 -d ./inspect
# A wheel is a zip file; list it and look for .pth files and unexpected binaries
python -m zipfile -l ./inspect/some_tool-1.4.2-py3-none-any.whl
A .pth file runs at every Python start up: a legitimate feature and a favourite hiding place. If a package only ships a source distribution, its setup.py or build backend runs when pip builds it, so read that first.
Check dependency count and names
# npm: count everything that would be installed
npm ls --all --parseable | wc -l
# Python: resolve without installing, wheels only, and count
pip install --dry-run --ignore-installed --only-binary :all: --quiet \
--report report.json some-tool==1.4.2
jq '.install | length' report.json
# Go
go list -m all | wc -l
# Rust
cargo tree --prefix none | sort -u | wc -l
Four hundred packages behind a small CLI proves nothing, but multiplies the code you trust. In the direct dependencies, look for unfamiliar names, names one letter off a popular package, and packages published days ago. An AI invented name that someone has since registered will look brand new.
Check where the release binary came from
Most desktop apps and many CLIs are installed from a release binary, not from source. Reviewing the repository tells you nothing about that binary unless you can connect the two.
# See what the latest release ships and whether checksums are published
gh release view --repo owner/tool
# Verify a downloaded artifact against the repository that should have built it
gh attestation verify ./tool-linux-amd64 -R owner/tool
# Or at least compare against a published checksum
shasum -a 256 ./tool-linux-amd64
GitHub's documentation says artifact attestations "establish where and how your software was built". A successful gh attestation verify ties the file to a build in the named repository. It does not prove the code is safe or that the built commit was reviewed. It does rule out a binary built on someone's laptop from code you have never seen. Platform code signing on macOS and Windows is a similar signal: it tells you who signed the build, not what the app does with your files.
Check network calls
Read before you run:
# Every URL and host the source mentions, outside vendored dependencies
grep -rEn "https?://[a-zA-Z0-9.-]+" --include="*.js" --include="*.ts" \
--include="*.py" --include="*.go" --include="*.rs" . \
| grep -v node_modules | grep -v "/vendor/"
# Patterns worth a second look: runtime code execution and encoded blobs
grep -rEn "child_process|subprocess|exec\(|eval\(|base64" \
--include="*.js" --include="*.ts" --include="*.py" . | grep -v node_modules
Neither command is a detector; they give you a short list of places to read. Then watch the tool in your sandbox: ss -tp on Linux or lsof -i -n -P on macOS shows connections by process.
Check maintainer history
gh repo view owner/tool --json createdAt,pushedAt,stargazerCount,isArchived,licenseInfo
git clone --filter=blob:none https://github.com/owner/tool && cd tool
git shortlog -sne | head
git log --reverse --format='%ad %an %s' --date=short | head -5
One author, a first commit of forty thousand lines and nothing since is a code drop, not a project: fine to run once in a sandbox, a poor choice for every engineer's laptop. Weigh stars below the issue tracker: answered issues, acknowledged security reports, merged pull requests from people other than the author.
Use Scorecard for the repository level view
OpenSSF Scorecard runs automated checks against a repository and scores each from 0 to 10. The ones most useful for this decision are Maintained, Code-Review, Dangerous-Workflow, Pinned-Dependencies, Signed-Releases, Binary-Artifacts, Security-Policy and Vulnerabilities.
export GITHUB_AUTH_TOKEN=<a read only token>
scorecard --repo=github.com/owner/tool --show-details \
--checks=Maintained,Code-Review,Signed-Releases,Binary-Artifacts,Vulnerabilities
You can also view published results at https://scorecard.dev/viewer/?uri=github.com/owner/tool for projects that publish them. Two caveats from the Scorecard docs: Maintained cannot assess a project younger than 90 days, and Code-Review only counts human reviews, so an author who merges an agent's pull requests without a second person will score low there. For vibe-coded tools, both of those are informative rather than unfair.
Step by step: vetting a tool from GitHub before you install it
Here is the whole process in order, for a typical case: a CLI tool you found on GitHub that installs from npm or a release binary.
- Decide whether you need it. The OpenSSF guide starts here: a tool you do not install has no risk.
- Confirm you have the real project. Repository owner and registry package should link to each other; look for a more popular project with a similar name.
- Read the history and maintainers.
gh repo view,git shortlog -sne, the issue tracker,SECURITY.md. - Check install scripts and the published artifact.
npm view <pkg> scripts,npm pack,pip download --only-binary :all:, thengh attestation verifyor a checksum for binaries. - Read the direct dependency list. Look up any unfamiliar or very new names.
- Skim the source for network calls and runtime execution with the two
grepcommands, then read the hits. - Optionally run an AI assisted review inside the sandbox, following the rules below.
- Scan the dependencies for known vulnerabilities and license problems.
- Run it in a sandbox first and watch what it reads, writes and connects to.
- Install for real with a pinned version. Lockfile plus
npm ci, hashes for pip, a checksum for binaries. Turn off auto update and update on purpose. - Write down what you checked: version, date, findings, who decided. That note is the start of an allowlist.
Steps 1 to 6 take about ten minutes for a small tool. Steps 7 to 9 give the real assurance.
How do you run an unfamiliar tool safely?
The goal is simple to state: if the tool turns out to be hostile, it should find nothing worth stealing and have nowhere to send it. In practice that means no credentials in reach, no network or tightly limited network, a filesystem it cannot persist in, and a box you can throw away.
Choosing the right isolation
| Option | Isolation strength | Good for | Weak spots |
|---|---|---|---|
Container with --network none | Process and filesystem isolation, shares the host kernel | CLIs, libraries, build tools on Linux or via Docker Desktop | Kernel escapes, mounted host paths, GUI apps are awkward |
| Windows Sandbox | Hypervisor isolated, disposable Windows desktop | Windows desktop apps and installers | Networking on by default; not on Windows Home; one instance at a time |
| Full VM with snapshots | Separate kernel, strong boundary | Desktop apps on any OS, long tests, watching behaviour | Shared folders, clipboard sharing and agent forwarding punch holes |
| Separate physical machine | Strongest | Tools that need hardware access or long term trials | Cost, and people end up logging into real accounts on it |
| Web version instead of install | Browser sandbox | Anything that offers one | You trust the operator with whatever data you upload |
For a deeper look at how strong each boundary is, see Can AI agents escape their sandbox?, which covers containers, gVisor style sandboxes and microVMs in detail.
A hardened container for a CLI tool
Docker's documentation describes the pieces: --network none leaves only a loopback interface, --read-only mounts the root filesystem read only, --security-opt no-new-privileges stops processes from gaining privileges through su or sudo, --cap-drop removes Linux capabilities, --pids-limit caps the process count and --rm deletes the container on exit.
The trick for tools that need dependencies is to install with the network on, then cut the network before the tool itself runs:
# 1. Start a named container with no credentials, no host home directory,
# a non root user, all capabilities dropped and resource limits
docker run -d --name vibe-test \
--cap-drop ALL \
--security-opt no-new-privileges \
--user node \
--pids-limit 256 \
--memory 2g \
-v "$PWD/tool-src:/src:ro" \
-w /home/node \
node:22-bookworm-slim sleep infinity
# 2. Copy the source in and install dependencies without running their scripts
docker exec vibe-test sh -c 'cp -r /src/. ./app && cd app && npm ci --ignore-scripts'
# 3. Cut the network from the host side before the tool ever runs
docker network disconnect bridge vibe-test
# 4. Run the tool and see what it tries to do
docker exec -it vibe-test sh -c 'cd app && node ./bin/tool.js --help'
# 5. See what it changed on disk, then throw everything away
docker diff vibe-test
docker rm -f vibe-test
docker diff lists every file the container added or changed, a quick way to spot start up hooks. If the tool fails without network, read the code path that failed and decide whether that connection was one you expected.
For a one shot run with no dependency install step, the simpler form works:
docker run --rm -it --network none --read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=256m \
--cap-drop ALL --security-opt no-new-privileges \
--user 1000:1000 \
-v "$PWD/tool:/work:ro" -w /work \
python:3.13-slim python ./tool.py --help
Never mount your home directory, ~/.ssh, ~/.aws, .env files or the Docker socket, which alone gives the container control of the host.
Windows Sandbox for desktop apps
Microsoft describes Windows Sandbox as a disposable, hypervisor isolated Windows desktop that starts clean each launch and deletes everything on close. It runs on Pro, Enterprise and Education, not Home. Microsoft warns that networking is on by default and can expose untrusted apps to the internal network, and recommends disabling it and mapping the app's folder read only.
Save this as untrusted.wsb and double click it:
<Configuration>
<Networking>Disable</Networking>
<MappedFolders>
<MappedFolder>
<HostFolder>C:\Users\me\Downloads\tool</HostFolder>
<SandboxFolder>C:\tool</SandboxFolder>
<ReadOnly>true</ReadOnly>
</MappedFolder>
</MappedFolders>
</Configuration>
Use the app as you intend to, then close the window. To see its network behaviour, enable networking in a second run and watch Resource Monitor's network tab.
A VM for macOS and Linux desktop apps
On a Mac, a local virtual machine running macOS or Linux is the practical equivalent. It is only isolated if you turn off shared folders (copy the installer in), clipboard sharing and SSH agent forwarding, keep signed in browsers, password managers and cloud CLIs out of it, and snapshot before installing so you can roll back. Route it through a logging firewall or proxy if you want to see its traffic.
The rule that matters more than the sandbox
Whatever you use, the box must hold no credentials. People most often defeat their own sandbox by logging into something inside it "just to test sync". If the tool needs an account, use a throwaway one. Our post on how infostealers steal developer and AI agent tokens lists the token locations worth keeping out of reach.
Can you use an AI assistant to audit a repo before you install it?
Yes, as long as you know what it is checking and what it is not. The value is speed: an assistant can read a large codebase faster than you, summarise each module, and point you at the twenty lines worth reading yourself.
How to run the audit so it helps rather than hurts
- Run it inside the sandbox, against a clone. Our guide to opening an untrusted repo with an AI coding agent covers which project files can execute code or steer an agent the moment you open a folder.
- Give it read only tools. No install, build or test commands during the audit.
- Use a checklist, not one sentence, as one commenter in the thread advised. Ask for each of these, with file and line references:
- Every install time script and build hook, and what it runs.
- Every outbound network call, with the host and the data sent.
- Every place the code reads from the user's home directory, environment variables or keychain.
- Every use of runtime code execution:
eval, dynamic imports, shell execution, decoding of embedded blobs. - Any persistence: start up items, cron, shell profile edits, auto update logic.
- Files whose content does not match their name or type, and minified or obfuscated files.
- Ask for evidence, then check it yourself. A claim without a file and line is unverified.
- Ask what it did not read. Large repositories exceed one pass; ask which directories it skipped.
What an AI audit misses
- The release binary. The assistant audits source. Unless the build is attested or reproducible, nothing connects that to the binary you install.
- Dependencies resolved at install time. What installs is decided when you run the package manager, possibly including versions that did not exist during the audit.
- Instructions planted for the auditor. OWASP's description of indirect prompt injection covers this: text in files the model processes can change its behaviour. A README note telling "AI reviewers" the code is already audited costs nothing to write.
- Behaviour that depends on time or environment. Code that only does something on a particular date, on a particular host name, or after a remote flag flips will read as harmless.
- Future versions. The audit is for one commit. Auto update replaces it with code nobody audited.
- Your own overconfidence. The CCS 2023 study found AI assistant users more likely to believe their code was secure; the same trap applies when an assistant says a repository looks fine.
An AI audit is a good reason to reject a tool and a weak reason to trust one. More in Can an AI model do a real security review of my code?
What signs suggest a project will be abandoned, and why does that matter for security?
Abandonment is normal in open source. One Hacker News commenter estimated that most vibe-coded projects are abandoned almost immediately; that is an opinion, not a measurement. Research on established packages is sobering on its own terms. The ICSE 2025 paper "Understanding the Response to Open Source Dependency Abandonment in the npm Ecosystem" (Miller, Jahanshahi, Mockus, Vasilescu and Kästner) found that abandonment is common even among widely used npm packages, that many projects exposed to it never respond, and that dependents remove an abandoned package much faster when its maintainer explicitly declares it end of life.
Warning signs
| Sign | Why it predicts abandonment |
|---|---|
| One maintainer, no other contributors with merged work | No one to take over when they lose interest |
| A large initial commit followed by a short burst, then silence | Built for a launch, not for maintenance |
| No releases or tags, only a default branch | No release process to keep up |
| Issues and pull requests unanswered for weeks | The maintainer is already gone in practice |
Version 0.x or labelled alpha or experimental | The author has not committed to stability |
| No tests, no CI | Every change is risky, so changes stop |
| Dependencies far behind current versions | Updates are already not happening |
Scorecard Maintained near zero | Little or no commit or issue activity in the last 90 days |
| Archived repository | Explicitly abandoned, which is the honest version |
The OpenSSF guide uses a 12 month window; Scorecard's Maintained check gives a full score only for at least one commit per week across 90 days. Neither is a hard rule, since a small finished library can be quiet and healthy. The real question is whether anyone would respond to a vulnerability report today.
Why abandonment is a security issue
- Nobody updates the dependencies. The lockfile ages into a list of known vulnerabilities you cannot fix without forking.
- Nobody fixes reported bugs. A vulnerability report sits in a public issue tracker, unpatched.
- The release channel can change hands. Unwatched maintainer accounts attract attackers, and expired domains in install or update URLs can be re-registered. An auto updating tool trusts whoever holds that channel next.
Your choices are to replace it, pin it with an explicit risk acceptance and review date, fork and maintain it, or get a maintained, patched build elsewhere.
What should a company allowlist process look like for developer tools?
NIST's Guide to Application Whitelisting (SP 800-167, 2015) describes the underlying control: only approved software runs on a host. For developer tools, a strict technical allowlist on every laptop is usually too slow and gets bypassed. A lightweight tiered process works better, with a fast path for low risk tools and enforcement where risk is highest.
Tier the tools by what they can reach
| Tier | Example | Review | Approver | Re-review |
|---|---|---|---|---|
| 0: Web app, no company data | A public formatter or diagram tool used with dummy data | None beyond policy on data | Self | Never |
| 1: Local tool, no credentials, no network need | A linter, a file converter, a local CLI | Ten minute checklist, pinned version | Team lead | Major version or ownership change |
| 2: Local tool that touches credentials, source or the network | A git client, a database GUI, an AI coding agent, a sync tool | Checklist plus sandbox run plus dependency scan | Security reviewer | Every minor version, or quarterly |
| 3: Runs in CI, on servers or with production access | A build plugin, a GitHub Action, a deploy CLI | Full review, pinned by hash, provenance where available | Security and platform owner | Every version |
What the request and the review should record
Keep the intake form to what a reviewer actually uses: name, source URL and exact version or commit; why it is needed and which approved tool was considered; where it runs (laptops, CI, servers); what it touches (source, credentials, customer data, network); how it installs; and a named owner. The reviewer adds the checklist results, the license outcome, known vulnerabilities and whether any are reachable, how the version is pinned (lockfile, hash, checksum or image digest), whether auto update is off, and a re-review date.
Triggers for a second review
- A new major version, or any change in the publishing account or repository owner.
- A new install script appearing in a release that never had one.
- The project archived or showing abandonment signs.
- A license change.
- A critical vulnerability in the tool or a dependency.
- The tool moving up a tier, for example from a laptop into CI.
Enforcement that does not slow everyone down
- Package managers. Route npm, pip and image pulls through an internal registry or proxy, or at least ship a managed
.npmrcwithignore-scripts=trueand exceptions for packages that must build. npm'smin-release-agesetting installs only versions at least a given number of days old, a cheap buffer against brand new malicious releases. - CI. Pin GitHub Actions and build tools by commit hash or digest, and fail builds on unapproved or known exploited dependencies.
- Laptops. Application control on managed devices for Tier 2 and 3, plus a published list of approved versions so engineers can self serve.
- Inventory. When a tool is compromised or abandoned, the first question is who has it.
If approving a Tier 1 tool takes more than a day, people install it anyway and stop telling you.
Common mistakes
- Trusting stars or a polished README. Both are cheap, and a model writes the README for free.
- Auditing the repository and installing the binary. Without attestation or a reproducible build, you audited something other than what you ran.
- First launch on your main machine "just to see". That is when a hostile tool reads
~/.sshand your cloud credentials. - Sandboxing with credentials inside, or mounting your home directory or the Docker socket into the test container.
- Letting the AI auditor run the code. An audit agent that runs install scripts has installed the tool.
- Taking an AI audit's "looks fine" as clearance. It covers one commit and only what the model read.
- Leaving auto update on. You approved one version, not every future one.
- Ignoring abandonment because the tool works today. Its dependencies keep collecting CVEs.
- Banning everything. Engineers then install tools on personal machines, which is worse.
Fix it without waiting for upstream
The hardest case in this post is a useful tool whose maintainer has moved on, sitting on dependencies that keep collecting CVEs. You do not have to choose between dropping the tool and waiting for a release that may never come.
In incidents like this one, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
For the manual version of this workflow, see How to patch an open source dependency without waiting for upstream.
Where Safeguard fits, and where it does not
Safeguard helps with the dependency and vulnerability half of vetting a tool, and with keeping an approved tool healthy afterwards.
- Before install. Clone the tool into your sandbox and run
safeguard scan --dir .to build an SBOM of its dependencies and match them against vulnerability databases. Results land as JSON under./output. Container images can be scanned with--image <name>and an existing SBOM with--sbom <file>. License compliance checks show whether the tool's dependency tree fits your license policy. - For a quick lookup without an account. Check each direct dependency, or any CVE that turns up, on gold.safeguard.sh for affected and fixed versions and KEV status.
- For the allowlist. Policies and gates in the platform can encode the rules above, such as no known exploited vulnerabilities and no disallowed licenses, and the platform shows which projects contain a given component and version when you need to find every copy of a tool after a problem.
- For the audit itself. The Safeguard CLI's assistant can read a repository, explain what it does and run commands only with your approval. Before pointing it at code you do not trust, switch
/permissionsout of the default Auto mode to a stricter one such as Ask, and run it inside the sandbox.
Where it does not help: a dependency scan is not a behavioural review of the tool's own code, Safeguard does not sandbox anything for you, and it cannot vouch for a release binary that was not built from the source you scanned or predict whether a maintainer will stick around. Those parts of the decision are still yours, and the checks and isolation above are how you make them.
If you want to try it on the next tool you are evaluating, you can download Safeguard and follow the CLI docs.
FAQ
Is vibe-coded software safe to use?
It can be, but do not assume so. Most are written quickly by one person and never reviewed, so accidental bugs, unnecessary dependencies and abandonment are more likely. Vet it like any unreviewed code, run it isolated first, and pin the version you checked.
Is AI-generated code more likely to contain malware?
Not by itself; malware is a human decision. AI generated code is more likely to contain accidental vulnerabilities and invented package names, and an agent that read untrusted content could in principle have been steered into adding something. Review and isolation address all of these.
What is the quickest way to check a GitHub repo before installing it?
Look at install scripts (npm view <pkg> scripts or the Python build files), count dependencies, check whether the release binary is attested with gh attestation verify, read git shortlog -sne and the issue tracker, and run OpenSSF Scorecard. Then run the tool once in a container with --network none or in a VM.
Is it safe to run npm install on a project I just cloned?
Not on your main machine if you do not trust it. npm install runs lifecycle scripts for every dependency that declares them. Use npm ci --ignore-scripts inside a container first, list which packages need install scripts, and read those. Our post on whether it is safe to run npm install right now covers this in depth.
Can I ask ChatGPT or Claude to check a GitHub repo for malicious code?
Yes, and it is useful for finding the parts worth reading. It cannot see what a prebuilt binary does, it reads only the commit you give it, and text in the repository can try to steer it. Run it in a sandbox with read only tools and verify the file and line evidence yourself.
Is a Docker container enough to run an untrusted app safely?
For most CLI tools, a container with networking off, all capabilities dropped, a non root user and no host directories mounted is a reasonable first line. Containers share the host kernel, so for anything you consider genuinely hostile, or for desktop apps, use a VM or Windows Sandbox instead.
Does Windows Sandbox block network access?
Not by default. Microsoft's documentation says networking is enabled by default and can be disabled in a .wsb configuration file with <Networking>Disable</Networking>. Map the app's folder read only as well.
What happens if an open source tool I use is abandoned?
It keeps working until its dependencies collect vulnerabilities nobody fixes, or until its release channel or domain changes hands. Pin it, set a review date, and plan to replace it, fork it or get a maintained build.
Should my company ban vibe-coded tools?
A ban is hard to enforce because you cannot reliably tell which tools are vibe coded, and it pushes people to work around it. A tiered allowlist with a fast path, pinned versions and re-review triggers manages the actual risk better.
Related reading
- Are AI coding agent plugins, hooks and skills safe to install?
- Is it safe to clone a repo and open it with an AI coding agent?
- Is vibe coding safe for production apps?
- Vet a new open source package in ten minutes
See how Safeguard would help
The first demo is a real Safeguard CLI session. It installs the CLI, opens the interactive terminal and asks it to fix a lodash CVE; the assistant reads the finding and the advisory, asks before each command, edits package.json to lodash 4.17.21, runs npm install and npm test only with approval, prints a summary and pushes nothing. It ends with /permissions, /model and /scan ., which are the commands you would use to tighten approvals and scan a tool's dependencies before you trust it.
Click through it at your own pace, or open it full screen.
The second demo sets up the Safeguard runner on your own machine, approves it with its device code, and then scans from the terminal. The same setup works inside a VM you keep for evaluating tools, so the dependency scan of an unfamiliar project happens in the disposable box rather than on your workstation.
Click through it at your own pace, or open it full screen.
The third demo connects Claude to the Safeguard MCP server with OAuth and shows how you choose which tools Claude can use. If you already ask an assistant to review repositories before install, this is how you give it vulnerability and dependency data to check against, while deciding exactly what it is allowed to do.
Click through it at your own pace, or open it full screen.
Quick check
You audited a tool's GitHub source and it looks clean. You then install its prebuilt release binary. What did your audit cover?
Only the source at that commit. Unless the binary has a verifiable attestation (gh attestation verify) or a reproducible build, nothing connects what you read to what you ran. Verify its origin, build it yourself from the audited commit, or sandbox it as unaudited.
You run an unfamiliar CLI in Docker with your home directory mounted so it can read its config file. Is that safe?
No. Mounting your home directory gives the tool your SSH keys, cloud credentials and shell history, which is exactly what the sandbox was meant to protect. Mount only a dedicated folder with a test config, read only, with networking off for the first run.
Sources
- Ask HN: Are you hesitant to install vibe-coded apps? (Hacker News)
- Ask HN: How do you check desktop apps for malicious code? (Hacker News)
- OpenSSF: Concise Guide for Evaluating Open Source Software
- OpenSSF Scorecard: check documentation
- OpenSSF Scorecard: project README and usage
- npm documentation: scripts
- npm documentation: config
- pip documentation: secure installs
- Docker documentation: running containers
- Docker documentation: docker container run reference
- Docker documentation: none network driver
- GitHub Docs: using artifact attestations
- Microsoft Learn: Windows Sandbox
- NIST SP 800-167: Guide to Application Whitelisting
- CISA: Widespread supply chain compromise impacting npm ecosystem (23 September 2025)
- OWASP GenAI Security Project: LLM01 Prompt Injection
- Perry et al.: Do Users Write More Insecure Code with AI Assistants? (ACM CCS 2023)
- Pearce et al.: Asleep at the Keyboard? (IEEE S&P 2022)
- Spracklen et al.: A Comprehensive Analysis of Package Hallucinations by Code Generating LLMs (USENIX Security 2025)
- Miller et al.: Understanding the Response to Open Source Dependency Abandonment in the npm Ecosystem (ICSE 2025)
Last reviewed: 22 October 2026. Package manager and sandbox defaults change between versions; check each project's documentation for the behaviour of the version you run.