Enhance Azure Foundry support, remove promotional content, and optimize code#6
Enhance Azure Foundry support, remove promotional content, and optimize code#6yadavnikhil17102004 wants to merge 7 commits intosilentchainai:mainfrom
Conversation
- Removed upgrade button from UI and openUpgradePage method - Removed promotional text pointing to silentchain.ai - Removed referral links from update checking - Removed Professional Edition upgrade notices from finding details - Removed demo video links and upgrade-to-pro section from README - Updated footer links to focus on community resources - Cleaned up professional support contact info - Updated installation and contributing docs The codebase is now free of commercial promotional content.
… improvements, and implementation details
- Removed SILENTCHAIN-AI-Intro.gif promotional animation - Kept static images (screenshots) as they are documentation
Fixes: - P0: doPassiveScan thread pool bypass (now uses AnalyzeTask) - P0: Semaphore deadlock fix (host sem first, then global) - P0: _migrate_config crash (removed pre-init save_config) - P1: _store_cached_findings blocking I/O (now async) - P1: _async_save_cache race condition (proper flag handling) - P1: Context menu raw threads (now uses ForcedAnalyzeTask) - P1: MD5 to SHA-256 in hashing functions - P1: Added AI param field display in findings - P2: Security header categories in AI prompt - P2: IDOR param name detection (id, user_id, etc) - P2: Claude API actual connection test Updated CHANGELOG with full technical details
There was a problem hiding this comment.
Pull request overview
This PR updates the SILENTCHAIN AI Burp extension and repo documentation to support Azure Foundry, improve runtime stability/performance (thread pool + caching), and remove/relocate older promotional and legacy docs into a clearer docs/ structure.
Changes:
- Add/extend Azure Foundry provider support (including
.envvalidation tooling) and improve runtime concurrency/caching behavior. - Restructure and refresh documentation (new guides, internal architecture, maintainer workflow, optimization plan) and update README/CHANGELOG references.
- Remove/relocate older top-level docs (Quickstart/Installation/Benchmark/Notice/Contributing) into
docs/, and sanitize promotional/support references.
Reviewed changes
Copilot reviewed 18 out of 21 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| variants/silentchain_v2_enhanced.py | Adds an enhanced v2 variant UI (detail panel + HTML export) and expanded analysis output, caching, and provider support. |
| tools/test_azure_env.sh | Adds a local script to validate Azure OpenAI/Azure Foundry .env variables and probe endpoint reachability. |
| silentchain_ai_community.py | Updates stable baseline: Azure Foundry provider, thread pool + semaphores, persistent cache, improved parsing, and reduced promotional messaging. |
| docs/project/OPTIMIZATION_PLAN.md | Documents optimization baseline, completed items, risks, and forward work. |
| docs/project/NOTICE.md | Adds fork-specific legal/support notice under docs/project. |
| docs/project/CONTRIBUTING.md | Adds fork contribution policy and Azure validation instructions. |
| docs/project/BENCHMARK.md | Adds benchmark notes/template under docs/project. |
| docs/guides/QUICKSTART.md | Adds new Quick Start guide under docs/guides. |
| docs/guides/INSTALLATION.md | Adds consolidated installation/provider configuration guide under docs/guides. |
| docs/INTERNAL_WORKING.md | Adds internal architecture/runtime flow documentation. |
| docs/DEVELOPER_WORKFLOW.md | Adds maintainer workflow and verification checklist. |
| README.md | Replaces prior promotional README with fork-focused overview and doc index. |
| QUICKSTART.md | Removes legacy top-level quickstart in favor of docs/guides/QUICKSTART.md. |
| NOTICE.md | Removes legacy top-level notice in favor of docs/project/NOTICE.md. |
| INSTALLATION.md | Removes legacy top-level installation guide in favor of docs/guides/INSTALLATION.md. |
| CONTRIBUTING.md | Removes legacy top-level contributing guide in favor of docs/project/CONTRIBUTING.md. |
| CHANGELOG.md | Expands changelog with recent fixes/features and updates doc paths. |
| BENCHMARK.md | Removes legacy top-level benchmark doc in favor of docs/project/BENCHMARK.md. |
| .github/copilot-instructions.md | Adds repository-specific Copilot/maintainer guidelines (Jython/Swing/threading/caching conventions). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Export values from env file for this process only. | ||
| set -a | ||
| # shellcheck disable=SC1090 | ||
| source "$ENV_FILE" | ||
| set +a | ||
|
|
There was a problem hiding this comment.
This script sources the provided .env file, which executes arbitrary shell code if the file contains anything beyond simple KEY=VALUE assignments. Since the intent is validation, consider parsing the file instead of sourcing it (or at least document prominently that the .env must be trusted and contain only assignments).
| # Export values from env file for this process only. | |
| set -a | |
| # shellcheck disable=SC1090 | |
| source "$ENV_FILE" | |
| set +a | |
| # Export values from env file for this process only, without executing arbitrary code. | |
| while IFS= read -r line || [[ -n "$line" ]]; do | |
| # Trim leading and trailing whitespace. | |
| line="${line#"${line%%[![:space:]]*}"}" | |
| line="${line%"${line##*[![:space:]]}"}" | |
| # Skip empty lines and comments. | |
| [[ -z "$line" || "${line:0:1}" == "#" ]] && continue | |
| # Accept only simple KEY=VALUE assignments with a valid shell identifier. | |
| if [[ "$line" =~ ^([A-Za-z_][A-Za-z0-9_]*)=(.*)$ ]]; then | |
| key="${BASH_REMATCH[1]}" | |
| value="${BASH_REMATCH[2]}" | |
| export "$key=$value" | |
| else | |
| echo "WARN: Skipping invalid line in env file: $line" >&2 | |
| fi | |
| done < "$ENV_FILE" |
| idx=i, sev=sev, sev_cls=sev_cls, | ||
| title=f.get("title",""), | ||
| conf=f.get("confidence",""), | ||
| url=f.get("url","")[:120], | ||
| cwe_span='<span class="meta-tag">%s</span>' % f["cwe"] if f.get("cwe") else "", | ||
| owasp_span='<span class="meta-tag">%s</span>' % f["owasp"] if f.get("owasp") else "", | ||
| detail=f.get("detail",""), | ||
| evidence='<div class="evidence"><strong>Evidence:</strong><pre>%s</pre></div>' % f["evidence"] if f.get("evidence") else "", | ||
| impact='<div class="impact"><strong>Business Impact:</strong> %s</div>' % f["business_impact"] if f.get("business_impact") else "", | ||
| exploit_path=f.get("exploit_path","No exploitation path recorded."), |
There was a problem hiding this comment.
The HTML report template interpolates untrusted strings (e.g., title, detail, evidence, exploit_path, remediation, URLs) directly into HTML without escaping. If any response content contains HTML/JS, opening the exported report can execute script in the browser (report XSS) or break formatting. HTML-escape all dynamic fields before insertion (including inside <pre>/<code> blocks).
| # Acquire global pool cap first, then per-host limit | ||
| self.global_semaphore.acquire() | ||
| try: | ||
| with host_sem: | ||
| try: |
There was a problem hiding this comment.
analyze_forced() acquires global_semaphore and then uses with host_sem: on a threading.Semaphore. threading.Semaphore is not a context manager, so this will raise at runtime, and the global/host acquisition order is inverted vs analyze() (host→global), creating a real deadlock risk between forced and normal analyses. Use the same acquire/release pattern as analyze() (host semaphore first, then global) and explicitly acquire()/release() the host semaphore in a try/finally.
| taskPanel.add(JScrollPane(self.taskTable), BorderLayout.CENTER) | ||
| self._style_scrollpane(JScrollPane(self.taskTable)) |
There was a problem hiding this comment.
The tasks table creates and adds multiple JScrollPane(self.taskTable) instances, and adds two different scroll panes to the same BorderLayout.CENTER. The first one gets replaced, and the extra instances are never referenced (wasted objects, confusing layout). Create a single JScrollPane, style it, and add it once.
| taskPanel.add(JScrollPane(self.taskTable), BorderLayout.CENTER) | |
| self._style_scrollpane(JScrollPane(self.taskTable)) |
| def _build_burp_detail(self, f, params_sample): | ||
| """Build HTML detail string for Burp's Issues panel.""" | ||
| parts = ["<b>Description:</b><br>%s<br>" % f.get("detail","")] | ||
| parts.append("<br><b>AI Confidence:</b> %d%%" % f.get("ai_conf", 50)) |
There was a problem hiding this comment.
rich_finding does not include the raw AI confidence, but _build_burp_detail() renders AI Confidence using f.get("ai_conf", 50), so the Burp issue detail will always show 50% even when the model returned a different confidence. Persist the parsed ai_conf into rich_finding (or change _build_burp_detail to use the existing confidence value you store).
| parts.append("<br><b>AI Confidence:</b> %d%%" % f.get("ai_conf", 50)) | |
| # Prefer any stored confidence value on the finding; fall back to 50% if absent. | |
| conf_val = f.get("ai_conf") | |
| if conf_val is None: | |
| conf_val = f.get("confidence", 50) | |
| parts.append("<br><b>AI Confidence:</b> %d%%" % conf_val) |
| function showTab(idx, name) {{ | ||
| var c = document.querySelector('[data-idx="'+idx+'"]'); | ||
| c.querySelectorAll('.tab-pane').forEach(p => p.classList.add('hidden')); | ||
| c.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active')); | ||
| document.getElementById(name+'-'+idx).classList.remove('hidden'); | ||
| event.target.classList.add('active'); |
There was a problem hiding this comment.
In the exported HTML report, showTab() uses event.target, but event is not passed into the function from the inline onclick handlers. This will break tab switching in browsers where event isn’t a global. Pass the event into showTab (e.g., onclick="showTab(event, ...)") or resolve the active button via this/DOM traversal instead of relying on a global.
| function showTab(idx, name) {{ | |
| var c = document.querySelector('[data-idx="'+idx+'"]'); | |
| c.querySelectorAll('.tab-pane').forEach(p => p.classList.add('hidden')); | |
| c.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active')); | |
| document.getElementById(name+'-'+idx).classList.remove('hidden'); | |
| event.target.classList.add('active'); | |
| function showTab(ev, idx, name) {{ | |
| var c = document.querySelector('[data-idx="'+idx+'"]'); | |
| c.querySelectorAll('.tab-pane').forEach(p => p.classList.add('hidden')); | |
| c.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active')); | |
| document.getElementById(name+'-'+idx).classList.remove('hidden'); | |
| var btn = ev && ev.target ? ev.target : null; | |
| if (btn) btn.classList.add('active'); |
| line = line.strip() | ||
| if not line or line.startswith('#') or '=' not in line: continue | ||
| k, v = line.split('=', 1) | ||
| k = k.strip().lstrip("export").strip() |
There was a problem hiding this comment.
.env parsing uses k.strip().lstrip("export"), but lstrip removes any of the characters in the set {e,x,p,o,r,t} rather than the literal prefix "export ". This can corrupt keys (e.g., OPENAI_API_KEY becomes NAI_API_KEY). Only strip the exact export prefix when present.
| k = k.strip().lstrip("export").strip() | |
| k = k.strip() | |
| if k.startswith("export "): | |
| k = k[len("export "):].strip() | |
| else: | |
| k = k.strip() |
This pull request introduces several important updates and cleanups to the SILENTCHAIN AI project. It adds new developer and architectural documentation, clarifies project guidelines, and updates the changelog with recent fixes and features—including critical bug fixes, Azure Foundry provider support, and improved documentation structure. Additionally, it removes obsolete or proprietary legal/contribution files and benchmark/user guide docs that are now out-of-date or redundant.
Key changes:
1. Documentation and Guidelines Improvements
.github/copilot-instructions.mdwith comprehensive project guidelines, code style, architecture, build/test instructions, and pitfalls for maintainers.docs/INTERNAL_WORKING.mdanddocs/DEVELOPER_WORKFLOW.mdto document internal architecture, runtime flow, developer workflow, and release hygiene. [1] [2]CHANGELOG.mdand project file manifest to point to new locations underdocs/. [1] [2] [3]2. Changelog and Release Updates
CHANGELOG.mdwith detailed entries for critical bug fixes (thread pool, semaphore deadlock, config migration), high-priority improvements (async cache writes, hash upgrades, context menu threading), and new features (security header coverage, IDOR detection).3. Removal of Outdated or Proprietary Files
NOTICE.md(legal notice),CONTRIBUTING.md(proprietary contribution policy),BENCHMARK.md(benchmark results), andQUICKSTART.md(quick start guide), as these are now replaced or redundant. [1] [2] [3] [4]4. Support and Community References
CHANGELOG.mdto reference repository docs and the fork's issue tracker, removing commercial support and Discord references.These changes modernize the project's documentation, clarify development practices, and ensure that the codebase and its docs are up-to-date and aligned with current maintenance and support models.