Skip to main content

A high-performance, open-source static code security scanner

Project description

๐Ÿ” Secara

Static Code Security Scanner

Fast. Accurate. Developer-Trusted.

Python 3.9+ License: GPL-3.0 PRs Welcome

Detect real, exploitable vulnerabilities โ€” not style warnings.


What is Secara?

Secara is an open-source, CLI-based static code security scanner designed for accuracy and developer usability. It uses a hybrid of AST-based analysis, regex pattern matching, and basic taint tracking to detect real security vulnerabilities in your codebase โ€” without false alarms.

It runs fully offline, requires no cloud APIs, and is built to scale across large monorepos.


โœจ Features

Feature Details
๐Ÿ”‘ Secrets Detection AWS keys, GitHub tokens, Stripe keys, private keys, high-entropy strings
๐Ÿ’‰ SQL Injection AST-based detection of string concat / f-string SQL in Python and JS
๐Ÿ–ฅ๏ธ Command Injection os.system, subprocess with shell=True, exec(), eval()
๐Ÿ Python (Tier 1) Full AST analysis + Interprocedural Taint Tracking
๐ŸŒ JavaScript / TypeScript (Tier 1) Regex-AST hybrid, no compiled dependencies
โ˜• Java / Kotlin (Tier 2) Detects SQLi, XXE, Insecure Deserialization, SSRF
๐Ÿ˜ PHP (Tier 2) Detects SQLi, LFI/RFI, XSS, Path Traversal
๐Ÿ’Ž Ruby (Tier 2) Detects ActiveRecord SQLi, Mass Assignment, CMDi
๐Ÿน Go (Tier 2) Basic regex-based AST parsing (SQLi, CMDi, SSRF)
๐Ÿ“ฆ SCA Scanning Dependency vulnerability scanning via OSV.dev API
๐Ÿš Bash / Shell (Tier 2) Eval injection, unsafe substitution patterns
โš™๏ธ JSON / YAML / .env (Tier 2) Config file plaintext credential detection
๐Ÿ’ง Inline Suppression Fine-grained suppression with secara: ignore[RULE_ID]
๐ŸŽจ Beautiful Output Rich terminal UI, JSON mode, SARIF export

๐Ÿš€ Quick Start

Linux / macOS โ€” One-line install (recommended)

git clone https://github.com/ilyshoaib/secara.git
cd secara
bash install.sh

The installer will:

  • Install secara from source
  • Create a global symlink in /usr/local/bin (may prompt for sudo password)
  • Verify the secara command works

You can now use secara from anywhere immediately:

secara scan .

Manual install (all platforms)

git clone https://github.com/ilyshoaib/secara.git
cd secara
pip install -e .

If secara command is not found after install (common on Linux):

# Check where pip installed the script
python3 -c "import site; print(site.getusersitepackages())"

# Add ~/.local/bin to your PATH permanently
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Windows (PowerShell):

git clone https://github.com/ilyshoaib/secara.git
cd secara
pip install -e .
# The secara command is available immediately โ€” no PATH fix needed
secara scan .

PyPI release coming soon โ€” once published, installation will be simply pip install secara.

Scan a directory

secara scan ./src

Scan a single file

secara scan app.py

JSON output (for CI/CD pipelines)

secara scan . --json > results.json

๐Ÿ“– Usage

Usage: secara scan [OPTIONS] PATH

  Scan a file or directory for security vulnerabilities.

Options:
  --json            Output results as JSON (machine-readable)
  --sarif           Output results as SARIF v2.1.0 for GitHub CI/CD integration
  -o, --output      Write output to file (useful with --sarif or --json)
  -v, --verbose     Show full descriptions and fix details
  -s, --severity    Minimum severity: HIGH | MEDIUM | LOW  [default: LOW]
  --min-confidence  Minimum confidence: HIGH | MEDIUM | LOW  [default: LOW]
  --policy          Policy preset: balanced | strict
  --changed-only    Scan only changed/untracked git files
  --baseline        Filter findings already present in baseline fingerprint file
  --write-baseline  Write current findings to a baseline fingerprint file
  --enforce-suppression-metadata  Require reason= and until= for suppressions
  --profile-scan    Show stage timings and cache stats
  --no-cache        Disable file cache (re-scan everything)
  -w, --workers     Number of parallel worker threads  [default: 8]
  -V, --version     Show version and exit
  --help            Show this message and exit

Examples

# Scan everything, show all findings
secara scan .

# Only show HIGH severity findings
secara scan . --severity HIGH

