rastray 0.15.0

Blazing-fast static analysis CLI for security, dependency, and performance audits.
# Summary

- [Introduction]./introduction.md
- [Quickstart]./quickstart.md
- [How to read these pages]./how-to-read.md

# Benchmarks

- [Methodology]./benchmarks/methodology.md
- [Summary table]./benchmarks/summary.md
- [OWASP Juice Shop]./benchmarks/juice-shop.md
- [OWASP NodeGoat]./benchmarks/nodegoat.md
- [DVWA]./benchmarks/dvwa.md
- [OWASP RailsGoat]./benchmarks/railsgoat.md
- [WebGoat]./benchmarks/webgoat.md
- [django-DefectDojo]./benchmarks/django-defectdojo.md

# Secrets in source

- [RSTR-SEC-001 — hard-coded credential pattern]./rules/RSTR-SEC-001.md
- [RSTR-SEC-002 — GitHub personal access token]./rules/RSTR-SEC-002.md
- [RSTR-SEC-003 — GitHub fine-grained PAT]./rules/RSTR-SEC-003.md
- [RSTR-SEC-004 — Slack bot token]./rules/RSTR-SEC-004.md
- [RSTR-SEC-005 — Stripe live secret key]./rules/RSTR-SEC-005.md
- [RSTR-SEC-006 — Google API key]./rules/RSTR-SEC-006.md
- [RSTR-SEC-007 — PEM private key]./rules/RSTR-SEC-007.md
- [RSTR-SEC-008 — npm access token]./rules/RSTR-SEC-008.md

# Broken cryptography

- [RSTR-CRY-001 — MD5 used for hashing]./rules/RSTR-CRY-001.md
- [RSTR-CRY-002 — SHA-1 used for hashing]./rules/RSTR-CRY-002.md
- [RSTR-CRY-003 — DES / 3DES cipher]./rules/RSTR-CRY-003.md
- [RSTR-CRY-004 — ECB cipher mode]./rules/RSTR-CRY-004.md
- [RSTR-CRY-005 — Math.random() used for security]./rules/RSTR-CRY-005.md
- [RSTR-CRY-006 — Python random / Go math/rand for security]./rules/RSTR-CRY-006.md
- [RSTR-CRY-007 — Rust rand::thread_rng() for security]./rules/RSTR-CRY-007.md

# Injection

- [RSTR-INJ-001 — SQL injection via f-string / template literal]./rules/RSTR-INJ-001.md
- [RSTR-INJ-002 — Python subprocess(shell=True) / os.system]./rules/RSTR-INJ-002.md
- [RSTR-INJ-003 — eval / exec / new Function]./rules/RSTR-INJ-003.md
- [RSTR-INJ-004 — Node child_process.exec with template literal]./rules/RSTR-INJ-004.md
- [RSTR-INJ-005 — Go exec.Command with sh -c]./rules/RSTR-INJ-005.md
- [RSTR-INJ-006 — PHP SQL query built from request superglobal]./rules/RSTR-INJ-006.md
- [RSTR-INJ-007 — PHP command exec on request superglobal]./rules/RSTR-INJ-007.md
- [RSTR-INJ-008 — Rails .where with string interpolation of params]./rules/RSTR-INJ-008.md
- [RSTR-INJ-009 — Rails params[...].constantize / classify]./rules/RSTR-INJ-009.md
- [RSTR-INJ-010 — Rails render inline: / text: with params interpolation]./rules/RSTR-INJ-010.md
- [RSTR-INJ-011 — C system / popen / exec* with non-literal argument]./rules/RSTR-INJ-011.md
- [RSTR-INJ-012 — Java Runtime.exec / ProcessBuilder with concat]./rules/RSTR-INJ-012.md

# Memory safety (C / C++)

- [RSTR-MEM-001 — strcpy / strcat / gets / sprintf]./rules/RSTR-MEM-001.md
- [RSTR-MEM-002 — scanf with unbounded %s]./rules/RSTR-MEM-002.md
- [RSTR-MEM-003 — alloca on attacker-controlled size]./rules/RSTR-MEM-003.md
- [RSTR-MEM-004 — memcpy / memmove with strlen length]./rules/RSTR-MEM-004.md
- [RSTR-MEM-005 — raw new outside a smart pointer]./rules/RSTR-MEM-005.md

# Server-side request forgery

- [RSTR-SSRF-001 — Node fetch / axios with request input]./rules/RSTR-SSRF-001.md
- [RSTR-SSRF-002 — Node http / https with request input]./rules/RSTR-SSRF-002.md
- [RSTR-SSRF-003 — Python requests / urlopen with request input]./rules/RSTR-SSRF-003.md
- [RSTR-SSRF-004 — Go http.Get / http.NewRequest with request input]./rules/RSTR-SSRF-004.md

