You have seen the pattern in a hundred install docs:
curl https://example.com/install.sh | bash
It is convenient. It is also the single most-argued line in DevOps. Before you paste it into a root shell, it is worth being precise about what it actually does — and about what curl qsa.sh does not do, because the two look similar and are not the same thing at all.
What curl <url> | bash actually does
The pipe does exactly what it says. curl fetches whatever bytes the server sends, and bash executes them as a shell script — on your machine, with your privileges, right now. There is no preview, no diff, no confirmation step. Whatever the server returns is the program that runs.
That is not a hypothetical. It is arbitrary local code execution by design. The risk is not that the pattern is broken; it is that it works perfectly and hands full trust to a remote party. Specifically:
- You cannot see what you ran. By the time the script executes, you have already run it. Auditing after the fact is not auditing.
- Trust extends to the whole chain. You are trusting the domain, its TLS, its DNS, the CDN in front of it, and anyone who can compromise any of those. A server can also detect a piped shell (no TTY) and serve different bytes than it shows in a browser — this has been demonstrated publicly.
- Failure modes get worse. A truncated download can leave a half-run script.
sudo curl ... | bashruns remote code as root.
To be fair — and this matters — curl | bash is not automatically malicious. Downloading a release binary, an apt package, or a container image is also "run code you didn't read." The pattern's real sins are that it skips the checkpoint where you could have looked, and that it re-fetches live every time, so a good script today can become a bad script tomorrow with nothing pinned.
The safer way to run an install script
If you are going to run one, split fetch from execute so there is a moment to look:
curl -fsSL https://example.com/install.sh -o install.sh
less install.sh # actually read it
sha256sum install.sh # compare to a published checksum, if any
bash install.sh
Not glamorous. But now there is a checkpoint, and you are running a known artifact instead of a live stream. Prefer signed packages or checksummed binaries when the project offers them.
Why curl qsa.sh is a different animal
Here is the part people conflate. curl qsa.sh is not curl qsa.sh | bash. There is no pipe into a shell, and there is nothing on our end that expects one.
curl qsa.sh makes an HTTP request and streams text back to your terminal. That text is a scan report. Your shell prints it, the same way it would print a README. No script is downloaded to be executed, no code runs on your machine, and adding | bash would accomplish nothing useful because the output is a human-readable report, not a program.
The work happens on our side, not yours:
- The scan runs from qsa.sh's own real, attributable scanner IP (reverse-DNS
scanner.qsa.sh) — an outside-in view, exactly what an external attacker sees. - It scans only the public IP you are connecting from. There is no target field; you cannot aim it at anyone else. Your IP is shown with a countdown before anything starts.
- The engine is the same open-source tooling you could run yourself: naabu for port discovery,
nmap -sV --script vulnersfor service/version and CVE matching, then nuclei for templated checks (current engine versions). No black box. - Zero retention: results stream to your terminal and are gone. No stored scan output, no stored IPs, no user-agents, no history.
So the trust question inverts. With curl <url> | bash, the remote server runs code on your machine. With curl qsa.sh, your machine runs nothing — it just displays what our scanner found looking at your public IP from the outside.
Side by side
curl <url> | bash | curl qsa.sh | |
|---|---|---|
| What comes back | A shell script | A text report |
| What runs it | Your shell, on your host | Nothing — it is printed |
| Where code executes | Your machine, your privileges | Our scanner, server-side |
| What it can touch | Your filesystem, your creds | Only your public IP, from outside |
| Retained | Whatever the script writes | Nothing |
A fair caveat, because this is a security site
You should still know who you are talking to. curl qsa.sh streams text and runs nothing locally — that is true whether you trust us or not, because the output never touches your shell as code. But the report itself comes from us, so treat qsa.sh like any external scanner: it is a starting point, an attacker's-eye view of your exposed surface, not a full audit.
One practical note: plain curl qsa.sh is HTTP. To encrypt the request and response in transit, use curl https://qsa.sh. Same scan, same report — just protected on the wire. On a network you do not control, prefer the https:// form.
The short version
curl <url> | bash is not evil, but it is arbitrary local code execution with no checkpoint — read it, checksum it, or use a signed package first. curl qsa.sh is not that pattern: it prints a report, runs no local code, and does its scanning from our own IP against only your public IP.
Run it and read the output:
curl https://qsa.sh
See how it works, what we do and don't retain, or what the paid tiers add.