September 23, 2026
v0.12.0@sixthwall packages 0.12.0
Added
sixthwall probe --recon: what of yours is on the internet that you forgot about. For a verified domain, subfinder lists the subdomains public sources know, httpx checks which answer over HTTP (status, title, technology), and naabu connect-scans twenty database and admin ports on up to a hundred hosts. Findings: an open PostgreSQL, MySQL, MongoDB, Redis, Elasticsearch, Docker or RDP port (severity by what listens there, Docker without TLS is critical), and live hosts whose names say staging, admin, backup, phpmyadmin and the like. Each comes with the compose or firewall change that closes it. All three tools are MIT and installed withsixthwall tools install subfinder httpx naabu; a connect-scan sends nothing to the service.
v0.13.0@sixthwall packages 0.13.0
Added
- Syntax-tree rules. Rules can now use
strategy: ast-grepand describe code by structure instead of by text:$FN($CMD, $$$)with constraints on what$FNand$CMDmay be. Whitespace, line breaks and formatting stop mattering, and a member call such asre.exec(input)can never be mistaken forexec(input). Powered by ast-grep (MIT) with the same JavaScript, TypeScript, TSX and Python parsers;{{tainted}}works inside constraint regexes exactly as in text rules, and a rule can keep a fewtext_patternsfor shapes a tree pattern expresses badly. - AI-CMD-001 (shell commands built from variables) is the first rule written this way. It catches commands concatenated from several template pieces across lines, matches the previous version finding for finding on a real project (9 of 9), and can no longer confuse
RegExp.prototype.execwith a shell.
v0.12.0@sixthwall packages 0.12.0
Added
- Four rules chosen by the weekly digest, 63 in total. The first
pnpm digestrun listed the weaknesses reported this week that no rule covered; these close the top three. Regular expressions that can run forever, through nested repeats such as(\w+)+or a RegExp built from request data, for JavaScript (AI-REDOS-001) and Python (AI-PY-REDOS-001). XML from the request parsed with the standard library or lxml without defusedxml (AI-PY-XXE-001). Express logins that write the user into the session without regenerating the session id (AI-SESSION-001). Each has positive and negative tests and was checked against seven local projects before shipping.
Websitesixthwall.dev
Added
/badge: the README security badge, with the embed code and an honest note that the number is the project's own statement until pull-request scanning verifies it./api/badge?score=Nserves the SVG.- The vulnerability wall now covers PyPI advisories alongside npm, links pip advisories to the matching Python rules, and shows the CISA Known Exploited Vulnerabilities added most recently, the list of what attackers are using this week.
- Full audits and reports. From a repository in the dashboard, "Run full audit" scans the whole default branch (downloaded as an archive, never cloned, deleted after the scan) with the repository's own config and ignore file, records findings and the score, and produces a self-contained HTML report you can open, download, share or print to PDF. Every scan, pull request or audit, now has its own page with all findings.
- Dashboard. Sign in with GitHub at
/dashboardand see every repository the App scans for your installations: score, scan history, the latest scan's findings with Fix Packs (owners only), and settings for which severities fail the check, whether the badge is public, whether pull requests are scanned automatically, and rules to ignore everywhere. Sessions are a signed cookie; no account is stored. The dashboard preview with sample data is gone. - Every AI crawler is named and allowed in robots.txt (GPTBot, OAI-SearchBot, ClaudeBot, PerplexityBot, Google-Extended and the rest), badge images are allowed so READMEs can embed them, and
pnpm indexnowsubmits the sitemap to the IndexNow engines (Bing, which feeds ChatGPT search and Copilot, plus Yandex, Seznam and Naver) after every deploy. Verified separately that Cloudflare does not block any of these crawlers. /docs/github-app: what the GitHub App does on a pull request, what it stores, the verified badge, and the install link. Pull request scanning is a free beta; the landing page and FAQ say so.- The GitHub App reads the repository's own
.sixthwall.yaml(ignored rules, excluded paths, block_on) and.sixthwall/ignoreat the scanned commit, so a finding reviewed locally is silent in the pull request too. The ignore-file parser moved into@sixthwall/coreso the CLI and the App share one implementation. - Layer 2 groundwork: the GitHub App backend. Three new private packages:
@sixthwall/db(Drizzle schema and migrations for installations, repos, scans, findings, score history),@sixthwall/api(Hono: signed webhook intake with redelivery protection, job queueing, public project summaries) and@sixthwall/workers(BullMQ: fetches only a pull request's changed files at the head commit, scans them with the same engine as the CLI, maps findings onto the diff, posts a check run with line annotations and one comment updated in place, stores metadata only). Postgres and Redis join the compose stack on an internal network. The site forwards/api/webhooks/githubto the API, serves a verified badge at/api/badge/gh/<owner>/<repo>and a public project page at/gh/<owner>/<repo>. The App itself is registered next; until then nothing is reachable. pnpm digest: a script for the team that pulls CISA KEV, the week's npm and PyPI advisories, new nuclei templates and the Georgia Tech tracker of AI-attributed CVEs, maps every weakness to our rules and prints the gaps first. This is how new rules get chosen.
Changed
- Security headers (HSTS, CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy) on every response and a permanent redirect from http to https, both found by running
sixthwall probeagainst our own site.
v0.11.0@sixthwall packages 0.11.0
Added
sixthwall tools: optional open-source binaries, installed on request.sixthwall tools install gitleaks nucleidownloads pinned releases (gitleaks 8.30.1, nuclei 3.11.1, both MIT) from the projects' GitHub release pages, verifies each archive against the release checksum file, and keeps the binaries in~/.sixthwall/bin. Nothing runs unless installed; the scanner never depends on them.- gitleaks inside
sixthwall scan. With gitleaks installed, its ~150 secret detectors run on the same files (full, directory, staged and diff modes). A line our own rules already reported is shown once and credited to both; new hits arrive as findings with redacted evidence, a severity based on whether the provider is known, and a Fix Pack. sixthwall depscovers Python.uv.lock,poetry.lock,pdm.lock,Pipfile.lockand exact pins inrequirements.txtare read alongside the JavaScript lockfile, and PyPI packages are checked against OSV with the matching ecosystem. Fixes suggest thepip,uvorpoetrycommand.- Findings listed in
.sixthwall/ignoreno longer count against the score (they were filtered from the output but not from the number). Ignore entries now accept every rule id shape, includingAI-PY-*,AI-IAC-*,GITLEAKS-*,NUCLEI-*andPROBE-*. - Test files are skipped by default in every scan mode:
__tests__/,*.test.*,*.spec.*,test_*.py,*_test.pyandconftest.py. Fake keys and deliberately bad snippets live there on purpose and are not what ships. A folder named explicitly as the scan target is still scanned in full. - README badge.
sixthwall.dev/api/badge?score=87returns a shields-style SVG coloured by score band (Excellent, Good, Needs work, At risk), or a neutral "scanned by sixthwall" badge without a score. The CLI prints the exact Markdown line after every full scan, the MCP server includes it in its score output, and/badgeexplains the three steps and the honest limit: the number is the project's own statement until pull-request scanning verifies it. sixthwall probe --deep. With nuclei installed, the probe adds a curated template set: exposures, misconfigurations, default logins, tokens, backups and CISA known-exploited CVEs. Intrusive, fuzzing and denial-of-service templates are excluded, requests are rate-limited, and the run has a hard timeout. Each match becomes a finding with the template's description, references and a prompt for your AI tool. Domain verification applies exactly as for the basic probe.
v0.10.0@sixthwall packages 0.10.0
Added
sixthwall probe <url>: the first Layer 3 slice, read-only checks against a deployed site you own. Security headers (HSTS, CSP, X-Content-Type-Options, framing, Referrer-Policy, Permissions-Policy, server version disclosure), cookie flags on session cookies, certificate validation and the http→https redirect, downloadable.env,.git,.npmrc, key and dump files, credentialed CORS for any origin, secrets and source maps with original code in the front-end bundle, GraphQL introspection, public API docs, Spring/Django/Laravel/Symfony/Go debug endpoints and Prometheus metrics, and directory listings. Every finding carries a Fix Pack with the exact header value or config change, and the run ends with a live app score.- Domain ownership is verified before a single request is sent.
sixthwall probe verify example.comprints a DNS TXT record (_sixthwall.example.com→sixthwall-verify=<token>) and checks it; a record on a domain covers its subdomains; loopback addresses need no record. The token lives in.sixthwall/domains.json. - The probe is bounded on purpose: GET requests plus one fixed GraphQL introspection POST, under 80 requests, 10 s per request, 2 MB per body, a clear User-Agent, and requests go only to the host named. Nothing is sent to SixthWall. Stated on the privacy and security pages.
- Tests run the checks against local HTTP servers: a careless deployment must produce each planted finding exactly once, a tidy one must produce none, and a down host must explain itself instead of reporting.
- Verification asks the system resolver first and then 1.1.1.1 and 8.8.8.8, because a record added a minute ago is usually invisible to the local resolver that cached the first "no such record" answer.
v0.9.0@sixthwall packages 0.9.0
Added
- NestJS rules, 59 rules in total. A controller handler that changes data with no guard in the file and no global guard in the project (AI-NEST-001); an app that starts without a ValidationPipe, or with one that lacks
whitelist: true(AI-NEST-002); a JWT strategy withignoreExpiration: trueor a secret written in the code, including theprocess.env.X || 'dev-secret'fallback (AI-NEST-003);@Body()typed as any or not at all (AI-NEST-004); login, register, reset and OTP handlers with no throttling anywhere in the project (AI-NEST-005). - Project-wide guards. Rules can declare
unless_project_present; the scanner checks the regex against every source file under the project root, so a guard registered once asAPP_GUARDin app.module.ts is respected when scanning a controller in another file. Diff and watch scans use the repository root, so they see it too. - Data-flow tracking treats NestJS decorated parameters (
@Body() dto,@Query('q') q,@Param('id') id), Koa'sctx.query/ctx.params/ctx.request.bodyand Hono'sc.req.json()/c.req.query()as request data, so the injection rules follow them. - Fastify, Koa and Hono apps count as app entries and auth routes for the existing helmet, rate-limiting and webhook rules;
@fastify/rate-limit,koa-ratelimitand@nestjs/throttlersatisfy the rate-limit check. - Three NestJS fixtures enforced by the precision suite: safe (zero findings), global-guard (zero findings), vulnerable (fires every NestJS rule plus SQL injection through a decorated parameter).
v0.8.0@sixthwall packages 0.8.0
Added
- Dockerfiles and docker-compose files are scanned, with 8 infrastructure rules, 54 rules in total. Dockerfile: the final stage runs as root (AI-IAC-001), base image on
:latestor untagged (AI-IAC-002), secrets baked in through ENV, ARG or a copied .env or key file (AI-IAC-003), a downloaded script piped into a shell or curl with certificate checks off (AI-IAC-004), world-writable permissions (AI-IAC-005). Compose: secrets written as literal values (AI-IAC-006), database and admin ports published on every interface (AI-IAC-007), privileged mode, the Docker socket, host networking or broad capabilities (AI-IAC-008). Each rule ships with positive and negative test cases and a fix that keeps the deployment working. - File discovery picks up
Dockerfile,Dockerfile.*,*.dockerfile,docker-compose*.ymlandcompose*.yml, with#comments ignored. Files whose names contain dev, local or test are exempt from the compose secret and port rules, since publishing Postgres to localhost on a laptop is the point of those files. - Safe and vulnerable infrastructure fixtures, enforced by the precision suite.
v0.7.0@sixthwall packages 0.7.0
Added
- Python support: 13 rules for Flask, FastAPI and Django, 46 rules in total. SQL built with f-strings, format() or concatenation (AI-PY-INJECT-001); shell commands from variables through os.system or shell=True (AI-PY-CMD-001); hardcoded API keys and passwords, including Django's generated secret key (AI-PY-SECRET-001); debug mode on (AI-PY-CONFIG-001); CSRF protection off (AI-PY-CONFIG-002); CORS open to every origin (AI-PY-CORS-001); pickle, unsafe yaml.load, eval and exec on request data (AI-PY-DESER-001); file paths built from the request (AI-PY-PATH-001); server-side fetches of caller-supplied URLs (AI-PY-SSRF-001); MD5 or SHA-1 for passwords, tokens from the random module and JWTs decoded without verification (AI-PY-CRYPTO-001); certificate checking switched off (AI-PY-TLS-001); HTML built from request data (AI-PY-XSS-001); routes that change data in a file with no sign of authentication (AI-PY-AUTH-001). Every rule ships with positive and negative test cases.
- Data-flow tracking for Python. The same variable tracking added for JavaScript in 0.6.0 now understands Python assignments, Flask and Django request accessors,
request.get_json()and FastAPI'sawait request.json(). It stops atint(),secure_filename, schema validation, ORM lookups and table lookups keyed by request data, socol = COLUMNS[request.args.get('sort')]is not treated as attacker text. - Safe and vulnerable Flask fixtures, enforced by the precision suite: the safe app produces zero findings and the vulnerable app fires all 13 rules.
Changed
venv/,site-packages/and.tox/are ignored by default, alongside.venv/and__pycache__/. A first run on a real project reported ten findings inside vendored copies of requests, urllib3 and pip.- A SQL f-string that also passes a parameter tuple is treated as parameterized; only the data-flow patterns apply to it. This removed nine false alarms on a project that builds WHERE clauses from allow-listed fragments and binds every value.
- Patterns that combine a
{{tainted}}alternative with static alternatives now keep matching the static part in files where nothing is tainted.
v0.6.0@sixthwall packages 0.6.0
Added
- Intra-file data-flow tracking for the injection rules. The scanner now follows request data through local variables inside a file. Until now
db.query(...${req.params.id})was caught but the way AI tools actually write it,const status = req.query.status;a few lines aboveconst stmt =SELECT ... ${status};andpool.query(stmt), was not. Sources are Express, Koa and Hono request objects, Next.jsawait req.json(),searchParams.get()and routeparams, including destructuring and renames; taint propagates through templates, concatenation,+=and helper calls, and stops at casts (Number,parseInt,String), schema validation (zod,yup,Joi),path.basename, escaping and sanitising, and at database lookups keyed by the value. Six rules use it: SQL injection (AI-INJECT-002), command injection (AI-CMD-001), path traversal (AI-PATH-001), SSRF (AI-SSRF-001), NoSQL injection (AI-NOSQL-001) and reflected XSS (AI-XSS-001). - Rule patterns can use a
{{tainted}}placeholder, expanded per file to the variables that hold request data. Files with no request data skip those patterns entirely, so scan time is unchanged. - Promisified
exec(execAsync,execPromise) with a template is now reported by AI-CMD-001. - New fixture
express-taintwith one indirect flow per rule, enforced by the precision suite alongside the safe fixtures, which still produce zero findings.
Changed
- AI-INJECT-002 ignores tagged templates such as
sql`...`andprisma.$queryRaw`...`in the new patterns; those are parameterized. - Command-line arguments are deliberately not a taint source: a script that opens the file named on its command line is doing its job, and treating that as path traversal produced three false alarms on a real project.