# Full details with fix suggestions
secara scan ./src --verbose

# Machine-readable JSON for CI integration
secara scan . --json | jq '.[] | select(.severity == "HIGH")'

# Generate SARIF for GitHub Code Scanning
secara scan . --sarif --output secara-results.sarif

# Force re-scan (ignore cache)
secara scan . --no-cache

# Scan with more parallel workers
secara scan /large/repo --workers 16

# Only scan changed files (fast PR checks)
secara scan . --changed-only

# Strict policy + confidence filtering
secara scan . --policy strict --min-confidence MEDIUM

# Baseline workflow (new findings only)
secara scan . --write-baseline .secara/baseline.json
secara scan . --baseline .secara/baseline.json

# View historical scan trends
secara metrics --limit 20

# Show per-rule benchmark quality metrics
secara metrics --rules

# Generate benchmark quality report artifacts (JSON + markdown)
secara quality-report --json-output artifacts/quality_report.json --md-output artifacts/quality_report.md

Advanced workflows

# Enforce suppression governance (must include reason= and until=YYYY-MM-DD)
secara scan . --enforce-suppression-metadata

# Focus only on high-confidence actionable findings
secara scan . --min-confidence HIGH

# Baseline + changed-only fast PR signal
secara scan . --baseline .secara/baseline.json --changed-only --policy strict

# Impacted graph mode (changed + dependent files)
secara scan . --impacted-only

# Deterministic sharded scan for CI parallel jobs
secara scan . --shard-index 0 --shard-count 4

# Print scan stage timings and cache hit/miss stats
secara scan . --profile-scan

# Benchmark scanner throughput (for CI trend tracking)
secara benchmark . --runs 5 --warmup 1 --json

๐Ÿ›ก๏ธ Vulnerability Coverage (v0.6.1)

๐Ÿ”‘ Hardcoded Secrets (35+ patterns)

Rule ID Vulnerability Severity
SEC001 AWS Access Key ID (AKIA...) HIGH
SEC001B AWS Secret Access Key HIGH
SEC002 GitHub PAT (ghp_...) HIGH
SEC004B GitHub Fine-Grained Token (github_pat_...) HIGH
SEC004C GitLab Token (glpat-...) HIGH
SEC005 Stripe Live Key (sk_live_...) HIGH
SEC007B Slack Webhook URL HIGH
SEC008 RSA/EC/OPENSSH Private Key Header HIGH
SEC009 SendGrid API Key (SG....) HIGH
SEC010 Google API Key (AIza...) HIGH
SEC010B Google OAuth Secret (GOCSPX-...) HIGH
SEC010C GCP Service Account Key HIGH
SEC012 Hardcoded JWT Token HIGH
SEC015 OpenAI API Key (sk-...) HIGH
SEC016 Anthropic API Key (sk-ant-...) HIGH
SEC017 Azure Storage Connection String HIGH
SEC018 npm Auth Token (npm_...) HIGH
SEC020 Telegram Bot Token HIGH
SEC021 Discord Bot Token HIGH
SEC024 PyPI Token (pypi-...) HIGH
SEC025 HuggingFace Token (hf_...) HIGH
SEC026 Databricks Token (dapi...) HIGH
SEC028 HashiCorp Vault Token (hvs....) HIGH
SEC029 Shopify Token (shpat_...) HIGH
SEC031 Database Connection String (Postgres/MySQL/MongoDB) HIGH
SEC013 Generic Hardcoded Credential (password/secret/api_key) HIGH
SEC014 High-Entropy String (Possible Secret) MEDIUM

๐Ÿ’‰ SQL Injection

Rule ID Vulnerability Languages Severity
SQL001 SQLi via String Concat / f-string Python AST HIGH
SQL201 SQLi via Dynamic Statement Java HIGH
SQL301 SQLi via mysql_query PHP HIGH
SQL401 SQLi via String Interpolation in ActiveRecord Ruby HIGH
SQL005 SQLi via string construction in db.Query Go HIGH

๐Ÿ–ฅ๏ธ Command Injection

Rule ID Vulnerability Languages Severity
CMD001 os.system() with dynamic args Python HIGH
CMD201 Runtime.getRuntime().exec() Java HIGH
CMD301 exec() / shell_exec() PHP HIGH
CMD401 `backticks` and system() Ruby HIGH
SH001 eval with variable in shell script Bash HIGH
SH002 Unsafe backtick substitution Bash HIGH
SH004 Dangerous command with unquoted variable Bash HIGH

