Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
SAFE — A contextual security auditing system for research artifacts | Kitploit
Tools/GitHubGitHub/nanda-rani/safe
Static AnalysisVulnerability AnalysisCode AnalysisLearning & EducationAI Security
GitHubnanda-rani/safe

SAFE

A contextual security auditing system for research artifacts

View Repository
14 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

SAFE

SAFE performs controlled, repository-aware security assessment of Semgrep and Trivy findings in research artifacts.

It supports two independent classification tasks: direct binary prediction (SECURITY_RELEVANT or NON_SECURITY) and the detailed multiclass contextual taxonomy (three labels — see Three labels). Each task can run in zero-shot or agentic mode.

It expects only:

  1. A semicolon-delimited findings CSV.
  2. A directory containing one research-artifact folder per artifact_id.
  3. Optionally, a paper PDF/text collection keyed by artifact_id.
  4. An OpenAI API key or access to an organization LiteLLM proxy.

It does not train on or tune against any labeled evaluation data. Labeled data is used only after inference, to evaluate predictions, and is never seen by the classifier. SAFE never executes artifact code; repository text is treated as untrusted evidence, not as instructions.

This release contains the complete safe_audit source, CLI, and tests, plus a self-contained demo/ of three fully synthetic example artifacts you can run end to end without any external data. It excludes the real research-artifact corpus, ground-truth labels, and evaluation findings used in the paper.

Download Tool

Quick start: after Installation, run the Demo — it works immediately with no data setup. config.example.yaml, covered later under Configuration, is a template for your own findings/artifacts and will not run until you edit it.

Installation

root@kitploit:~
cd path/to/safe-artifact-auditor
python3 -m venv .venv
source .venv/bin/activate
pip install -e .

Set the API key:

root@kitploit:~
export OPENAI_API_KEY="your-key"

For an organization LiteLLM proxy, use config.litellm.example.yaml instead — it's commented inline. Credentials and custom header values are read from environment variables and are never stored in SAFE configuration or result files.

Demo

demo/ contains three small, fully synthetic example artifacts — none derived from or corresponding to any real published research artifact — one per taxonomy label, so reviewers can exercise the full pipeline without any external data:

  • demo-contextual-risk/ — a toy federated-learning checkpoint aggregator that deserializes a checkpoint downloaded from a caller-supplied URL with torch.load. Untrusted, network-sourced input reaches an unsafe deserialization sink, which SAFE is expected to classify CONTEXTUAL_RISK.
  • demo-hardening-recommendation/ — a toy benchmark harness that runs subprocess.run(..., shell=True) against command lines that are all hardcoded Python literals, with no caller-controlled input. SAFE is expected to classify this HARDENING_RECOMMENDATION: the shell pattern is real and worth flagging, but nothing external can reach or influence it.
  • demo-false-positive/ — a test-fixture generator pinned to an older Pillow version with a hypothetical decompression-bomb advisory. The code only creates new in-memory images and never opens external data, so the advisory's actual code path is never reached. SAFE is expected to classify this FALSE_POSITIVE.

demo/findings.csv holds one finding per artifact, and demo/demo-zero-shot.yaml / demo/demo-agentic.yaml are ready-to-run configs (artifact_root: . resolves relative to the config file, so run from inside demo/):

root@kitploit:~
cd demo
safe-audit run --config demo-zero-shot.yaml
safe-audit run --config demo-agentic.yaml

Results land in demo/runs/demo-zero-shot/ and demo/runs/demo-agentic/ respectively (see Output).

Three labels

  • CONTEXTUAL_RISK
  • HARDENING_RECOMMENDATION
  • FALSE_POSITIVE

No additional category and no deterministic label-changing rule is used. A documented, isolated research/security mechanism in an artifact's own code is classified HARDENING_RECOMMENDATION, since the underlying practice is still real even when isolation limits realistic exploitability.

Binary classes

  • SECURITY_RELEVANT: a valid contextual risk or hardening concern, including intentional, isolated security-research behavior.
  • NON_SECURITY: a false, mismatched, non-applicable, absent, or demonstrably unused affected-feature finding.

The evaluator also derives a binary view from multi-class predictions: FALSE_POSITIVE becomes NON_SECURITY; every other multi-class label becomes SECURITY_RELEVANT. Direct and derived binary results remain explicitly separate.

Input structure

root@kitploit:~
project/
├── config.yaml
├── data/
│   └── findings.csv
└── artifacts/
    ├── artifact_001/
    ├── artifact_002/
    └── artifact_003/

The mapping is exact: artifact_id = artifact_001 resolves to artifacts/artifact_001/.

Required CSV columns:

root@kitploit:~
artifact_id;tool;finding_id

Optional columns:

root@kitploit:~
artifact_id;tool;finding_id;category;severity_raw;file;line;message;package;version;cwe;cvss;scanner_applicable

An initial unnamed index column is ignored. Additional columns are preserved by the input model.

