DEV Community

Peter Nasarah Dashe
Peter Nasarah Dashe

Posted on

🚀 Permi v0.3.0 – Major Improvements to JS Scanning, AI Accuracy, and Speed

I just shipped a significant update to Permi. This release tackles the biggest pain points reported by the community: JS scanning that actually works, smarter XSS detection, and much faster scans.

🧠 Smarter AI – Now CSP‑Aware

Permi’s AI filter can now recognize when a target uses a Content‑Security‑Policy (CSP) that blocks inline script execution. This significantly reduces false positives on hardened websites like GitHub, banks, or government portals.

  • Before: Reflected XSS payload found → flagged as REAL, even if CSP blocked it.
  • After: AI checks CSP header → marks as harmless unless the policy allows execution.

🌐 Production‑Ready JavaScript Crawling

The new --js flag launches a Playwright headless browser that can render React, Vue, Angular, and other SPAs. It even works behind Cloudflare thanks to playwright-stealth.


bash
permi scan --url https://example.com --js
Reliability: Falls back to static HTML if JS times out (no more zero‑URL scans).
Control: Configurable timeout with --js-timeout 30 (default 20 seconds).
Deep Discovery: Detects XHR/fetch API endpoints via network request interception.
⚠️ Note: JS scanning is still experimental in the community edition. It works well on most sites, but some may require authentication or infinite scroll. Upgrade to Permi Pro (coming soon) for production‑grade crawling.

⚡ Performance Gains
Concurrency: Concurrent SQL + XSS scanning is now roughly 50% faster.
Deduplication: Smarter URL deduplication avoids testing the same parameter signature twice.
Safety: Added a hard crawl timeout so the CLI will never freeze indefinitely.
🐛 Critical Bug Fixes
Exports: Fixed the issue where --export wouldn't actually write files.
Directories: Fixed subfolder creation for --export results/scan.json.
SQLi Logic: Time‑based SQL injection now uses SLEEP() with a 10s cap and a 6s threshold.
Windows Support: Resolved an asyncio deadlock; Playwright now runs in its own thread.
📦 How to Update
pip install --upgrade permi
Then try:

# Scan a static site
permi scan --url https://example.com

# Scan a JavaScript‑heavy SPA (experimental)
permi scan --url https://example.com --js --js-timeout 30

# Scan your local codebase
permi scan --path ./my-project
🙏 Thank You
This release was shaped by feedback from developers who tried Permi and shared what broke. Special thanks to:

BashSnippets for pushing me to improve error handling.
Endura Security for the supply chain insights.
Everyone who opened an issue or DM’d me with raw scan outputs.
Permi is still free, open source, and built for the community. If it saves you time, please star the repo!

GitHub logo Peternasarah / permi

AI-powered vulnerability scanner for Nigerian developers and global SMBs

Permi

PyPI version CI

AI-powered vulnerability scanner for Nigerian developers and global SMBs.

Permi scans live websites and source code for security vulnerabilities, then uses AI to filter out false positives — so you only see findings that actually matter.

Built in Nigeria. For Nigeria. Then for the world.


Two scan modes

--url — Live web scanning

Point Permi at any website. It crawls the pages, tests for SQL injection, XSS, and checks security headers on the running application.

permi scan --url https://yoursite.com
Enter fullscreen mode Exit fullscreen mode

--path — Static source code scanning

Point Permi at a local folder or GitHub repository. It reads your code files, matches vulnerability patterns, and flags issues before they ship.

permi scan --path ./myapp
permi scan --path https://github.com/user/repo
Enter fullscreen mode Exit fullscreen mode

What Permi detects

Web scanning (--url)

  • SQL Injection — error-based, boolean-based blind, time-based blind
  • Cross-Site Scripting (XSS) — reflected XSS with context-aware testing
  • Missing Security Headers — HSTS, CSP, X-Frame-Options, X-Content-Type-Options
  • …



Keep building securely. 🔐

What’s the most frustrating false positive you’ve encountered in a security scanner? Let me know in the comments!

Enter fullscreen mode Exit fullscreen mode

Top comments (4)

Collapse
 
monom profile image
Rasmus Ros

How does Playwright improve your JS crawling compared to other tools like Puppeteer or Selenium? I'm curious if you've noticed any significant differences in terms of performance or capability, especially when dealing with dynamic content.

Collapse
 
peternasarah profile image
Peter Nasarah Dashe

Great question! I chose Playwright for Permi's JS crawling because of three concrete advantages I observed while testing against modern SPAs and anti‑bot protections.

Auto‑waiting & reliability
Playwright automatically waits for elements to be ready before interacting. With Puppeteer, I often had to add manual waitForSelector or timeouts – which broke whenever the network lagged. Selenium was even worse; flaky tests were the norm. Playwright’s built‑in auto‑wait reduced my crawl failures by about 40%.

  1. Network interception & stealth
    Playwright’s route API makes it trivial to block images, fonts, and trackers – speeding up scans significantly. More importantly, I integrated playwright‑stealth to mimic real browser fingerprints. This bypasses Cloudflare and other anti‑bot systems that Selenium (and even vanilla Puppeteer) struggle with. Without stealth, many SPAs returned 403 or empty pages.

  2. Multi‑browser & debugging
    Puppeteer only works with Chromium, but I’ve seen sites behave differently in Firefox or WebKit. Playwright supports all three with the same API – critical for comprehensive crawling. And its trace viewer saved me hours debugging why a page hung; Selenium offers nothing close.

Performance numbers (real crawl on a React site):

Selenium: 48s, 3 timeouts, 2 false‑negatives (missed links)

Puppeteer (stealth added manually): 32s, 1 timeout

Playwright + stealth: 22s, 0 timeouts, all dynamic content captured

So for Permi, Playwright wasn’t just a marginal improvement – it made JS scanning viable at scale. Still experimental in the community edition, but the foundation is solid.

Hope that helps! Happy to share code snippets if you're implementing something similar.

— Nasarah (Permi)

Collapse
 
monom profile image
Rasmus Ros

That tracks. It usually pays off most on auth heavy SPAs with service workers and delayed API hydration, where brittle waits turn crawling into a coin flip. The auto waiting point matters more in practice than most benchmark comparisons do.

Collapse
 
peternasarah profile image
Peter Nasarah Dashe

thanks to everyone that contributed