๐Ÿ” Cryptographic Failures [OWASP A02]

Rule ID Vulnerability Languages Severity
CRY001 Weak hash: hashlib.md5() / hashlib.sha1() Python HIGH
CRY002 SSL cert verification disabled: verify=False Python HIGH
CRY003 Insecure PRNG: random.random() for secrets Python MEDIUM
CRY004 Weak hash: crypto.createHash('md5'/'sha1') JavaScript HIGH
CRY005 Insecure random: Math.random() for tokens/secrets JavaScript HIGH

๐ŸŒ Server-Side Request Forgery [OWASP A10]

Rule ID Vulnerability Languages Severity
SSRF001 requests.get/post(user_url) โ€” tainted URL Python HIGH
SSRF002 fetch/axios.get(user_url) โ€” tainted URL JavaScript HIGH
SSRF003 http.Get with dynamic strings Go HIGH

๐Ÿ’ฃ Insecure Deserialization [OWASP A08]

Rule ID Vulnerability Languages Severity
DSER001 pickle.loads(data) โ€” arbitrary code execution Python HIGH
DSER002 marshal.loads(data) Python HIGH
DSER003 shelve.open(user_path) โ€” pickle-based Python MEDIUM
DSER004 yaml.load() without SafeLoader Python HIGH
DSER005 node-serialize.deserialize(req.body) JavaScript HIGH
DSER006 yaml.load() without safe schema JavaScript HIGH

๐Ÿ“‚ Path Traversal [OWASP A01]

Rule ID Vulnerability Languages Severity
PATH001 open(user_input) โ€” directory traversal Python HIGH
PATH201 new File(user_input) Java HIGH
PATH301 file_get_contents($user_input) PHP HIGH
PATH401 File.read(user_input) Ruby HIGH
PATH004 os.Open with dynamic path Go MEDIUM

๐ŸŽฏ Injection โ€” Extended [OWASP A03]

Rule ID Vulnerability Languages Severity
SSTI001 SSTI via render_template_string(user_data) Python HIGH
XSS001 XSS via innerHTML = req.params.x JavaScript HIGH
XSS002 Potential XSS via element.innerHTML = var JavaScript MEDIUM
XSS003 XSS via document.write(user_data) JavaScript HIGH

๐Ÿ”‡ Security Logging Failures [OWASP A09]

Rule ID Vulnerability Languages Severity
LOG001 Sensitive variable (password/token) passed to logger Python MEDIUM
TEMP001 Insecure Temporary File via tempfile.mktemp() Python HIGH
RACE001 TOCTOU check via os.path.exists() before open() Python MEDIUM
MASS001 Mass Assignment via __dict__.update(user_data) Python HIGH
MASS002 Mass Assignment via **kwargs in ORM creation Python MEDIUM

โš™๏ธ Security Misconfiguration [OWASP A05]

Rule ID Vulnerability Languages Severity
CFG001 Plaintext secret value in .env/.ini file Config HIGH
CFG201 Spring Boot CSRF Disabled Java MEDIUM
CFG301 display_errors enabled in code PHP MEDIUM
CFG010 CORS wildcard * origin JavaScript MEDIUM

๐Ÿ“ฆ Software Composition Analysis (SCA)

File Scanner Severity Mapping
requirements.txt Python Dependency Scan OSV.dev (CVE/GHSA)
package.json JS Dependency Scan OSV.dev (CVE/GHSA)
go.mod Go Dependency Scan OSV.dev (CVE/GHSA)
Gemfile.lock Ruby Dependency Scan OSV.dev (CVE/GHSA)

๐Ÿ—๏ธ Architecture