# Cross-site scripting

- [RSTR-XSS-001 — reflected XSS via res.send/res.end/res.write]./rules/RSTR-XSS-001.md
- [RSTR-XSS-002 — DOM-based XSS via innerHTML/outerHTML]./rules/RSTR-XSS-002.md
- [RSTR-XSS-003 — document.write with DOM data]./rules/RSTR-XSS-003.md
- [RSTR-XSS-004 — Flask Markup / direct return of request input]./rules/RSTR-XSS-004.md
- [RSTR-XSS-005 — Go HTTP response writes with request input]./rules/RSTR-XSS-005.md
- [RSTR-XSS-006 — PHP echo / print of request superglobal]./rules/RSTR-XSS-006.md

# JSON-Web-Token misuse

- [RSTR-JWT-001 — alg:none or wildcard algorithms accepted]./rules/RSTR-JWT-001.md
- [RSTR-JWT-002 — JWT verification disabled]./rules/RSTR-JWT-002.md
- [RSTR-JWT-003 — hardcoded JWT secret in source]./rules/RSTR-JWT-003.md
- [RSTR-JWT-004 — verify without explicit algorithms list]./rules/RSTR-JWT-004.md
- [RSTR-JWT-005 — Go jwt.Parse keyfunc without method check]./rules/RSTR-JWT-005.md

# Open redirect

- [RSTR-RDR-001 — Express res.redirect(req.x)]./rules/RSTR-RDR-001.md
- [RSTR-RDR-002 — Flask / Django redirect with request input]./rules/RSTR-RDR-002.md
- [RSTR-RDR-003 — Go http.Redirect with request input]./rules/RSTR-RDR-003.md
- [RSTR-RDR-004 — Rails redirect_to params[...]]./rules/RSTR-RDR-004.md

# Server-side template injection

- [RSTR-SSTI-001 — Python render_template_string / Template(req.x)]./rules/RSTR-SSTI-001.md
- [RSTR-SSTI-002 — Node template compile from request input]./rules/RSTR-SSTI-002.md

# XML external entity

- [RSTR-XXE-001 — Python stdlib XML parsers]./rules/RSTR-XXE-001.md
- [RSTR-XXE-002 — lxml XMLParser(resolve_entities=True)]./rules/RSTR-XXE-002.md
- [RSTR-XXE-003 — libxmljs parseXml with noent: true]./rules/RSTR-XXE-003.md
- [RSTR-XXE-004 — xml2js permissive parser options]./rules/RSTR-XXE-004.md
- [RSTR-XXE-005 — Java XML factory without entity hardening]./rules/RSTR-XXE-005.md

# NoSQL injection

- [RSTR-NOSQLI-001 — Mongo find/update with req.body object]./rules/RSTR-NOSQLI-001.md
- [RSTR-NOSQLI-002 — Mongo $where with request input]./rules/RSTR-NOSQLI-002.md
- [RSTR-NOSQLI-003 — PyMongo filter from request.*](./rules/RSTR-NOSQLI-003.md)

# Deserialization

- [RSTR-DES-001 — Python pickle.loads on untrusted input](./rules/RSTR-DES-001.md)
- [RSTR-DES-002 — Python yaml.load without SafeLoader](./rules/RSTR-DES-002.md)
- [RSTR-DES-003 — Python marshal.loads on untrusted input](./rules/RSTR-DES-003.md)
- [RSTR-DES-004 — Node node-serialize unserialize](./rules/RSTR-DES-004.md)
- [RSTR-DES-005 — Ruby Marshal.load](./rules/RSTR-DES-005.md)
- [RSTR-DES-006 — Java ObjectInputStream.readObject](./rules/RSTR-DES-006.md)
- [RSTR-DES-007 — PHP unserialize](./rules/RSTR-DES-007.md)

# Path traversal

- [RSTR-PTH-001 — Flask send_file(request.*)](./rules/RSTR-PTH-001.md)
- [RSTR-PTH-002 — Express sendFile / fs read with request input](./rules/RSTR-PTH-002.md)
- [RSTR-PTH-003 — Java new File(servletRequest...)](./rules/RSTR-PTH-003.md)
- [RSTR-PTH-004 — literal ../../ in source](./rules/RSTR-PTH-004.md)
- [RSTR-PTH-005 — PHP include/require from request superglobal](./rules/RSTR-PTH-005.md)
- [RSTR-PTH-006 — PHP file API on request superglobal](./rules/RSTR-PTH-006.md)

# Web-app configuration