Example:

root@kitploit:~
artifact_id;tool;finding_id;category;severity_raw;file;line;message;package;version;cwe;cvss;scanner_applicable
artifact_001;semgrep;python.lang.security.audit.subprocess-shell-true;code;HIGH;src/probe.py;42;Shell command uses shell=True;;;;CWE-78;;yes
artifact_002;trivy;DEMO-CVE-0001;dependency;HIGH;;;Affected package (illustrative, not a real CVE);example-lib;1.2.0;CWE-502;8.1;yes

Generate findings from a new codebase

scripts/run_scanners.py and scripts/build_findings_csv.py produce the findings.csv and artifact layout described above directly from your own code, using Semgrep and Trivy.

Install Semgrep (works the same on any OS, including Linux):

root@kitploit:~
pip install semgrep

Install Trivy on Linux — either the apt repository (Debian/Ubuntu):

root@kitploit:~
sudo apt-get install wget gnupg
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install trivy

or the official install script, which works on any Linux distribution and installs a binary release into /usr/local/bin (no root packages required beyond sudo for that directory):

root@kitploit:~
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin

Verify both are on PATH before continuing:

root@kitploit:~
semgrep --version
trivy --version

Then lay out one directory per artifact under an artifact_root/ and run:

root@kitploit:~
python scripts/run_scanners.py artifact_root --output scan-output
python scripts/build_findings_csv.py scan-output --output data/findings.csv

The first command runs Semgrep and Trivy (vulnerability and secret scanning) against each artifact directory and saves the raw scanner JSON. The second parses that JSON into a SAFE-compatible findings.csv (columns match Input structure; file is reported relative to each artifact directory). Pass --skip-semgrep/--skip-trivy to either script to run only one tool. --config on run_scanners.py pins a specific Semgrep ruleset instead of the default auto, which is convenient but not reproducibly pinned.

Configuration

This section is for running SAFE against your own findings CSV and artifact folders (see Input structure above). If you just want to see SAFE run, use Demo instead — config.example.yaml below is a template and will not run as-is.

Copy config.example.yaml:

root@kitploit:~
cp config.example.yaml config.yaml

Then edit input_csv and artifact_root (and optionally paper_root) to point at your own data before running.

Key settings:

  • model / provider: exact OpenAI model identifier (or LiteLLM alias), and openai or litellm with proxy URL and credential environment-variable name.
  • analysis_mode: zero_shot or agentic.
  • classification_task: binary or multiclass; independent of analysis_mode.
  • max_agent_steps: required only in an agentic configuration.
  • max_workers / max_output_tokens / max_schema_retries: concurrency, per-response output ceiling, and model-call retry budget for schema-invalid responses.
  • resume / resume_policy: incomplete retries failures, missing artifacts, and unattempted findings; failed_only retries only failures while retaining recorded successes.
  • cost: optional live cost accounting and max_run_cost_usd termination.

The default model is gpt-5.6-sol. Change it explicitly if availability, cost, or latency requirements differ.

Run analysis

root@kitploit:~
safe-audit run --config config.yaml

Or without installing the console command:

root@kitploit:~
PYTHONPATH=src python -m safe_audit.cli run --config config.yaml

For a runnable matched comparison against the included synthetic data, see Demo (demo/demo-zero-shot.yaml and demo/demo-agentic.yaml). They differ only in analysis_mode and run_name. Zero-shot makes one model call over the base evidence. Agentic mode starts from the same evidence and may call bounded read-only repository tools before returning the same structured result.

Output

root@kitploit:~
runs/<run_name>/
├── config.resolved.yaml
├── run_metadata.json
├── summary.json
├── results.jsonl
├── results.csv
├── profiles/
├── evidence/
├── raw/<finding_uid>/
│   ├── 0001-request.json
│   ├── 0001-response.json (or 0001-error.json)
│   └── final-output.txt
└── logs/
    ├── events.jsonl
    ├── result_attempts.jsonl
    └── run_sessions.jsonl

results.csv is intended for analysis. results.jsonl preserves the complete structured records. Evidence and raw model outputs support auditing and error analysis. Both are canonical: they contain only the latest record for each finding, while logs/result_attempts.jsonl is append-only and preserves every historical outcome.

On resume, SAFE first re-parses every failed finding's saved raw responses with the current strict parser; a uniquely valid classification is recovered without an API call. Only unrecoverable failures are scheduled for model inference. For a failed-only continuation of a partially completed run, keep the same output_root and run_name and set:

root@kitploit:~
resume: true
resume_policy: failed_only

To evaluate predictions against a labeled gold CSV (with a security_label or security_class column):

root@kitploit:~
safe-audit evaluate --results runs/<run_name>/results.jsonl --gold GOLD.csv --output runs/<run_name>/evaluation.json

Testing

root@kitploit:~
PYTHONPATH=src python -m unittest discover -s tests -v

The test suite uses a fake provider and therefore does not require an API key.