GitHub Security Lab Taskflow Agent द्वारा संचालित एक LLM-आधारित फ़ज़िंग पाइपलाइन
नेटिव C/C++ प्रोजेक्ट्स के लिए एक LLM-संचालित, OSS-Fuzz-शैली की फ़ज़िंग पाइपलाइन। निष्पादन के लिए AFL++, कवरेज के लिए clang+lcov, हार्नेस लेखन, कवरेज-फ़ीडबैक निर्णयों, ट्राइएज और रिपोर्टिंग के लिए एक LLM एजेंट।
इस रेपॉजिटरी में
GitHub Security Lab Taskflow Agent के लिए fuzzing taskflow शामिल है।
यह कुछ साझा बिल्डिंग ब्लॉक्स
(fetch_source_code taskflow, local_file_viewer / gh_file_viewer
toolboxes, और डिफ़ॉल्ट model_config) के लिए
seclab-taskflows
सहयोगी रेपॉजिटरी पर निर्भर करता है — ये एक Python निर्भरता के रूप में
स्वचालित रूप से इंस्टॉल हो जाते हैं।
योगदान का स्वागत है! दिशानिर्देशों के लिए कृपया CONTRIBUTING.md देखें।
apt तक पहुँच वाला एक Linux वातावरण (या Codespace)gh)pip install git+https://github.com/GitHubSecurityLab/seclab-taskflows-fuzzing
यह `seclab-taskflow-agent` और `seclab-taskflows` (parent) को
संक्रमणीय रूप से शामिल करता है, इसलिए
`seclab_taskflows.taskflows.audit.*`,
`seclab_taskflows.toolboxes.local_file_viewer`,
`seclab_taskflows.toolboxes.gh_file_viewer`, और
`seclab_taskflows.configs.model_config` के रूप में प्रत्येक डॉटेड संदर्भ
रनटाइम पर parent वितरण से हल हो जाता है।
---
## विषय-सूची
1. [यह क्या है](#what-this-is)
2. [त्वरित शुरुआत](#quick-start)
3. [आर्किटेक्चर](#architecture)
4. [पाइपलाइन, चरण दर चरण](#the-pipeline-stage-by-stage)
5. [कवरेज-फीडबैक लूप](#the-coverage-feedback-loop)
6. [संरचना-जागरूक फ़ज़िंग](#structure-aware-fuzzing)
7. [पुनरावृत्तियों और अभियानों में स्थायी कॉर्पस](#persistent-corpus-across-iterations-and-campaigns)
8. [ट्राइएज और भेद्यता रिपोर्ट](#triage-and-vulnerability-reports)
9. [लाइव डैशबोर्ड](#live-dashboard)
10. [आउटपुट फ़ाइलें](#output-files)
11. [डेटाबेस स्कीमा](#database-schema)
12. [MCP टूल्स (एजेंट की शब्दावली)](#mcp-tools-the-agents-vocabulary)
13. [समायोज्य नॉब्स (पर्यावरण चर)](#tunable-knobs-environment-variables)
14. [पाइपलाइन का विस्तार](#extending-the-pipeline)
15. [बेंचमार्क प्रोजेक्ट्स और परिणाम](#benchmark-projects-and-results)
16. [सीमाएँ और सावधानियाँ](#limitations-and-gotchas)
17. [सुरक्षा चेतावनी](#security-warning)
18. [विकास: परीक्षण, लिंटिंग, योगदान](#development-testing-linting-contributing)
19. [शब्दावली](#glossary)
---
## यह क्या है
यह टास्कफ़्लो एक पूर्णतः स्वायत्त फ़ज़िंग पाइपलाइन है। एक नेटिव C/C++ प्रोजेक्ट के GitHub रेपो को देखते हुए, यह:
1. यदि अनुपस्थित हों तो AFL++ + clang/llvm/lcov + ctags/cscope/graphviz इंस्टॉल करेगा,
2. स्रोत प्राप्त करेगा,
3. संभावित फ़ज़ लक्ष्यों (पार्सर, डिकोडर, वैलिडेटर, …) की पहचान करेगा,
4. बिल्ड सिस्टम का विश्लेषण करेगा,
5. प्रति लक्ष्य एक या अधिक हार्नेस उम्मीदवार लिखेगा, प्रत्येक को AFL-इंस्ट्रुमेंटेड `.afl` बाइनरी और कवरेज-इंस्ट्रुमेंटेड `.cov` बाइनरी दोनों के रूप में बनाएगा,
6. (वैकल्पिक रूप से) 60-सेकंड कवरेज द्वारा उम्मीदवारों को योग्य ठहराएगा और सर्वश्रेष्ठ रखेगा,
7. दोगुने समय बजट के साथ फ़ज़/कवरेज/सुधार लूप चलाएगा,
8. प्रत्येक क्रैश का ट्राइएज करेगा, पुष्टि करेगा कि पहले से ज्ञात क्रैश अभी भी पुनरुत्पादित होते हैं, और प्रति-क्रैश मार्कडाउन भेद्यता रिपोर्ट लिखेगा जिसमें निर्णय, शोषणीयता, सुझाए गए पैच, और रिग्रेशन-टेस्ट स्केच शामिल होंगे,
9. अगले अभियान के लिए Fuzz-Introspector-शैली का कॉल ग्राफ़ + अछूते-API रिपोर्ट बनाएगा,
10. सब कुछ एक लाइव HTML डैशबोर्ड पर प्रकाशित करेगा।
पाइपलाइन भावना में **OSS-Fuzz-शैली** की है: यह कई समान तकनीकों का उपयोग करती है (प्रति-फ़ॉर्मेट म्यूटेटर और डिक्शनरी, संरचना-जागरूक टोकन स्प्लिसिंग, कवरेज-चालित हार्नेस सुधार, मशीन-पठनीय रिपोर्ट, डीडुप्ड स्टैक-हैश्ड क्रैश) लेकिन यह बहुत छोटी और स्व-निहित है।
---
## त्वरित शुरुआत```bash
# Inside the codespace (or a host with python + git available):
./scripts/fuzzing/run_fuzzing.sh tukaani-project/xz
यही पूरा इंटरफ़ेस है। स्क्रिप्ट स्वायत्त है; यह पहली बार चलाने पर AFL++
इंस्टॉल करेगी, फिर बाकी टास्कफ़्लो को चलाएगी। आउटपुट फ़ाइलें
~/.local/share/seclab-taskflow-agent/seclab-taskflows/ में लिखी जाती हैं।
डैशबोर्ड बैकग्राउंड में स्वतः शुरू हो जाता है; Codespace में, पोर्ट 8765
स्वतः फ़ॉरवर्ड हो जाता है — प्रगति को लाइव देखने के लिए इसे किसी भी ब्राउज़र में खोलें।
एक त्वरित स्मोक-टेस्ट के लिए, एक छोटा लक्ष्य उपयोग करें:```bash ./scripts/fuzzing/run_fuzzing.sh DaveGamble/cJSON
---
## आर्किटेक्चर
तीन परतें, ऊपर से नीचे:```
┌────────────────────────────────────────────────────────────────────┐
│ scripts/fuzzing/run_fuzzing.sh │
│ shell driver; chains the taskflow stages with `set +e` │
└────────────────────┬───────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────┐
│ src/seclab_taskflows/taskflows/fuzzing/*.yaml │
│ LLM agent prompts; one YAML per pipeline stage │
└────────────────────┬───────────────────────────────────────────────┘
│ (calls MCP tools)
▼
┌────────────────────────────────────────────────────────────────────┐
│ src/seclab_taskflows/mcp_servers/ │
│ ├ fuzz_context.py persistence (SQLite via SQLAlchemy) │
│ └ fuzz_runner.py subprocess wrappers (AFL, clang, lcov, ...) │
│ │
│ scripts/fuzzing/dashboard.py │
│ read-only HTML view of fuzz_context.db │
└────────────────────────────────────────────────────────────────────┘
मुख्य डिज़ाइन नियम:
fuzz_context.db में रहती है।run_afl_for, compile_harness, store_crash, आदि को एक्सपोज़ करते हैं।afl-clang-lto -fsanitize=address,undefined के साथ (.afl बाइनरी) और एक बार
clang -fprofile-instr-generate -fcoverage-mapping के साथ (.cov
बाइनरी)। .afl बाइनरी फ़ज़ करती है; .cov बाइनरी वास्तविक सोर्स-लाइन/फ़ंक्शन/ब्रांच कवरेज उत्पन्न करने के लिए AFL
क्यू को रीप्ले करती है।| # | चरण | Taskflow YAML |
|---|---|---|
| 1 | AFL++ + टूलिंग इंस्टॉल करें | scripts/fuzzing/install_afl.sh |
| 2 | सोर्स फ़ेच करें | seclab_taskflows.taskflows.audit.fetch_source_code |
| 3 | फ़ज़ टारगेट पहचानें | seclab_taskflows_fuzzing.taskflows.fuzzing.identify_fuzz_targets |
| 4 | बिल्ड सिस्टम का विश्लेषण करें | seclab_taskflows_fuzzing.taskflows.fuzzing.analyze_build_system |
| 5a | प्रारंभिक हार्नेस लिखें (अनुरोध किए जाने पर ×N कैंडिडेट) | seclab_taskflows_fuzzing.taskflows.fuzzing.write_initial_harnesses |
| 5b | हार्नेस बिल्ड करें (AFL + कवरेज) | seclab_taskflows_fuzzing.taskflows.fuzzing.build_harnesses |
| 5c | कैंडिडेट को क्वालिफ़ाई करें (जब HARNESS_CANDIDATES > 1) | seclab_taskflows_fuzzing.taskflows.fuzzing.qualify_harnesses |
| 6 | फ़ज़/कवरेज/सुधार लूप (×N इटरेशन) | seclab_taskflows_fuzzing.taskflows.fuzzing.fuzz_iteration |
| 7 | क्रैश का ट्रायाज करें | seclab_taskflows_fuzzing.taskflows.fuzzing.triage_crashes |
| 8 | पुष्टि करें कि पहले से ज्ञात क्रैश अभी भी रीप्रोड्यूस होते हैं | seclab_taskflows_fuzzing.taskflows.fuzzing.confirm_fixed_crashes |
| 9 | कॉल ग्राफ़ + अनटच्ड-API रिपोर्ट बनाएँ | seclab_taskflows_fuzzing.taskflows.fuzzing.analyze_call_graph |
| 10 | प्रति-क्रैश वल्न रिपोर्ट लिखें | seclab_taskflows_fuzzing.taskflows.fuzzing.write_vuln_reports |
| 11 | कैंपेन रिपोर्ट लिखें | seclab_taskflows_fuzzing.taskflows.fuzzing.write_report |
प्रत्येक चरण एक स्व-निहित taskflow YAML है जिसे एजेंट
एंड-टू-एंड चलाता है। चरण विशेष रूप से fuzz_context.db में SQLite डेटाबेस के माध्यम से
संवाद करते हैं — कोई इन-मेमोरी हैंड-ऑफ़ नहीं है।
यह पाइपलाइन का हृदय है। समय बजट प्रत्येक इटरेशन में दोगुना होता है:``` 30s → 60s → 120s → 240s → 480s → 960s (≈ 32 min/target)
प्रति पुनरावृत्ति, प्रति हार्नेस, एजेंट:
1. इस हार्नेस की स्थिर कॉर्पस डायरेक्टरी के लिए `get_persistent_corpus_dir(harness_id)` को कॉल करता है।
2. `run_afl_for(afl_binary_path, seed_dir=<persistent corpus>, output_dir=<run dir>, seconds=<budget>, dictionary=<auto.dict>)` को कॉल करता है।
3. LCOV ट्रेसफ़ाइल और HTML रिपोर्ट उत्पन्न करने के लिए `run_coverage(cov_binary_path, inputs_dir=<run>/default/queue, output_dir=<run>/coverage)` को कॉल करता है।
4. एक `coverage_report` पंक्ति + प्रति-अनकवर आइटम `coverage_gap` पंक्तियों को स्थायी बनाने के लिए `store_coverage_from_lcov(run_id, lcov_path, html_path)` को कॉल करता है।
5. AFL की पुनरावृत्ति कतार को स्थायी कॉर्पस में मर्ज करने और आकार को सीमित रखने के लिए `cmin` चलाने हेतु `fold_queue_into_persistent_corpus(...)` को कॉल करता है।
6. `get_coverage_summary` + `get_coverage_gaps` को पढ़ता है, फिर या तो:
- एक अनकवर ब्रांच तक पहुँचने के लिए एक नया सीड जोड़ता है (जिसे `coverage_feedback` टैग किया जाता है),
- एक अतिरिक्त API को कॉल करने के लिए हार्नेस स्रोत को संपादित करता है,
- एक गार्ड को संतुष्ट करने के लिए AFL को आवश्यक मैजिक कॉन्स्टेंट के लिए डिक्शनरी प्रविष्टियों को स्वतः जोड़ने हेतु `enrich_dictionary_from_uncovered(...)` को कॉल करता है, या
- अंतराल को छोड़ देता है (कोल्ड एरर पथ / विक्रेता कोड)।
7. `store_iteration_note(repo, iteration_number, harness_id, note=<one line summary>)` को कॉल करता है ताकि डैशबोर्ड की पुनरावृत्ति टाइमलाइन ट्रैक कर सके कि क्या बदला।
**पठार का पता लगाना।** लूप जल्दी समाप्त हो जाता है जब दो लगातार पुनरावृत्तियों ने लाइन कवरेज के `<FUZZ_PLATEAU_THRESHOLD_PCT` (डिफ़ॉल्ट `1.0`) पूर्ण प्रतिशत अंक से कम लाभ प्राप्त किया हो।
---
## संरचना-जागरूक फ़ज़िंग
तीन पूरक तंत्र कच्चे बाइट म्यूटेशन की तुलना में मजबूत इनपुट उत्पन्न करते हैं।
### 1. प्रति-प्रारूप डिक्शनरी + कस्टम म्यूटेटर
उन लक्ष्यों के लिए जिनका `input_kind` किसी ज्ञात प्रारूप से मेल खाता है, टास्कफ़्लो पूर्व-निर्मित डिक्शनरी और `LLVMFuzzerCustomMutator` C स्रोत फ़ाइलें भेजता है:
| प्रारूप | डिक्शनरी | म्यूटेटर | नोट्स |
|--------|------------|---------|-------|
| `json` | `json.dict` | `json_mutator.c` | टोकन स्प्लाइस, संतुलित ब्रैकेट डुप/ड्रॉप, टाइप फ्लिप |
| `xml` | `xml.dict` | `xml_mutator.c` | टैग, एंटिटीज़, DTDs, बिलियन-लाफ्स टोकन |
| `regex` | `regex.dict` | `regex_mutator.c` | एंकर, क्लासेस, क्वांटिफायर, वास्तविक ReDoS पैटर्न |
| `binary_tlv` | _(कोई नहीं)_ | `binary_tlv_mutator.c` | लंबाई-प्रीफ़िक्स्ड रिकॉर्ड: लंबाई-ओवरफ़्लो / डुप / ड्रॉप |
| `png` | `png.dict` | _(binary_tlv का पुन: उपयोग)_ | PNG डिक्शनरी + binary_tlv म्यूटेटर |
इन्हें `write_initial_harnesses` (डिक्शनरी सीड्स के बगल में कॉपी की जाती है) और `build_harnesses` (म्यूटेटर AFL बाइनरी में लिंक किया जाता है) द्वारा स्वचालित रूप से उठाया जाता है। प्रत्येक म्यूटेटर 50% म्यूटेशन AFL के डिफ़ॉल्ट बाइट म्यूटेटर को सौंपता है ताकि हम इंजन की रैंडमाइज़ेशन न खोएँ।
एक नया प्रारूप जोड़ने के लिए: `src/seclab_taskflows/dictionaries/` में एक `<name>.dict` और/या एक `<name>_mutator.c` डालें, फिर इसे `fuzz_runner.py` के निचले भाग में `_FORMAT_ASSETS` मैप में पंजीकृत करें।
### 2. स्रोत-जागरूक (प्रोजेक्ट-विशिष्ट) स्मार्ट म्यूटेटर
अपरिचित प्रारूपों के लिए, या जब भी आप मजबूत प्रोजेक्ट-विशिष्ट टोकन चाहते हैं, `generate_smart_mutator` लक्ष्य रेपो की अपनी `.c`/`.h` फ़ाइलों को स्कैन करता है और एक `LLVMFuzzerCustomMutator` C फ़ाइल उत्सर्जित करता है जिसकी स्प्लाइस डिक्शनरी निम्न से निकाली जाती हैं:
- ≥3 वर्णमाला वर्णों वाले स्ट्रिंग लिटरल (कंपाइलर/लाइसेंस शोर, पथ, हेडर, asm कंस्ट्रेंट, प्रारूप स्पेसिफायर को फ़िल्टर करने के बाद),
- `#define`, `case`, और `enum` से 32-बिट संख्यात्मक कॉन्स्टेंट (0, 1, 256, 0xff… जैसे सामान्य छोटे-इंट शोर को फ़िल्टर करने के बाद)।
तीन फोकस उपलब्ध हैं:
| फोकस | क्या स्प्लाइस करता है | कब उपयोग करें |
|-------|-----------------|-------------|
| `strings` | केवल प्रोजेक्ट स्ट्रिंग लिटरल | टेक्स्ट प्रारूप (JSON, XML, YAML, CSV) |
| `constants` | केवल 32-बिट संख्यात्मक मैजिक मान | बाइनरी प्रोटोकॉल, मैजिक नंबर वाले हेडर |
| `combined` | दोनों | डिफ़ॉल्ट; आमतौर पर सर्वोत्तम |
`generate_smart_mutators(...)` (बहुवचन) को `HARNESS_CANDIDATES >= 3` के साथ जोड़ें ताकि प्रत्येक फोकस क्वालिफायर राउंड में एक उम्मीदवार हार्नेस बन जाए।
### 3. प्रोजेक्ट-जागरूक AFL डिक्शनरी + कवरेज-चालित संवर्धन
दो पूरक उपकरण अभियान के दौरान एक AFL `-x` डिक्शनरी बनाते और बढ़ाते हैं:
- **`generate_project_dictionary(source_root, output_path)`** — पुनरावृत्ति 1 से पहले एक बार चलता है, स्मार्ट म्यूटेटर द्वारा उपयोग किए जाने वाले समान स्रोत-टोकन सेट को स्थिर रूप से निकालता है और इसे AFL डिक्शनरी के रूप में लिखता है। संख्यात्मक कॉन्स्टेंट दोनों एंडियननेस में उत्सर्जित होते हैं ताकि फ़ज़र होस्ट बाइट ऑर्डर की परवाह किए बिना `memcmp(x, &magic, 4)` को संतुष्ट कर सके।
- **`enrich_dictionary_from_uncovered(source_root, dictionary_path, uncovered_locations)`** — प्रत्येक पुनरावृत्ति के कवरेज चरण के बाद चलता है, अनकवर लाइनों के पास सशर्त गार्ड (`strncmp/memcmp/strstr`, `case 0xN:`, `== 0xN`, `== 'X'`) के लिए आसपास के स्रोत को स्कैन करता है, और किसी भी नए टोकन को डिक्शनरी में जोड़ता है। इडेम्पोटेंट: पहले से मौजूद प्रविष्टि को कभी दोबारा नहीं जोड़ता।
### 4. कॉर्पस-स्प्लाइस ऑप
जब `corpus_dir` को `generate_smart_mutator` में पास किया जाता है, तो उत्पन्न C को एक कॉर्पस-स्प्लाइस ऑपरेटर भी मिलता है: पहली कॉल पर यह उस डायरेक्टरी से 64 फ़ाइलों तक लोड करता है (प्रत्येक 4 KiB तक सीमित), और उसके बाद उन फ़ाइलों के यादृच्छिक उप-क्षेत्रों को म्यूटेटेड इनपुट में स्प्लाइस कर सकता है। यह म्यूटेटर को एक रीकॉम्बिनेशन-शैली ऑपरेटर देता है जो AFL का स्टॉक हेवोक अच्छी तरह नहीं करता। `get_persistent_corpus_dir(...)` के साथ जोड़ें ताकि स्प्लाइस लाइब्रेरी "जो AFL ने पहले ही खोज लिया है उसे रीमिक्स करे"।
---
## पुनरावृत्तियों और अभियानों में स्थायी कॉर्पस
प्रत्येक हार्नेस की एक स्थिर कॉर्पस डायरेक्टरी होती है:```
<workspace>/corpus/harness_<id>/
यह वही है जिसे fuzz_iteration, run_afl_for के लिए seed_dir के रूप में उपयोग करता है (<harness>/seeds के बजाय)। प्रत्येक iteration के अंत में, fold_queue_into_persistent_corpus(...) AFL की iteration queue को इस dir में merge करता है और इसे bounded रखने के लिए afl-cmin चलाता है।
परिणाम: कल की queue आज के run में और उसी project के re-runs में भी carry होती है। campaign का stop-and-restart करने पर कोई progress नहीं खोता।
fuzz/coverage/improve loop समाप्त होने के बाद, तीन stages स्वचालित रूप से चलते हैं:
triage_crashes<run>/default/crashes/ में प्रत्येक crash file के लिए:
afl-tmin,stack_top_hash capture करने के लिए replay_under_asan
(top-N normalised frames; templates, libcxx inline namespaces, anonymous
namespaces, और LTO numeric suffixes हटा दिए जाते हैं ताकि semantically
identical crashes का hash समान हो),crash row persist करें।confirm_fixed_crashesप्रत्येक पहले से classified crash (जिसका verdict पहले से fixed/duplicate/non_reproducible नहीं है) को वर्तमान AFL+ASan binary के माध्यम से replay करता है। यदि यह अब crash नहीं होता, तो verdict="fixed" mark करता है। यह तब उपयोगी है जब किसी project के विरुद्ध campaign re-run किया जा रहा हो जिसमें पिछले campaign के बाद से upstream fixes लागू हो चुके हैं।
write_vuln_reportsप्रत्येक unique crash के लिए, agent harness source + crashing function का source पढ़ता है, public API से call chain को walk करता है, फिर दस OSS-Fuzz-style verdicts में से एक assign करता है और एक markdown vuln report लिखता है:
| Verdict | Meaning |
|---|---|
vulnerability | वास्तविक, public API के माध्यम से exploitable |
library_hardening | वास्तविक bug लेकिन कोई realistic public-API path नहीं; library को फिर भी अपनी रक्षा करनी चाहिए |
harness_bug | Bug हमारे harness में है, library में नहीं |
non_reproducible | Replay minimised input पर crash reproduce नहीं करता |
oom | Out-of-memory; vuln केवल तब यदि attacker-controllable size unbounded हो |
timeout | algorithmic blow-up के माध्यम से DoS |
assertion_failure | assert() hit; security relevance भिन्न होती है |
fixed | confirm_fixed_crashes द्वारा set: input अब reproduce नहीं करता |
duplicate | भिन्न stack hash के साथ किसी अन्य crash के समान root cause |
needs_investigation | निर्धारित नहीं कर सका; human review के लिए flagged |
प्रत्येक vuln report में शामिल है:
Dashboard run_fuzzing.sh द्वारा background में स्वचालित रूप से start किया जाता है। FUZZ_NO_DASHBOARD=1 से disable करें; port को FUZZ_DASHBOARD_PORT से override करें (default 8765)।
Codespace में, port 8765 auto-forwarded होता है — forwarded URL को किसी भी browser में खोलें। Page हर 5 s में auto-refresh होता है और दिखाता है:
fuzz_runvulnerability पहले), प्रत्येक vuln report और minimised input से link करता हैDashboard scripts के लिए एक छोटा read-only JSON API भी expose करता है:```bash
curl 'http://127.0.0.1:8765/api/json?repo=kkos/oniguruma' | jq .
---
## आउटपुट फ़ाइलें
सभी `~/.local/share/seclab-taskflow-agent/seclab-taskflows/` के अंतर्गत।
| पथ | सामग्री |
|------|----------|
| `fuzz_context/fuzz_context.db` | SQLite — लक्ष्य, हार्नेस, रन, कवरेज, क्रैश, निर्णय, कॉल ग्राफ़, हार्नेस सुझाव, पुनरावृत्ति नोट्स |
| `fuzz_runner/builds/` | निर्मित `.afl` और `.cov` बाइनरी |
| `fuzz_runner/runs/` | AFL आउटपुट डायरेक्टरी + LCOV फ़ाइलें + HTML कवरेज रिपोर्ट |
| `fuzz_runner/corpus/harness_<id>/` | प्रति हार्नेस स्थायी कॉर्पस (पुनरावृत्तियों और अभियानों में बना रहता है) |
| `fuzz_runner/repo/<owner>__<repo>/REPORT.md` | Markdown अभियान सारांश, निर्णय के अनुसार समूहीकृत क्रैश |
| `fuzz_runner/repo/<owner>__<repo>/vuln_<crash_id>.md` | प्रति-क्रैश markdown भेद्यता रिपोर्ट |
| `fuzz_runner/repo/<owner>__<repo>/call_graph.{dot,svg,md}` | स्थिर कॉल ग्राफ़ + पहुँचे/अपहुँचे ओवरले |
---
## डेटाबेस स्कीमा
`fuzz_context.db` में तालिकाएँ (SQLAlchemy के माध्यम से SQLite):
| तालिका | रुचि के कॉलम |
|-------|--------------------|
| `fuzz_target` | `repo, file, function, signature, input_kind` |
| `harness` | `target_id, repo, harness_path, afl_binary_path, cov_binary_path, build_status, version, sanitizers` |
| `seed_corpus` | `target_id, source, path, bytes_count, added_in_iteration` |
| `fuzz_run` | `harness_id, iteration_number, exec_per_sec, paths_total, crashes_count, status, output_dir, started_at, ended_at` |
| `coverage_report` | `run_id, lines_total, lines_hit, line_pct, fns_*, branches_*, lcov_path, html_path` |
| `coverage_gap` | `report_id, file, function, line, kind, reason_hint` |
| `crash` | `run_id, input_blob_path, minimized_path, stack_top_hash, sanitizer_output, verdict, bug_class, cwe, severity, vuln_report_path, reproducer_path, classification, notes` |
| `call_graph` | `repo, target_id, dot_path, svg_path, functions_total, functions_in_graph, functions_reached, functions_unreached, untouched_surface_json` |
| `harness_suggestion` | `repo, function_name, file, rationale, input_kind, priority` |
| `iteration_note` | `repo, harness_id, iteration_number, note, created_at` |
स्कीमा माइग्रेशन `fuzz_context.py` में `_migrate()` में स्थित हैं। नई TABLES
`Base.metadata.create_all()` द्वारा स्वतः-निर्मित होती हैं; केवल नए COLUMNS के लिए
PRAGMA-आधारित `ALTER TABLE` की आवश्यकता होती है।
---
## MCP टूल्स (एजेंट की शब्दावली)
एजेंट कभी सीधे AFL या clang को कॉल नहीं करता — यह MCP टूल्स को कॉल करके
पाइपलाइन को संयोजित करता है। पूरा सेट, उद्देश्य के अनुसार समूहीकृत:
### दृढ़ता (`fuzz_context.py`)
- `store_fuzz_target`, `get_fuzz_targets`
- `store_harness`, `update_harness_build`, `get_harnesses`
- `store_seed`, `start_fuzz_run`, `finish_fuzz_run`, `get_fuzz_runs`
- `store_coverage_from_lcov`, `get_coverage_summary`, `get_coverage_gaps`,
`coverage_plateau_reached`
- `store_crash`, `update_crash_verdict`, `get_crashes`,
`get_crashes_grouped`, `suggest_severity`
- `store_call_graph`, `get_call_graphs`, `get_repo_reached_functions`
- `store_harness_suggestion`, `get_harness_suggestions`
- `store_iteration_note`, `get_iteration_notes`
### बिल्ड / फ़ज़ / कवरेज (`fuzz_runner.py`)
- `check_tooling`, `workspace_paths`
- `compile_harness` — `.afl` और `.cov` बाइनरी बनाता है
- `run_afl_for`, `cmin`, `tmin`, `replay_under_asan`, `reproduce_crash`
- `run_coverage` — `.cov` बाइनरी के विरुद्ध AFL कतार को रीप्ले करता है, LCOV निर्यात करता है
- `extract_dictionary` — बाइनरी से प्रिंटेबल स्ट्रिंग्स निकालता है
- `package_reproducer` — एकल-क्रैश `.tgz` को बंडल करता है
### स्थायी कॉर्पस (v8)
- `get_persistent_corpus_dir`, `fold_queue_into_persistent_corpus`
### फ़ॉर्मेट एसेट्स (C5)
- `list_format_assets`, `get_format_dictionary`, `write_format_mutator`
### स्मार्ट म्यूटेटर + प्रोजेक्ट-जागरूक डिक्शनरी
- `generate_smart_mutator`, `generate_smart_mutators`
- `generate_project_dictionary`, `enrich_dictionary_from_uncovered`
टूल फ़ंक्शन `@mcp.tool()` (FastMCP) से सज्जित हैं। परीक्षणों के अंदर,
उन्हें `.fn` एट्रिब्यूट के माध्यम से आमंत्रित करें, जैसे
`fr.run_afl_for.fn(afl_binary_path=..., ...)`।
---
## ट्यूनेबल नॉब्स (पर्यावरण चर)
| चर | डिफ़ॉल्ट | उद्देश्य |
|----------|---------|---------|
| `HARNESS_CANDIDATES` | `1` | प्रति लक्ष्य लिखे गए उम्मीदवार हार्नेस की संख्या। OSS-Fuzz-Gen-शैली प्रतिस्पर्धा के लिए 2 या 3 पर सेट करें। क्वालिफायर चरण प्रत्येक को `QUALIFIER_SECONDS` तक चलाता है और लाइन % के आधार पर सर्वश्रेष्ठ रखता है। |
| `QUALIFIER_SECONDS` | `60` | क्वालिफायर चरण में प्रति-उम्मीदवार वॉल-क्लॉक बजट। |
| `FUZZ_PLATEAU_THRESHOLD_PCT` | `1.0` | लाइन-कवरेज लाभ (पूर्ण pp में) जिसके नीचे दो क्रमागत पुनरावृत्तियों को पठार माना जाता है और लूप जल्दी रुक जाता है। |
| `FUZZ_DASHBOARD_PORT` | `8765` | लाइव डैशबोर्ड के लिए पोर्ट। |
| `FUZZ_NO_DASHBOARD` | (अनसेट) | डैशबोर्ड शुरू करना छोड़ने के लिए `1` पर सेट करें। |
| `FUZZ_RUNNER_TIMEOUT` | `1200` | `fuzz_runner` में प्रति-टूल सबप्रोसेस टाइमआउट (सेकंड)। |
| `LOCAL_SHELL_TIMEOUT` | `180` | `local_shell` में प्रति-कमांड टाइमआउट (सेकंड)। |
साथ ही मानक एजेंट चर (`COPILOT_TOKEN`, `LOG_DIR`,
`FUZZ_CONTEXT_DIR`, …)। पूरी सूची के लिए प्रोजेक्ट रूट README देखें।
---
## पाइपलाइन का विस्तार
### नया फ़ॉर्मेट जोड़ना (म्यूटेटर + डिक्शनरी)
1. `dictionaries/<name>.dict` (AFL `-x` फ़ॉर्मेट) और/या
`dictionaries/<name>_mutator.c` (libFuzzer कस्टम म्यूटेटर) छोड़ें।
2. `fuzz_runner.py` के निचले भाग में `_FORMAT_ASSETS` में पंजीकृत करें: ```python
"<name>": {
"dictionary": "<name>.dict",
"mutator": "<name>_mutator.c",
"description": "Short one-liner about the format",
},
list_format_assets() के माध्यम से स्वचालित रूप से उठा लेगा।fuzz_context.py (persistence के लिए) या fuzz_runner.py (subprocess कार्य के लिए) में एक @mcp.tool()-decorated फ़ंक्शन जोड़ें।Annotated[type, Field(description=...)] का उपयोग करें — description वही है जो LLM देखता है।tests/test_fuzz_context.py / tests/test_fuzz_runner.py में एक unit test जोड़ें। टूल को उसके .fn attribute के माध्यम से invoke करें (FastMCP convention)।user_prompt में नए टूल का संदर्भ दें।src/seclab_taskflows/taskflows/fuzzing/ में एक नया YAML बनाएं। मौजूदा फ़ाइलों में से एक (जैसे triage_crashes.yaml) को template के रूप में उपयोग करें।scripts/fuzzing/run_fuzzing.sh में सही दो मौजूदा stages के बीच wire करें।scripts/fuzzing/dashboard.py में एक stage-specific dashboard section जोड़ें।जब एक नई SQL table जोड़ें:
fuzz_context_models.py में SQLAlchemy model जोड़ें।Base.metadata.create_all() engine init पर कॉल किया जाता है और नई tables स्वचालित रूप से बना देता है।जब किसी मौजूदा table में एक नया COLUMN जोड़ें:
fuzz_context.py में _migrate() में एक PRAGMA table_info + ALTER TABLE ADD COLUMN block जोड़ें ताकि पुराने DBs पारदर्शी रूप से upgrade हो जाएं।scripts/fuzzing/dashboard.py में _migrate_if_writable() को भी अपडेट करें।benchmark/projects.yaml reference projects को सूचीबद्ध करता है। इन्हें इस तरह चुना गया है कि पूरा v4+ pipeline बिना मानवीय हस्तक्षेप के codespace dev image पर end-to-end चल सके।
| # | Repo | यह दिलचस्प क्यों है | Notes |
|---|---|---|---|
| 1 | tukaani-project/xz | वास्तविक दुनिया की parser-heavy library (liblzma); समृद्ध filter chain + integer/VLI parsing surface | Baseline |
| 2 | DaveGamble/cJSON | छोटा single-file C JSON parser; trivial CMake | Pipeline के लिए त्वरित smoke |
| 3 | akheron/jansson | संक्षिप्त C JSON library जिसमें documented json_loadb() byte-buffer entry point है | CMake; बहुत तेज़ exec/sec |
| 4 | libexpat/libexpat | परिपक्व streaming XML parser; कई ऐतिहासिक CVEs | CMake या autotools |
| 5 | kkos/oniguruma | Regex engine; attacker pattern + subject लेता है | Autotools; pattern compilation ही hot path है |
codespace dev image पर पूर्ण v4-pipeline run से reference numbers (≈32 min/target):
| Repo | Targets | Harnesses | AFL runs | Crashes | Verdicts |
|---|---|---|---|---|---|
tukaani-project/xz | 8 | 8 | 48 | 0 | — |
DaveGamble/cJSON | 6 | 6 | 36 | 0 | — |
akheron/jansson | 7 | 7 | 35 | 10 | harness_bug, library_hardening, duplicate, needs_investigation |
libexpat/libexpat | 3 | 3 | 18 | 0 | — |
kkos/oniguruma | 10 | 10 | 60 | 13 | vulnerability (×2 OOB read in regerror.c), library_hardening, harness_bug, non_reproducible |
xz / cJSON / libexpat के zero-crash परिणाम अपेक्षित हैं: वे projects upstream में भारी रूप से fuzzed हैं। oniguruma में दो vulnerability-classified findings onig_snprintf_with_pattern के warning-formatting code path में वास्तविक out-of-bounds reads हैं (जब pattern backslash पर समाप्त होता है तो pat_end से एक byte आगे पढ़ना); प्रति-crash markdown reports में सुझाए गए patches शामिल हैं।
एक नया benchmark project जोड़ने के लिए, benchmark/projects.yaml में एक entry जोड़ें और (वैकल्पिक रूप से) benchmark/README.md में कारण document करें। कोई भी चीज़ जिसे मौजूदा analyze_build_system stage clang + AFL++ flags के साथ build कर सकता है, एक उचित उम्मीदवार है। Pure-C parsers, decoders, और serialisers सबसे अच्छा काम करते हैं।
BUILD_FAILED: के रूप में चिह्नित करता है और उन्हें छोड़ देता है।kernel.core_pattern=core और एक CPU governor tweak चाहिए। Codespace में ये उपलब्ध नहीं हैं, इसलिए taskflow डिफ़ॉल्ट रूप से AFL_SKIP_CPUFREQ=1 और AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 export करता है। AFL warnings प्रिंट करता है लेकिन libFuzzer-style abort handling के माध्यम से फिर भी crashes ढूंढ लेता है।<dirent.h> का उपयोग करता है। Linux/macOS के लिए ठीक; Windows पर compile नहीं होगा।compile_harness के माध्यम से बनाए गए AFL binaries argv mode में libAFLDriver का उपयोग करते हैं। इसलिए replay_under_asan और tmin डिफ़ॉल्ट रूप से stdin_input=False रखते हैं क्योंकि stdin के माध्यम से driven होने पर libAFLDriver अनंत काल तक loop करता है।generate_smart_mutator + generate_smart_mutators Python .format() का उपयोग करते हैं — C template में हर literal { / } को दोगुना किया जाना चाहिए ({{ / }})। यदि आप template edit करते हैं और KeyError दिखने लगे, तो यही कारण है।यह taskflow afl-fuzz, clang, llvm-cov, और LLM द्वारा चुने गए arbitrary build commands को सीधे host पर (बिना container) चलाता है। एक prompt-injected एजेंट सैद्धांतिक रूप से वह सब कुछ कर सकता है जो आपका user कर सकता है। केवल इनमें चलाएं:
git, apt, और build system को चाहिए।local_shell toolbox NOT एक confirmation prompt के पीछे है — taskflow autonomous है और बिना human in the loop के चलता है, इसलिए एक interactive confirmation बस हमेशा के लिए block हो जाएगा। हर shell command बाद में समीक्षा के लिए $LOG_DIR/mcp_local_shell.log में logged होता है।
hatch test
hatch fmt --linter --check
hatch fmt --linter
hatch fmt --linter --check -- src/seclab_taskflows/mcp_servers/fuzz_runner.py
कोडबेस परंपराएँ (इनका कैंपेन-इतिहास संस्करण भी `benchmark/improvements.md` में देखें):
- `os.environ.get(NAME, "default")` के बजाय
`os.environ.get(NAME) or "default"` का उपयोग करें। अन्यथा YAML टेम्पलेट
प्रतिस्थापन से आने वाली खाली स्ट्रिंग्स लौटा दी जाएँगी।
- नए एनोटेशन में `Optional[X]` के बजाय `X | None` (PEP 604) का उपयोग करें।
- टेस्ट MCP टूल्स को सीधे डेकोरेटेड नाम से नहीं, बल्कि `.fn(...)` के माध्यम से
आमंत्रित करते हैं।
- टेस्ट में `/tmp/...` लिटरल्स से बचें — `tmp_path` pytest फिक्स्चर का उपयोग
करें (लिंट नियम `S108`)।
- टेस्ट मेथड्स के अंदर सभी इनलाइन इम्पोर्ट्स के लिए `# noqa: PLC0415` आवश्यक है
यदि आप उन्हें फ़ाइल के शीर्ष पर नहीं ले जा सकते (जैसे कि `pytest.skip` के बाद
सशर्त रूप से इम्पोर्ट किए जाने पर)।
- कंपाउंड ट्रुथ टेस्ट के लिए प्रति-पंक्ति एक-असेर्शन (लिंट नियम `PT018`)।
सुधार ट्रैकर (`benchmark/improvements.md`) संस्करणों के आर-पार पाइपलाइन में जोड़े गए
बदलावों का स्थायी लॉग है। जब आप कोई महत्वपूर्ण फ़ीचर जोड़ें, तो वहाँ एक अनुभाग
जोड़ें जिसमें वर्णित हो कि क्या बदला, वह कहाँ स्थित है, और कौन-से टेस्ट उसकी रक्षा
करते हैं।
---
## शब्दावली
- **AFL++** — कवरेज-निर्देशित ग्रेबॉक्स फ़ज़र; यहाँ निष्पादन इंजन।
- **libAFLDriver** — स्टैटिक लाइब्रेरी जो AFL++ हार्नेस को libFuzzer
एंट्री-पॉइंट परंपरा (`LLVMFuzzerTestOneInput`) का उपयोग करने देती है।
- **LCOV** — उद्योग-मानक कवरेज ट्रेसफ़ाइल प्रारूप। हम `llvm-cov export -format=lcov`
के माध्यम से इसमें निर्यात करते हैं और इसे स्वयं पार्स करते हैं।
- **`stack_top_hash`** — ASan/UBSan स्टैक ट्रेस के शीर्ष N सामान्यीकृत फ़्रेम्स का
16-अक्षर का हैश। क्रैश डिडुप्लीकेशन के लिए उपयोग किया जाता है।
- **स्थायी कॉर्पस** — `<workspace>/corpus/harness_<id>/` पर प्रति-हार्नेस
डायरेक्टरी जो एक ही कैंपेन के पुनरावृत्तियों और पुनः-रन के आर-पार AFL के
रोचक इनपुट्स को बनाए रखती है।
- **स्मार्ट म्यूटेटर** — एक `LLVMFuzzerCustomMutator` जिसके स्प्लाइस टोकन लक्ष्य के
स्वयं के सोर्स कोड से निकाले जाते हैं (`generate_smart_mutator`)।
- **कस्टम म्यूटेटर (libFuzzer)** — उपयोगकर्ता-प्रदत्त C फ़ंक्शन जिसे इंजन द्वारा
बफ़र को कैसे म्यूटेट करना है, इस पर पूर्ण स्वतंत्रता के साथ कॉल किया जाता है;
AFL++ समान ABI का समर्थन करता है।
- **MCP टूल** — एक FastMCP-डेकोरेटेड फ़ंक्शन जिसे LLM एजेंट कॉल कर सकता है।
- **OSS-Fuzz / Fuzz-Introspector** — Google का ओपन-सोर्स-फ़ज़िंग
इंफ्रास्ट्रक्चर और उसका सहयोगी कॉल-ग्राफ़/कवरेज विश्लेषण टूल।
इस टास्कफ़्लो की कई सुविधाएँ (प्रति-प्रारूप म्यूटेटर, डिडुप-बाय-स्टैक,
कॉल-ग्राफ़ + अनटच्ड API रिपोर्ट, मल्टी-कैंडिडेट हार्नेस) इनसे प्रेरित हैं।
---
## लाइसेंस
यह प्रोजेक्ट MIT ओपन सोर्स लाइसेंस की शर्तों के अंतर्गत लाइसेंस प्राप्त है। पूर्ण शर्तों के लिए कृपया [LICENSE](https://github.com/githubsecuritylab/seclab-taskflows-fuzzing/blob/main/LICENSE.txt) फ़ाइल देखें।
## मेंटेनर्स
[CODEOWNERS](https://github.com/githubsecuritylab/seclab-taskflows-fuzzing/blob/main/CODEOWNERS) देखें या GitHub Security Lab टीम से संपर्क करें।
## सहायता
इस प्रोजेक्ट के साथ सहायता प्राप्त करने के तरीके के बारे में विवरण के लिए [SUPPORT.md](https://github.com/githubsecuritylab/seclab-taskflows-fuzzing/blob/main/SUPPORT.md) देखें।
## आभार
यह प्रोजेक्ट [AFL++](https://github.com/AFLplusplus/AFLplusplus), [OSS-Fuzz](https://github.com/google/oss-fuzz), और [Fuzz-Introspector](https://github.com/ossf/fuzz-introspector) की अवधारणाओं और तकनीकों पर आधारित है।