- [RSTR-COOKIE-001 — cookie without secure: true](./rules/RSTR-COOKIE-001.md)
- [RSTR-COOKIE-002 — cookie without httpOnly: true](./rules/RSTR-COOKIE-002.md)
- [RSTR-COOKIE-003 — cookie with sameSite: 'none'](./rules/RSTR-COOKIE-003.md)
- [RSTR-CORS-001 — cors origin:true|* with credentials:true](./rules/RSTR-CORS-001.md)
- [RSTR-CORS-002 — manual ACAO: * with credentials](./rules/RSTR-CORS-002.md)
- [RSTR-CSRF-001 — Flask WTF_CSRF_ENABLED disabled](./rules/RSTR-CSRF-001.md)
- [RSTR-CSRF-002 — Django @csrf_exempt](./rules/RSTR-CSRF-002.md)

# ORM mass-assignment

- [RSTR-ORM-001 — Node ORM Model.create(req.body)](./rules/RSTR-ORM-001.md)
- [RSTR-ORM-002 — Django ORM create with **request.POST](./rules/RSTR-ORM-002.md)
- [RSTR-ORM-003 — Rails create / update with raw params](./rules/RSTR-ORM-003.md)
- [RSTR-ORM-004 — raw SQL template literal](./rules/RSTR-ORM-004.md)
- [RSTR-ORM-005 — Rails params.require(:x).permit! (open permit)](./rules/RSTR-ORM-005.md)

# LDAP injection

- [RSTR-LDAP-001 — ldapjs search with template-literal filter](./rules/RSTR-LDAP-001.md)
- [RSTR-LDAP-002 — Python LDAP filter built with f-string](./rules/RSTR-LDAP-002.md)

# Regular expressions

- [RSTR-REDOS-001 — nested quantifier catastrophic backtracking](./rules/RSTR-REDOS-001.md)

# Network

- [RSTR-NET-001 — TLS verification disabled](./rules/RSTR-NET-001.md)
- [RSTR-NET-002 — Python SSL context with verification disabled](./rules/RSTR-NET-002.md)
- [RSTR-NET-003 — Wildcard CORS with credentials](./rules/RSTR-NET-003.md)
- [RSTR-NET-004 — cookie httpOnly: false (network variant)](./rules/RSTR-NET-004.md)
- [RSTR-NET-005 — Java HostnameVerifier accepts every hostname](./rules/RSTR-NET-005.md)

# CI / GitHub Actions

- [RSTR-GHA-001 — pull_request_target + PR-head checkout](./rules/RSTR-GHA-001.md)
- [RSTR-GHA-002 — action pinned by floating tag](./rules/RSTR-GHA-002.md)
- [RSTR-GHA-003 — github.event.* interpolated into run:](./rules/RSTR-GHA-003.md)
- [RSTR-GHA-005 — checkout with persist-credentials: true](./rules/RSTR-GHA-005.md)

# Containers / Infrastructure-as-Code

- [RSTR-IAC-001 — FROM image:latest](./rules/RSTR-IAC-001.md)
- [RSTR-IAC-002 — USER root in runtime stage](./rules/RSTR-IAC-002.md)
- [RSTR-IAC-003 — ADD with remote URL](./rules/RSTR-IAC-003.md)
- [RSTR-IAC-005 — chmod 777](./rules/RSTR-IAC-005.md)
- [RSTR-IAC-006 — curl | sh](./rules/RSTR-IAC-006.md)
- [RSTR-IAC-007 — privileged container](./rules/RSTR-IAC-007.md)
- [RSTR-IAC-008 — host namespace shared](./rules/RSTR-IAC-008.md)
- [RSTR-IAC-009 — public S3 bucket ACL](./rules/RSTR-IAC-009.md)
- [RSTR-IAC-010 — open ingress cidr 0.0.0.0/0](./rules/RSTR-IAC-010.md)
- [RSTR-IAC-011 — publicly accessible database](./rules/RSTR-IAC-011.md)

# Performance — Rust

- [RSTR-PERF-001 — format! accumulator in a loop](./rules/RSTR-PERF-001.md)
- [RSTR-PERF-002 — for x in xs.clone()](./rules/RSTR-PERF-002.md)

# Performance — JavaScript / TypeScript

- [RSTR-PERF-101 — await inside a loop](./rules/RSTR-PERF-101.md)
- [RSTR-PERF-102 — new Date() inside a loop](./rules/RSTR-PERF-102.md)

# Performance — Python

- [RSTR-PERF-201 — string += inside a loop](./rules/RSTR-PERF-201.md)
- [RSTR-PERF-202 — time.sleep() inside an async def](./rules/RSTR-PERF-202.md)

# Performance — Go

- [RSTR-PERF-301 — defer inside a for loop](./rules/RSTR-PERF-301.md)
- [RSTR-PERF-302 — fmt.Sprintf inside a for loop](./rules/RSTR-PERF-302.md)