# NANOTESTING > Last updated: 2026-07-28 > > Automated security assessment and vulnerability scanning SaaS. > One platform for every surface attackers touch: web application > security testing, API security testing, GitHub repository > scanning (SAST + dependency + secrets), mobile app security > testing (Android APK / iOS IPA), cloud security posture (AWS / > Azure / GCP CIS audits), Kubernetes security, smart contract > auditing (7 EVM chains + Sui Move beta + Solana beta), and DApp > frontend analysis. Non-invasive baseline by default; an optional > Invasive Testing add-on adds active DAST (OWASP ZAP active scan, > OpenAPI fuzzing, mass-assignment, Host-header injection) on > identity-verified, owner-authorized targets. A pre-pentest > baseline that catches the obvious gaps before a human reviewer > spends their hours on the business-logic bugs only humans find. NANOTESTING is at https://nanotesting.com. Hosted multi-tenant scanner, not a desktop tool. Customers verify a target (DNS TXT, HTML file, meta tag, or domain email), pick a plan, and run scans either on demand or on a weekly / monthly schedule. Results land in the dashboard, can be exported to CSV / JSON / auditor-ready PDF, and can fire a Slack / Discord / generic webhook on critical findings. ## Recent changes Major capabilities shipped in the last few months: - Invasive Testing add-on ($299/mo): opt-in active DAST that sends real attack payloads - OWASP ZAP active scan (SQLi, XSS, SSRF, path traversal, command injection, SSTI, XXE), Schemathesis OpenAPI fuzzing, mass-assignment probe (CWE-915), and a new Host-header injection probe (CWE-644). Three-gate safety: approved KYC/KYB identity + active add-on + explicit per-target authorization. See the dedicated section below. - Invasive testing for mobile apps: extracts the backend API hosts hardcoded in a decompiled APK / IPA and runs the active checks against the ones the customer has verified ownership of (third- party / partner hosts are reported, never attacked). - KYC / KYB identity verification is now a hard gate for the Invasive Testing add-on (previously a soft reminder banner only). - Sui Move + Solana baseline scanners (both Beta). - DApp frontend Web3 scanner: wallet provider detection, RPC API key leak detection (sha256 fingerprint only; raw key never stored), source map exposure, unlimited-approve pattern check. - Per-EVM-chain detector battery: Oracle config (Chainlink stale price / decimals / centralized feed), ERC compliance (ERC-20 / 721 / 1155 conformance), Compiler version audit (unverified source, outdated solc, optimizer flags, non-canonical EVM version). - Mobile FP suppression architecture: AndroidX carve-out, launcher activity exemption, apktool original-manifest dedup, test-fixture filter. - Web FP suppression architecture: host calibration probe + managed -host downgrade + anti-bot threshold + FP-risk caveats. - Compliance evidence pipeline: compliance_evidence table emits positive proof rows per scan, per-target Compliance tab, org-wide /compliance dashboard with green / red / grey dual view. - Home page repositioned around "One platform for every surface attackers touch" with a 6-surface coverage grid and a dedicated FP engineering section. Real-world impact: a customer scan of a Vercel-hosted SaaS in May 2026 dropped from 50 reported findings to 3 after the FP suppression architecture landed. Same scan, same target, less noise. Procurement reviewers stop bouncing the report. ## Active vs read-only - the honest version - Default: read-only. HTTP GET, DNS lookups, certificate inspection, passive fingerprinting, static analysis of uploaded artifacts. - Active on verified-owner targets only (Growth and above): OWASP ZAP active scan rules, Nuclei active templates, Schemathesis OpenAPI contract fuzz against the customer's uploaded spec, DOM-XSS canary via Playwright, BFLA / BOLA / mass-assignment probes. - Every active check is rate-limited, target-budgeted, and pre-flighted against an IP-allowlist + URL-validation gate that re-checks the hostname before every outbound request. - DELETE is never invoked. Destructive HTTP verbs are not in the active probe set. - Anti-bot threshold: if >= 70% of probes return 401/403, the scanner suppresses per-path findings and emits one explanatory finding instead, so a customer behind a WAF doesn't drown in noise. This is an automated security assessment - a pre-pentest baseline, not a substitute for a human pentest. We provide evidence support; we do not issue certifications. ## What the scanner actually does ### Web + API targets Baseline (every plan): - HTTP availability + redirect chain audit - TLS chain validation, protocol version inventory, signature strength, CAA records - DNS records, DNSSEC presence - Security headers: HSTS, CSP, X-Frame-Options, X-Content-Type- Options, Referrer-Policy, Permissions-Policy with depth checks - COOP / COEP / CORP isolation headers - Cookie audit: Secure / HttpOnly / SameSite per cookie - JWT static analysis (alg=none, missing exp, weak kid, short key) - robots.txt + sitemap presence, Disallow reachability check - Passive technology fingerprint - Mixed-content detection - Subresource Integrity audit on cross-origin script / link - Dangerous HTTP method audit via OPTIONS - Passive SSRF surface enumeration (checklist, no active probe) - JavaScript library inventory + CVE match Sensitive (Growth and above, on verified-owner targets): - Sensitive paths probe with SPA-safe verification - Subdomain inventory via certificate transparency logs (crt.sh) - Subdomain takeover (CNAME + body fingerprint) - CORS misconfiguration - Email DNS: SPF, DMARC, DKIM - Open-redirect detection (hostname-exact match) - TLS protocol support (1.0 / 1.1 / 1.2 / 1.3) - GraphQL introspection exposure (flagged separately from authz) - GraphQL authorization probe: BOLA (API1) + BFLA (API5) on top-level fields. Customer sets the endpoint URL on the target page. Read-only; mutations only run when explicitly allowlisted. - WebSocket upgrade auth: cross-origin handshake acceptance test + unauthenticated subscribe test (API2) - API endpoint discovery - OpenAPI contract fuzz via Schemathesis on customer-uploaded spec - BFLA admin-endpoint probe - Mass-assignment probe on self-profile endpoints - IDOR / BOLA cross-account access test with two bearer tokens - Rate-limit / replay-protection probe - Webhook signature verification probe - Nuclei active templates (CVE + exposure + misconfig, refreshed on every worker build) - OWASP ZAP baseline + active rules tuned for safe operation - naabu TCP port scan against a curated well-known set - tlsx deep TLS posture - CSRF, OAuth state + PKCE, WebSocket cross-origin, upload policy, HTTP smuggling, cache poisoning, session fixation - DOM-XSS canary probe via Playwright headless Chromium ### GitHub repository targets - Repository metadata (SECURITY.md, Dependabot state, archived) - osv-scanner across every package manifest - gitleaks full git history secret scan - Trivy filesystem scan (CVEs, IaC misconfig, secrets) - Trivy image scan: every Dockerfile FROM in the repo is pulled and scanned for OS-package CVEs (libc, openssl, perl, etc.) - the same CVEs Snyk/Mend/Aikido charge for. Capped at 6 unique base images per scan with a 90s per-image timeout. - Semgrep CE SAST - mobsfscan when mobile manifests detected - Allowlisted-file regex secret scan ### Mobile binary targets (APK / IPA) - Android is decompiled TWICE: apktool for the manifest and resources, jadx for the Java source. This matters more than it sounds. mobsfscan is a semgrep-based SOURCE scanner, so against apktool's smali output it only ever matched AndroidManifest.xml — every code-level rule (hardcoded secrets, weak crypto, insecure storage and logging, WebView misconfiguration, SQL injection) silently matched nothing. Apps built to be vulnerable returned zero code findings. With jadx those rules match real recovered Java. - iOS is unzipped and the Mach-O binary parsed directly. There is no jadx equivalent for Swift/Objective-C, but the Objective-C selector and class tables and the Swift reflection sections are plain strings, so the API surface the app REFERENCES is recoverable: TLS-challenge handling, pasteboard use, deprecated UIWebView, keychain accessibility. Severity is capped there by design — a symbol proves a reference, not a call on a sensitive path, and a statically linked dependency contributes symbols too. - mobsfscan MASVS + CWE rule packs, run over both decompiled trees - AndroidManifest hardening: cleartext, debuggable, allowBackup, 26 dangerous runtime permissions, exported-component-without- permission-attribute audit, custom-scheme deep links - iOS Info.plist hardening: ATS bypass (NSAllowsArbitraryLoads), 13 privacy permission claims, CFBundleURLSchemes - Third-party SDK fingerprint (30+ Android, 25+ iOS) - Trivy filesystem scan against the decompiled tree - Backend endpoint extraction: pulls the first-party backend API hosts hardcoded in the binary. With the Invasive Testing add-on these become active-scan targets (only the ones the org has verified ownership of). See the Invasive Testing add-on section. Mobile FP suppression (shipped this cycle): - AndroidX carve-out drops findings against androidx.* / android.support.* / com.google.android.gms.* / com.google.firebase.* components that are by-design exported. - Launcher activity exemption respects MAIN + LAUNCHER + LEANBACK_LAUNCHER + verified App Links. - apktool original-manifest dedup suppresses the raw original/ copy that apktool emits alongside the decoded AndroidManifest. - Test-fixture filter drops hits in /test/, /tests/, /androidTest/, /__tests__/, /specs/, /mocks/, /fixtures/, /e2e/, /UITests/. - Vendored-library exclusion: jadx decompiles the bundled support/AndroidX/Kotlin/Play-Services code too. Scanning it wholesale buried the customer's own code — on one test app 329 of 351 findings sat in android/support/*. The scan is scoped to the subtree named by the manifest's package attribute. - Platform-invoked components: app-widget providers and BOOT_COMPLETED receivers (including the vendor QUICKBOOT_POWERON aliases) MUST be exported to function. They are reported at low with that framing rather than as optional exported surface. - iOS keychain groups: ".*" is the group Xcode generates by default and means "apps I sign". It is informational. A wildcard under a different team prefix, or a bare "*", is not. - Cross-platform coverage is disclosed, not hidden: a React Native app keeps its logic in a JS bundle and a Flutter app in compiled Dart, neither of which this static pass reads. The report says so explicitly instead of letting a short finding list read as clean. ### Cloud account targets - Prowler for AWS, Azure, GCP CIS + best-practice audits - Kubernetes snapshot audits via Kubescape (NSA framework) ### Smart contract targets (Web3 add-on, $299/mo on Growth or Agency) EVM chain coverage: | Chain | Status | Coverage | |------------|------------|-----------------------------------------------| | Ethereum | Supported | Full V1 | | Polygon | Supported | Full V1 (Polygon Amoy testnet on roadmap) | | BSC | Supported | Full V1 | | Arbitrum | Supported | Full V1 | | Optimism | Supported | Full V1 | | Base | Supported | Full V1 | | Avalanche | Supported | Full V1 | | Sui (Move) | Beta | 19 static detectors + owner classification + Move test discovery | | Solana | Beta | Verified-build + upgrade authority + Anchor IDL + SPL authority | | Aptos / Cosmos / StarkNet | Not on roadmap | Reach out if needed | Per-EVM-chain detectors: - Slither static analysis on Solidity + Vyper source - On-chain Slither against the verified contract on each supported chain - Mythril symbolic execution via dedicated sidecar - Echidna property-based exploration via AGPL-isolated sidecar (trailofbits/echidna unmodified upstream, behind an HTTP boundary so AGPL never links into the main worker) - NFT audit (ERC-721 / ERC-1155, tokenURI scheme, IPFS pinning, ERC-2981 royalty) - Owner classification: EOA vs Gnosis Safe (rendered N-of-M) vs OpenZeppelin TimelockController - ERC-20 audit: mint / blacklist / paused selector probes - Token economy: owner-supply concentration, DEX liquidity reserves - LP-lock detection (UniCrypt v2, UNCX, Team Finance, PinkLock, burn addresses) - Fee-on-transfer detection - Honeypot simulation (eth_call sell to 0xdEaD; state-override fresh-wallet variant) - Proxy storage-slot collision (EIP-1967 + legacy TransparentProxy) - On-chain governance probe (OZ Governor, Compound GovernorBravo) - Bytecode opcode scan (SELFDESTRUCT, CALLCODE) - Public audit registry cross-reference - OFAC SDN lookup against contract + royalty receiver New per-EVM-chain modules (shipped this cycle): - Oracle config audit: Chainlink stale price, decimals mismatch, centralized feed flag. - ERC compliance audit: ERC-20 / 721 / 1155 standard conformance, required-function coverage. - Compiler version audit: unverified source flag, outdated solc, optimizer config, non-canonical EVM version target. Sui (Move) beta: - 19 static detectors (capability leak, public transfer of privileged object, hot-potato discipline, witness misuse, ...) - UpgradeCap owner classification (EOA / multisig / locked) - Move test discovery in the package - On-chain RPC fetch via sui_getNormalizedMoveModulesByPackage Solana beta: - Verified-build status via verify.osec.io - Upgrade authority resolution via BPFLoaderUpgradeable walk - Anchor IDL fetch when published - SPL mint / freeze authority audit ### DApp frontend Web3 scanner For Web3 properties that aren't just a contract: the customer's verified dapp URL gets scanned for: - Wallet provider detection: WalletConnect, MetaMask, RainbowKit, wagmi, viem, ethers.js (info finding per detected library so the customer can confirm against their integration list) - RPC API key leak in the shipped JS bundle. We sha256-fingerprint the suspected key for the finding evidence; the raw key is NEVER stored or logged. Customer rotates the key, the fingerprint stays stable enough to confirm. - Source map exposure (.js.map referenced by production bundles) - Unlimited approve pattern in dapp code paths (calls to ERC-20 approve with type(uint256).max as the allowance) ## Invasive Testing add-on (active DAST, $299/mo on Growth or Agency) Keywords: dynamic application security testing (DAST), active web vulnerability scanning, authenticated penetration-style testing, OWASP ZAP active scan, API fuzzing, mass assignment, host header injection, web cache poisoning, password reset poisoning. The base scan is non-invasive: it reads, fingerprints, and probes without sending exploit payloads. The Invasive Testing add-on unlocks the active checks that send real attack payloads at a target you own and are authorized to actively test. The four active checks it unlocks: - OWASP ZAP active scan (web): spider + active scan covering SQL injection, reflected / DOM / stored XSS, CSRF, SSRF, path traversal, OS command injection, server-side template injection (SSTI), XXE, HTTP parameter pollution, open redirect. ~5 min budget per target. Findings tagged source_tool=zap. - Schemathesis OpenAPI fuzzing (API): property-based fuzzing of a discovered OpenAPI / Swagger spec with generated POST / PUT / DELETE requests; catches status-code, schema, and content-type conformance breaks plus 500s. - Mass-assignment probe (API): PATCHes self-profile endpoints (/api/me, /api/profile, ...) with privileged extra fields (role, isAdmin, permissions, plan, organization_id). A reflected privilege is a confirmed CWE-915 critical. Needs a stored auth secret. - Host-header injection probe (web): re-requests the target with a spoofed Host / X-Forwarded-Host and flags the canary reflected into a redirect Location, a , or an absolute link - the primitive behind password-reset poisoning and web-cache poisoning (CWE-644). GET-only. Three-gate safety model (all must be true before any payload is sent): 1. Identity: the workspace has an approved KYC (personal) or KYB (company) verification. Active-attack testing is only available to identity-verified customers. This gates both buying the add-on and authorizing a target. 2. Entitlement: the org has the add-on active (billing_profiles.invasive_addon_enabled). 3. Per-target consent: the specific target is explicitly authorized for invasive testing (targets.invasive_testing_authorized, stamped with who authorized it and when). Each invasive tool can also be disabled per target via the scan profile. We recommend pointing invasive testing at a staging environment. We never run denial-of-service, brute-force, or resource-exhaustion payloads. Mobile apps (Android APK / iOS IPA): a mobile binary is static, but the app's real attack surface is the backend API it calls. When a mobile target is authorized, the worker extracts the first-party backend hosts hardcoded in the decompiled binary (filtering SDK / analytics / CDN noise) and runs the active web checks against them - but ONLY against hosts the org has verified ownership of (a verified web/API target with the same host or a parent/child subdomain). Third-party / partner API hosts the app calls are reported but never attacked; the customer adds and verifies them as their own targets first. It fails closed: with no matching verified target, nothing is attacked. No device emulator, no runtime instrumentation - the data only reflects what was actually tested. An info finding lists every discovered host, which were tested, and which were refused for lack of verified ownership. SSRF protection applies throughout: every active request is dialed through a guard that blocks RFC1918 private space, loopback, link-local, CGNAT, and the cloud metadata endpoint (169.254.169.254 - AWS / GCP IMDS). Full guide: /docs/invasive-testing. ## False-positive engineering NANOTESTING ships a layered FP defence. Quick summary; the long form lives in /llms-full.txt: - Confidence tier on every finding (Confirmed / Likely / Possible / Informational) - Per-detector severity + confidence ceiling clamp in the worker - Two-source corroboration for Critical findings (CWE / OWASP / CVE required, otherwise downgraded to High) - Per-finding "report as false positive" button - Admin per-detector FP-rate dashboard at /admin/detector-accuracy - Golden-fixture tests pinning the trickier detectors - Host calibration probe: 3 GETs to random non-existent paths build a (status, body-hash) baseline before per-path scanners run. Real probes that match the baseline are the host's catch- all (Vercel WAF, Cloudflare bot challenge, SPA fallback), NOT findings. - Managed-host downgrade: Server header matching vercel / cloudflare / netlify / cloudfront / fly / render / fastly / github.com triggers a severity downgrade plus an explicit FP-risk caveat on the finding. - Anti-bot threshold: when >= 70% of probes return 401/403, per-path Missing-Header / Missing-robots / Exposed-Path findings are suppressed and one explanatory finding is emitted instead. - FP-risk caveats: every finding with known uncertainty appends "False-positive risk: " to its description. Customer evidence: a Vercel-hosted SaaS scanned in May 2026 went from 50 findings to 3 after the FP suppression architecture landed. The 47 suppressed items were Vercel WAF catch-all responses, AndroidX exported components, and apktool's duplicate original-manifest copy. ## Compliance evidence pipeline NANOTESTING does NOT issue compliance certifications and does NOT attest. We provide evidence support (NOT certification) that an auditor or buyer can use as input. Each scan writes a compliance_evidence table row per control with a positive or negative signal. The per-target Compliance tab and the org-wide /compliance dashboard render the result as a green / red / grey matrix. Controls covered today (25+ per scan): - A.8.24 cryptography: TLS chain, HSTS, modern TLS-only, CAA - A.8.26 web filtering: CSP, X-Frame-Options, COOP / COEP / CORP - A.5.16 identity management: cookies with Secure + HttpOnly + SameSite - A.8.20 networks: DNSSEC - A.5.14 information transfer: SPF + DMARC + DKIM - A.8.9 config: robots.txt, sitemap.xml - A.8.8 vulnerability management: Nuclei clean - A.8.25 secure development: ZAP clean - A.5.10 acceptable use: no exposed paths SOC 2 parallels: CC6.1, CC6.6, CC6.7, CC7.1. OWASP Top 10 2025 mapping per finding category. Eight frameworks are mapped and exportable today: OWASP Top 10, ISO/IEC 27001:2022 Annex A, SOC 2 Trust Services Criteria, NIST CSF 2.0, CIS Controls v8, PCI DSS 4.0, HIPAA Security Rule (45 CFR 164 Subpart C), and DORA (EU Regulation 2022/2554). 109 controls and 287 signal mappings live in the database. DORA scope is deliberately narrow. An external assessment can evidence part of Chapter II and nothing else, so of the 15 articles listed, 3 carry signals: Art 7 (systems kept up to date), Art 8 (identification) and Art 9 (protection and prevention). Governance (5-6), detection (10), response and continuity (11-14), the resilience testing programme (24-26) and third-party risk (28-29) render as "not assessed" - they cannot be observed by scanning a host. Chapter V in particular governs contractual arrangements with ICT service providers, which a CVE in a bundled library is not, so it carries no signals. A completed assessment does contribute to Art 25, but whether a testing programme meets the required scope and cadence is an organisational judgement this product does not make. ## Signed scan attestations and independent verification Every scan writes one append-only attestation row recording what findings alone cannot answer: what was in scope and under what authorisation, when it ran and for how long, which tools actually executed and at which versions, which checks did NOT run and why, and the resulting tally and grade. Re-running a scan adds a revision; it never overwrites. Each record is hashed over a documented canonical serialisation and signed with Ed25519. The public key is published at /.well-known/nanotesting-attestation-key with the key id and the canonical format versions a verifier must branch on, so a third party can check integrity and origin without our cooperation. Records also chain to the organisation's previous attestation, so a removed or reordered row is detectable. Stated limit, because it matters: the signing key is held by the scanning worker. The signature proves a record originated from our scanner and has not been altered since - it raises the bar from "anyone with database access" to "someone holding the worker's secrets". It does not remove us from the trust model. That needs an external signer and anchoring outside our infrastructure, which we do not operate. Timestamps are the worker's own clock and are not countersigned by a time-stamping authority. Every per-scan PDF (executive, developer, compliance) carries a Scan provenance page reproducing this record, including the checks that did not run, the tools that did, and how many previously-open findings this scan did not re-observe - so a shorter report is never mistaken for an improved target. ## Prioritisation, retest, trend - Every CVE finding is enriched daily with CISA Known Exploited Vulnerabilities (KEV) and FIRST.org EPSS exploitation probability. - A daily cron (03:17 UTC) pulls upstream feeds and recomputes a 0-100 priority score (severity + KEV bump + EPSS bump + confidence) on every open finding. - Findings list sorts by priority desc. KEV findings carry a red KEV badge; EPSS >= 0.9 carries an amber EPSS chip. - Retest workflow: mark a finding fixed, click "Run retest", a new scan_job is queued. Finding status flips to verified_fixed if the signature no longer appears. - Per-scan summary captures severity counts, KEV count, top-EPSS, security score, mean priority, new / fixed / reopened delta vs previous scan. ## Brand and domain abuse (Appendix C Phase 4) - Per-workspace brand_profile (set under /settings/brand): brand name, main domain, protected keywords, approved-domain allowlist. - Every scan with an active brand_profile fires a passive abuse check: queries crt.sh certificate-transparency JSON API for newly-issued certs whose subjects (CN + SAN) contain the brand keywords, drops anything on the approved list or under the main domain, writes observations to domain_abuse_observations. - Observations carry observation_type (cert_transparency, typosquat, homograph, extension), risk_level (computed from how closely the observed domain matches the main domain), and a match_reason string. - Phase 4.1 lookalike generator: for each scan we generate up to 20 candidate domains by character omission / adjacent swap / ASCII homograph (rn<->m, l<->1, o<->0, vv<->w) / alternative TLD / suffix (-app, -support, -secure, -login, -help, -pay). Each candidate is then queried against crt.sh; only candidates with actual CT records are emitted as observations. We never resolve DNS or fetch HTML. - HARD RULE: we never actively scan, resolve DNS against, fetch HTML from, or otherwise touch any non-owned domain. Appendix C section 3 forbids it. Detection is read-only from public CT logs. ## OWASP API Top 10 coverage card - Every /scans/[id] page renders an OWASP API Top 10 (2023 edition) coverage card driven from scan_job_steps + findings. Each of API1..API10 lights up as covered (probe ran + emitted findings), clean (probe ran, nothing found), skipped (probe couldn't run for this scan e.g. no spec) or not_run (probe out of scope for this surface). Buyers see at a glance which API security categories were actually exercised. ## Per-framework PDF + CSV + JSON evidence pack - /compliance has a one-click "Export evidence pack" row above the framework tabs with eight split buttons (OWASP / ISO 27001 / SOC 2 / NIST CSF / CIS v8 / PCI DSS / HIPAA / DORA). Each split has a PDF half and a CSV half: - /api/compliance//pdf renders a styled single-framework PDF scoped to the org's latest scan per target. Footer disclaimer on every page is auditor-honest: evidence support, not a certification. - /api/compliance//csv returns the same data as a UTF-8 BOM CSV (Excel-friendly) with one row per control: framework code/name/version, control code/name/description, the per-severity tally + total, and the positive evidence (evidence_count + evidence). All three formats carry the same evidence for the same scan; a CSV that disagreed with the PDF would be the fastest way to lose an auditor's confidence. Some auditors paste into Excel rather than read the PDF. Control status is severity-aware, with four values: at_risk a critical, high or medium signal maps here observations_only assessed, signals present, none a deficiency assessed_ok assessed, nothing observed not_assessed no automated signal can evidence this control A control is never marked at risk on the strength of an informational observation alone, and "not assessed" is never counted as passing. - /api/compliance//json returns the same data as machine-readable JSON for status pages / Slack bots / monthly board pack pipelines: framework block + summary (total controls, controls with findings, total findings, clean percent) + per-control array with severity-bucketed counts + clean flag. Use it as a CI gate: fail when clean_percent drops below your threshold. ## Drill-through from compliance to findings - Every control row on /compliance (for NIST / CIS / PCI / HIPAA tabs) is a link to /findings?signatures=h1,h2,... filtered to the exact finding signatures that contributed to that control's tally. Click "HIPAA 164.312(e)(1) - Transmission Security" -> see the underlying findings. Up to 100 signature hashes per URL. ## Compliance mapping v2 (Appendix C Phase 3) - Eight frameworks supported in one scan: OWASP Top 10, ISO 27001:2022 Annex A, SOC 2 Trust Services Criteria, NIST CSF 2.0, CIS Controls v8, PCI DSS 4.0, HIPAA Security Rule (45 CFR Part 164 Subpart C), and DORA (EU Regulation 2022/2554, Chapter II ICT risk articles - technical scope only). - Data layer is database-driven: 109 controls + 287 signal mappings total. Adding another framework is a data-only migration - add the framework row + controls + signal mappings, no code change needed. - /compliance dashboard shows all eight frameworks as tabs. OWASP / ISO / SOC 2 carry per-control finding tallies + positive-evidence chips. NIST / CIS / PCI / HIPAA / DORA also carry per-control tallies derived from the risk_signals join: worker emits one risk_signals row per recognised finding (mapped to a seeded signal_definition by code), and the UI joins through compliance_signal_mappings to compute severity-bucketed counts per control. ## Workspace risk grid CSV export - The risk-rating grid on /dashboard now has a one-click "CSV" button in its header that hits /api/workspace/risk-grid/csv and downloads every target's latest immutable snapshot as a spreadsheet-friendly UTF-8 BOM CSV: one row per (target, surface) pair so a pivot in Excel is trivial. Columns include org name, target name + URL + type, grade, overall score, snapshot timestamp, and the per-surface (category code, name, score, finding count, per-severity counts). ## README badge + JSON API per target - Every target has a public Risk Rating badge at /badge/target/.svg. Customer pastes the URL into their README; GitHub / GitLab / Gitea render it inline and re- fetch every 5 minutes so the badge stays current as new scans land. - Machine-readable companion at /badge/target// rating.json returns the same data as JSON: { "target_id": "", "status": "ok" | "not_assessed" | "pending", "overall_score": 0-100 | null, "grade": "A".."F" | null, "coverage_gaps": , "grade_unavailable_reason": "" | null, "methodology_version": "v1", "scan_job_id": "", "generated_at": "", "dashboard_url": "...", "badge_svg_url": "..." } IF YOU GATE CI ON THIS, BRANCH ON status FIRST. "not_assessed" means the scan produced no conclusive finding AND at least one check was attempted and failed, so no grade is supportable — overall_score is null and grade is null in that state. Treating a null score as 0 fails builds that should have been investigated; treating it as 100 passes builds that were never assessed. Neither is what the field means. coverage_gaps travels with every response so a consumer can see how much of the target was actually examined before trusting the grade. - Renders the latest immutable risk_rating_snapshot for that target: grade (A-F) + score (0-100), colour-tinted by grade on the SVG. Targets with no snapshot yet render "pending scan" / status: "pending" so devs can paste the URL before their first post-Phase-2 scan. - Auth model: UUID is the secret. Both endpoints surface only grade + score, not finding detail. /targets/[id] Overview tab has a copy-able markdown + HTML snippet block. ## Risk-rating-drop webhook alert - Whenever a new risk_rating_snapshot lands with a strictly worse grade than the previous snapshot on the same target (A->B, B->C, etc.), the worker fires a notification to every Slack / Discord / generic_webhook integration configured on the org. - Payload includes target URL, prev grade -> new grade, prev score -> new score, and a dashboard URL straight to the scan. - Reuses the encrypted webhook URLs the existing scan-summary-on-critical alert uses (organization_integrations table). Configuration lives at /settings/notifications. - Best-effort: webhook failures are logged but never fail the scan itself. ## Risk rating v2 (Appendix C) - Every completed scan emits an immutable risk_rating_snapshot: overall_score 0-100, grade A-F, methodology version, top 5 risk drivers, and the coverage behind the grade. The snapshot row is unique per scan_job_id so history stays stable as later scans run. - Per-surface breakdown (Web / API / Repo / Secrets / Cloud / Kubernetes / Code / Web3 / Dependencies). Each surface starts at 100 and applies severity-weighted deductions (critical -25, high -10, medium -3, low -1, informational 0). - Overall score = 100 minus the summed deductions across ALL findings, floored at 0. Informational findings are exactly neutral: they inform, and they neither help nor hurt. This replaced a finding-count weighted mean, which inverted the meaning of the score — informational findings deducted nothing yet still carried weight, so each one pulled the average toward 100. One unresolved CRITICAL alongside 50 routine informational findings graded "A" (99/100). More scanner output meant a better grade. It does not any more. - NO GRADE is issued when a scan produced no conclusive finding AND at least one check was attempted and failed. There is no evidence to support any grade, and "A" would be a claim about checks that never ran. The report says "Not assessed" and gives the reason; the public badge says "not assessed" and shows no score. - A gap because OUR capability is not deployed (e.g. Android runtime analysis) is recorded separately from a gap because a check failed against the target. Only the latter withholds a grade — an unbuilt feature of ours must never permanently block a customer's result. - The Risk Rating snapshot is rendered on the Executive PDF cover (compact grade chip + per-surface progress bars). When no snapshot exists (older scans pre-2026-05-31), the PDF gracefully falls back to the legacy securityScore display only. - Methodology version (v1) is stamped on every snapshot. A v2 re-roll can ship without rewriting history. - Brand-abuse observations (Phase 4) flow into the standard findings table under category "Brand abuse" so they roll up into the Risk Rating + the /findings list + the /compliance dashboard exactly like every other finding. Each observation also stays in domain_abuse_observations for the dedicated brand-monitoring view. ## Scan attestations: evidence a third party can verify Every scan writes an append-only scan_attestation. A findings list does not survive audit scrutiny on its own; the questions an auditor asks are about the assessment, not the defects. - WHAT was in scope and was it authorised: target URL, target type, its authorization_status, and the per-target scan profile (which tools the customer had switched off). - WHEN: start, end, duration. - HOW: methodology and score version, the worker image, and the tool inventory with exact versions — split into the tools that ACTUALLY RAN in this scan versus what merely existed in the image. A website assessment listing an Android decompiler among its tools is not evidence, it is noise. - WHAT DID NOT RUN: every step that failed or was skipped, named, with its error. A count tells a reader how much was missed, never what. - INTEGRITY: each row is signed with Ed25519. The private key lives only in the scanning worker's environment, never in the database, so possession of database credentials is not enough to forge a record. Each row also chains to the organisation's previous attestation, so altering an old record breaks every later link rather than one row. - The public key is published at https://www.nanotesting.com/.well-known/nanotesting-attestation-key so anyone can verify our evidence WITHOUT our cooperation. An integrity control only the vendor can check is not one an auditor accepts. - The serialisation is versioned, so records keep verifying under the format they were sealed with. Silently invalidating evidence already issued would be worse than the defect that prompted a format change. Stated limit, because overclaiming here would defeat the purpose: the worker holds the signing key, so an attacker with the worker's secrets could still sign. This raises the bar from "anyone with the database" to "someone with the worker's secrets". It does not remove the vendor from the trust model; that needs an external signer (KMS/HSM) and anchoring outside this infrastructure. Timestamps are the worker's own clock and are not attested by an external time source: what was recorded is verifiable, when it happened is not. ## Auditor-ready PDF reports Four auditor-ready PDF reports per scan, server-side via react-pdf, with embedded screenshots of every medium-and-above web-facing finding (captured by the Playwright screenshot sidecar at scan time): 1. **Executive** - top risks, score, severity counts, trend delta 2. **Developer remediation** - one ticket per finding: severity, KEV chip, priority score, CVE, Why / Evidence / How to fix / Acceptance criteria / Regression test hint 3. **Compliance mapping** - OWASP Top 10 2025 + OWASP API Top 10 2023 + ISO 27001 Annex A (25+ controls) + SOC 2 TSC evidence matrix. NOT a compliance attestation; explicit disclaimer printed on the cover. 4. **Security trend** - score history (last 30 scans, SVG sparkline), MTTR, reopen rate, KPI cards When the Web3 add-on has produced findings the Executive + Developer + Compliance PDFs gain a dedicated Web3 / Smart contract section. When the DApp frontend scanner has produced findings the same PDFs include a DApp Web3 section. ## Pricing (Phase 101 plans, 2026) - **Free** - $0. 1 verified target, 1 scan / month. Baseline only. Limited findings preview. No PDF export. - **Starter** - $39 / month. 3 verified targets, 10 scans / month, weekly or monthly schedule. Executive + Developer PDF export. Subdomain takeover, cookie + CSRF audit, basic API discovery, basic dependency + secrets scan. Email alerts. Retest workflow. - **Growth** - $79 / month. 15 verified targets, 100 scans / month, weekly or monthly schedule with a higher scheduled-scan allowance (80 / 30 days vs Starter's 8). Adds mobile binary scanning (APK / IPA), the cloud audit (AWS / Azure / GCP via Prowler + CloudFox), Kubernetes manifests via Kubescape, OpenAPI upload, Nuclei active templates, OpenAPI BOLA / BFLA discovery, repo deep scan, CSRF / OAuth / WebSocket / upload audits, JWT bug battery, DOM-XSS canary, HTTP smuggling + cache poisoning, KEV + EPSS prioritisation, Slack / Discord / generic webhook alerts, all four PDF types, CSV / JSON exports. The active-attack-payload checks (ZAP active scan, Schemathesis fuzz, mass-assignment, Host-header injection) ship in the separate Invasive Testing add-on, not the base plan. - **Agency** - $199 / month. 50 verified targets, 300 scans / month, 25 client workspaces (targets are tagged to a client so a large portfolio stays organised), 15 team members, priority scan queue (Agency jobs are claimed ahead of every other plan), and branded Executive + per-framework Compliance PDFs with your logo, accent colour and company name. Not yet built, and therefore not sold: per-workspace client logins, a cross-workspace rollup dashboard, per-client compliance dashboards, and reusable scan-policy templates. - **Enterprise** - Custom. SSO / SAML, advanced RBAC, internal scanner agent, private network scanning, custom retention, dedicated onboarding. - **Annual billing** - 20% off Starter / Growth / Agency. - **14-day free trial** - automatic on every Starter / Growth / Agency Stripe Checkout. Cancel any time before day 14 from the billing portal for no charge. ### Add-ons - **Web3 / smart contract scanning** - $299 / month. Layered on Growth or Agency only. Covers all 7 supported EVM chains, Sui (Beta), Solana (Beta), and the DApp frontend scanner. - **Invasive Testing** - $299 / month. Layered on Growth or Agency only. Unlocks the active / intrusive checks that send real attack payloads: OWASP ZAP active scan (SQLi / XSS / SSRF / path traversal / cmd injection / SSTI), Schemathesis OpenAPI fuzz (generated POST / PUT / DELETE), mass-assignment probe (privileged-field PATCH, confirmed CWE-915), and Host-header injection (password-reset / cache-poisoning primitive, CWE-644). Three-gate safety model: (1) the workspace must be identity-verified (approved KYC or KYB), (2) the add-on must be active, AND (3) the individual target must be explicitly authorized for invasive testing (per-target consent, stamped with who + when) before any payload is sent. Per-tool opt-out per target; staging-first; never DoS / brute-force. Works for web/API targets and for MOBILE: a mobile binary is static, so the worker extracts the backend API hosts hardcoded in the binary and runs the active checks ONLY against hosts the org has verified ownership of (a verified target with the same host or parent/child domain). Third-party / partner hosts the app calls are reported but never attacked - they must be added and verified as targets first. No emulator, no runtime instrumentation. Guide at /docs/invasive-testing. ## Architecture - **Web app**: Next.js 16 (App Router) on Vercel, Supabase Postgres with RLS for tenancy isolation, encrypted object storage for raw scan output + PDF artifacts + customer OpenAPI specs + mobile binaries (50 MiB cap, service_role-locked). - **Worker**: Go binary on Fly.io. Long-polls scan_jobs, dispatches the right scan type, writes findings back. Bundles pinned binaries of Nuclei, osv-scanner, gitleaks, Trivy, naabu, tlsx, Schemathesis, Semgrep CE, Prowler, ZAP, Kubescape, mobsfscan, Slither, solc-select, apktool, plus the Trivy DB. - **Sidecar services**: Mythril, Echidna (AGPL-isolated), Screenshot (Playwright), Sui RPC, Solana RPC. Reached over a private container network. - **Daily cron** (03:17 UTC): refresh threat intel + recompute priority on every open finding. - **Hourly cron**: enqueue evidence snapshots. - **Stripe Checkout** for first-time payments; plan changes happen inline via subscriptions.update. ## Differentiators - Repeatable on a schedule, not a one-off engagement. - Normalised findings table with CWE / OWASP / MASVS / ISO / SOC 2 mapping. - Auditor-ready PDFs that procurement reviewers accept as evidence support. - Curated bundle of FOSS scanners (Apache / MIT / BSD / LGPL preferred; the sole AGPL dep is Echidna and runs as an unmodified sidecar) maintained as a single SaaS so customers don't have to learn each tool. - Read-only by default. Rate-limited active checks on verified targets. IP-allowlist + URL-validation gate re-checks the target before every outbound request. - Layered FP engineering: host calibration probe, managed-host downgrade, anti-bot threshold, AndroidX carve-out, launcher exemption, test-fixture filter. - Compliance evidence pipeline emits positive proof rows, not just failure rows. ## Authorisation model - DNS TXT record on the apex - HTML file at /.well-known/nanotesting-verification.txt - HTML meta tag on the landing page - Email to webmaster@ / security@ / admin@ on the verified domain Registered free users get one limited scan per day with all results blurred until they verify ownership and upgrade. ## Trust + legal Legal stack under /legal. Eight documents, operating entity Sodasoft LLC (30 N Gould St, Sheridan WY 82801, USA). Effective date 2026-05-14. - /legal/privacy - GDPR + UK GDPR + CCPA-aligned - /legal/terms - Master Subscription Agreement - /legal/dpa - Data Processing Agreement - /legal/subprocessors - 8 subprocessors with regions + transfer mechanisms - /legal/aup - Acceptable Use Policy - /legal/cookies - Per-entry cookie inventory - /legal/refund - 30-day full refund on annual - /legal/bug-bounty - Responsible disclosure with safe harbour /.well-known/security.txt points Policy and Acknowledgments at /legal/bug-bounty. Contact: security@nanotesting.com. ## Key pages - / - landing page (one-stop shop positioning) - /pricing - plan ladder with monthly / annual toggle - /security - safe-scanning policy + authorisation model - /sample-report - sample PDF output for procurement reviewers - /compliance - org-wide compliance evidence dashboard - /docs - product documentation - /status - operational status (computed live) - /legal - index of the 8 legal documents - /vs/burp-suite - comparison vs Burp Suite - /vs/nessus - comparison vs Tenable Nessus / Tenable.io - /vs/detectify - comparison vs Detectify - /signup - magic-link only (no passwords) - /login - magic-link only - /dashboard - target list, scans, findings, billing - /findings/{id} - per-finding detail with org-scoped discussion - /targets/import - bulk CSV target import (up to 100 rows) - /settings/profile - display name + avatar URL - /settings/privacy - GDPR export + account deletion ## Guides + articles (blog) Long-form guides at https://nanotesting.com/blog (RSS at /blog/rss.xml; every post is in the sitemap). Recent additions: - /blog/dast-vs-sast-vs-sca - DAST vs SAST vs SCA: which application security testing you need, and how one platform runs all three. - /blog/what-is-dast - what dynamic application security testing is, passive vs active, and its blind spots. - /blog/scan-github-repo-vulnerabilities - scanning a repo for secrets, dependency CVEs, and SAST issues, prioritised by CISA KEV + EPSS. - /blog/cloud-security-posture-management-cspm - CSPM for AWS / Azure / GCP CIS audits (Prowler posture + CloudFox attack surface). - /blog/kubernetes-security-scanning - the K8s manifest misconfigurations a static scan catches. - /blog/security-headers-explained - CSP, HSTS, and the response headers every web scan checks. - /blog/tls-ssl-misconfigurations - the TLS/SSL issues that fail security audits, and how to fix them. - /blog/mapping-findings-compliance-frameworks - mapping scan findings to NIST CSF 2.0, CIS v8, and PCI DSS 4.0 (honestly: scans can't assess every control). - /blog/detecting-honeypot-tokens-rug-pulls - on-chain red flags for honeypot tokens and rug pulls. - /blog/erc20-token-security-risks - ERC-20 risks: owner mint, blacklist, and fee-on-transfer. ## Contact + corporate - Operating entity: Sodasoft LLC, 30 N Gould St, Sheridan WY 82801, United States - Founder: Ratomir Jovanovic - Customer support: support@nanotesting.com - Privacy / GDPR / DSAR: privacy@nanotesting.com - DPO: dpo@nanotesting.com - Legal: legal@nanotesting.com - Billing: billing@nanotesting.com - Security disclosure: security@nanotesting.com - Domain: https://nanotesting.com - LinkedIn: https://www.linkedin.com/company/nanotesting