secara/
โ”œโ”€โ”€ cli.py                    # CLI entry point (deps/scan commands)
โ”œโ”€โ”€ scanner/
โ”‚   โ”œโ”€โ”€ file_scanner.py       # Recursive traversal + parallel execution
โ”‚   โ”œโ”€โ”€ language_engine.py    # Maps files to analysis tier (Tier 1/2)
โ”‚   โ””โ”€โ”€ cache.py              # SHA-256 file cache
โ”œโ”€โ”€ detectors/
โ”‚   โ”œโ”€โ”€ python_analyzer.py    # Python AST + Taint analysis
โ”‚   โ”œโ”€โ”€ js_analyzer.py        # JavaScript/TypeScript hybrid
โ”‚   โ”œโ”€โ”€ java_analyzer.py      # Java/Kotlin Tier 2
โ”‚   โ”œโ”€โ”€ php_analyzer.py       # PHP Tier 2
โ”‚   โ”œโ”€โ”€ ruby_analyzer.py      # Ruby Tier 2
โ”‚   โ”œโ”€โ”€ secrets_detector.py   # Global secrets detection
โ”‚   โ””โ”€โ”€ generic_analyzer.py   # Base class for YAML-based regex detectors
โ”œโ”€โ”€ sca/
โ”‚   โ”œโ”€โ”€ osv_client.py         # OSV.dev API integration
โ”‚   โ””โ”€โ”€ parsers.py            # Manifest parsers (requirements, package.json...)
โ”œโ”€โ”€ taint/
โ”‚   โ”œโ”€โ”€ interproc_taint.py    # Interprocedural Call Graph logic
โ”‚   โ””โ”€โ”€ python_taint.py       # Intraprocedural taint (AST)
โ””โ”€โ”€ output/
    โ”œโ”€โ”€ sarif_formatter.py    # SARIF v2.1.0 output
    โ””โ”€โ”€ rich_formatter.py     # Pretty-print CLI output

Language Tiers:

  • Tier 1 (AST-based): Python, JavaScript, TypeScript
  • Tier 2 (Regex-hybrid): Java, Kotlin, PHP, Ruby, Go, Bash
  • SCA: requirements.txt, package.json, go.mod, Gemfile.lock

โšก Performance

Scenario Performance
1,000 Python files ~2-3 seconds
10,000 mixed files ~15-25 seconds
Re-scan (cached) ~0.5 seconds
Files > 512KB Automatically skipped
Binary files Automatically skipped

Performance scales linearly with --workers. Cached results make repeat scans near-instant.


๐Ÿ”ง Suppressing False Positives

Add # secara: ignore to any line to suppress findings on that specific line:

SIGNING_NONCE = "Xk9mP2wQzR4nV7tY1aL8cF0jH6"  # secara: ignore
result = eval(compile(safe_tree, "<string>", "eval"))  # secara: ignore

๐Ÿงช Running Tests

# Install with dev dependencies
pip install -e ".[dev]"

# Run all tests
pytest tests/ -v

# With coverage
pytest tests/ --cov=secara --cov-report=html

๐Ÿค Contributing

Contributions are welcome! See CONTRIBUTING.md for guidelines.

Areas where you can help:

  • Adding new vulnerability rules
  • Improving taint tracking accuracy
  • Adding support for new languages (Go, Ruby, Java, PHPโ€ฆ)
  • Improving false positive rate
  • VS Code extension / GitHub Action support

๐Ÿ—บ๏ธ Roadmap

  • Go language support (Tier 2/Regex)
  • Java / Kotlin / Ruby / PHP support (Tier 2)
  • Software Composition Analysis (SCA) - Dependency scanning
  • SARIF output format (GitHub Code Scanning compatible)
  • GitHub Actions workflow
  • VS Code extension
  • Interprocedural taint analysis
  • Custom rule authoring (YAML)
  • Path traversal detection
  • SSRF detection
  • Insecure deserialization detection
  • CWE Mapping for all rules

๐Ÿ“„ License

GNU GPLv3 โ€” see LICENSE for details.


Built with โค๏ธ for the security community ยท Star โญ if you find it useful

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

secara-0.10.2.tar.gz (104.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

secara-0.10.2-py3-none-any.whl (104.1 kB view details)

Uploaded Python 3

File details

Details for the file secara-0.10.2.tar.gz.

File metadata

  • Download URL: secara-0.10.2.tar.gz
  • Upload date:
  • Size: 104.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for secara-0.10.2.tar.gz
Algorithm Hash digest
SHA256 37c751ab139708ca8d3d5ab30ad4b578f3704f432f6d61a89e450a66499daaee
MD5 c6d75eb02f4719586c32107c2c01b9dd
BLAKE2b-256 931a0a90f90c987cce72ab3887e28f3c41b2921660fa5bae37a84f5f70c6d59a

See more details on using hashes here.

File details

Details for the file secara-0.10.2-py3-none-any.whl.

File metadata

  • Download URL: secara-0.10.2-py3-none-any.whl
  • Upload date:
  • Size: 104.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for secara-0.10.2-py3-none-any.whl
Algorithm Hash digest
SHA256 8682fd976ca7c557aa1e0d502dccfde9a24ee3cb595821cafcf3899f4321ccca
MD5 7e241f4d4f90dceb9ad879417be818ca
BLAKE2b-256 810141e69fdb19923adb9deda5d857015b4cf727993329eb5b1f489492bd9ece

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page