diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..a5a5203 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,35 @@ +version: 2 +updates: + # Dev dependencies — Playwright, Vite, http-server, esbuild. + # No runtime npm deps ship to users, so these are dev-tool hygiene only. + - package-ecosystem: npm + directory: / + schedule: + interval: weekly + day: monday + time: "08:00" + open-pull-requests-limit: 5 + labels: + - dependencies + groups: + dev-minor-and-patch: + dependency-type: development + update-types: + - minor + - patch + + # GitHub Actions used by our workflows (checkout, setup-node, codeql, scorecard, ...). + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + day: monday + time: "08:00" + labels: + - dependencies + - github-actions + groups: + actions-minor-and-patch: + update-types: + - minor + - patch diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..0d213ea --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,48 @@ +name: CodeQL + +on: + push: + branches: [main, dev] + pull_request: + branches: [main, dev] + schedule: + # Weekly Mondays at 06:00 UTC — independent of push activity so the + # badge stays current even when the repo is quiet. + - cron: '0 6 * * 1' + +jobs: + analyze: + name: Analyze (javascript-typescript) + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + security-events: write + contents: read + actions: read + + strategy: + fail-fast: false + matrix: + language: [javascript-typescript] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + queries: security-and-quality + # Saxon-JS is a vendored third-party engine — out of scope for findings on our code. + # tests/ is Playwright harness code, not shipped to users. + config: | + paths-ignore: + - lib/SaxonJS2.js + - tests/** + - dist/** + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 0000000..aeab6b1 --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,50 @@ +name: OpenSSF Scorecard + +on: + push: + branches: [main] + schedule: + # Weekly Mondays at 07:00 UTC — staggered from CodeQL so they don't compete for runners. + - cron: '0 7 * * 1' + workflow_dispatch: + +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + # Upload SARIF to the Security tab. + security-events: write + # Sign the results for the public Scorecard API. + id-token: write + contents: read + actions: read + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Run analysis + uses: ossf/scorecard-action@v2.4.0 + with: + results_file: results.sarif + results_format: sarif + # publish_results: true serves the badge from api.scorecard.dev. + publish_results: true + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + - name: Upload to code-scanning + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: results.sarif diff --git a/README.md b/README.md index 19c1325..d6ca595 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # XSLTDebugX — SAP Cloud Integration XSLT IDE -![XSLT 3.0](https://img.shields.io/badge/XSLT-3.0-blue?logo=w3c) ![XPath 3.1](https://img.shields.io/badge/XPath-3.1-blue) ![Saxon-JS](https://img.shields.io/badge/Saxon--JS-2.x-green) [![License](https://img.shields.io/badge/license-AGPL%203.0-blue)](LICENSE) [![CI](https://github.com/linusdevx/XSLTDebugX/actions/workflows/e2e-tests.yml/badge.svg)](https://github.com/linusdevx/XSLTDebugX/actions/workflows/e2e-tests.yml) ![Built with Vite](https://img.shields.io/badge/built%20with-vite-646cff?logo=vite&logoColor=white) ![Deployed on Cloudflare Pages](https://img.shields.io/badge/deployed%20on-Cloudflare%20Pages-f38020?logo=cloudflare&logoColor=white) ![Zero Dependencies](https://img.shields.io/badge/dependencies-0-brightgreen) +![XSLT 3.0](https://img.shields.io/badge/XSLT-3.0-blue?logo=w3c) ![XPath 3.1](https://img.shields.io/badge/XPath-3.1-blue) ![Saxon-JS](https://img.shields.io/badge/Saxon--JS-2.x-green) [![License](https://img.shields.io/badge/license-AGPL%203.0-blue)](LICENSE) [![CI](https://github.com/linusdevx/XSLTDebugX/actions/workflows/e2e-tests.yml/badge.svg)](https://github.com/linusdevx/XSLTDebugX/actions/workflows/e2e-tests.yml) [![CodeQL](https://github.com/linusdevx/XSLTDebugX/actions/workflows/codeql.yml/badge.svg)](https://github.com/linusdevx/XSLTDebugX/actions/workflows/codeql.yml) [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/linusdevx/XSLTDebugX/badge)](https://scorecard.dev/viewer/?uri=github.com/linusdevx/XSLTDebugX) [![Dependabot](https://img.shields.io/badge/Dependabot-enabled-025e8c?logo=dependabot&logoColor=white)](.github/dependabot.yml) ![Built with Vite](https://img.shields.io/badge/built%20with-vite-646cff?logo=vite&logoColor=white) ![Deployed on Cloudflare Pages](https://img.shields.io/badge/deployed%20on-Cloudflare%20Pages-f38020?logo=cloudflare&logoColor=white) ![Zero Dependencies](https://img.shields.io/badge/dependencies-0-brightgreen) [![No Telemetry](https://img.shields.io/badge/telemetry-none-brightgreen)](SECURITY.md) > A browser-based XSLT 3.0 IDE and XPath evaluator built specifically for SAP Cloud Integration (CPI) developers. Test and debug XSLT mappings and XPath expressions locally — with full CPI runtime simulation — before ever deploying to your tenant. @@ -209,11 +209,21 @@ Hosted on **Cloudflare Pages**, auto-deploys from `main`. CI (GitHub Actions) ru --- +## Security + +- **No backend, no telemetry** — the app is static HTML + JS. Your XML, XSLT, headers, properties, and XPath expressions never leave your browser. The deployed site uses anonymous, cookie-less GoatCounter pageview pings only. +- **Zero runtime npm dependencies** — Monaco / Lucide / pako load from CDN at pinned versions; Saxon-JS is bundled locally. Dev tools (Playwright, Vite, http-server) never ship. +- **Continuous scanning** — every push and PR is analysed by [CodeQL](https://github.com/linusdevx/XSLTDebugX/actions/workflows/codeql.yml) (`security-and-quality` query suite); [OpenSSF Scorecard](https://scorecard.dev/viewer/?uri=github.com/linusdevx/XSLTDebugX) scores repo practices weekly; Dependabot tracks dev-deps and GitHub Actions. +- **Auditable** — full source under AGPL-3.0; the deployed bundle is reproducible from this repo via `npm run build`. +- **Reporting** — see [SECURITY.md](SECURITY.md) for the policy, or open a private [GitHub Security Advisory](https://github.com/linusdevx/XSLTDebugX/security/advisories/new). + +--- + ## Support - **Bugs and feature requests** — [GitHub Issues](https://github.com/linusdevx/XSLTDebugX/issues) - **Questions** — start by checking the [FAQ](#faq) or [.github/docs/DEVELOPMENT.md](.github/docs/DEVELOPMENT.md) -- **Security** — for sensitive reports, please use [GitHub Security Advisories](https://github.com/linusdevx/XSLTDebugX/security/advisories) instead of public issues +- **Security** — see [Security](#security) above or [SECURITY.md](SECURITY.md) for the full policy --- diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..50d3fac --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,67 @@ +# Security Policy + +## Supported versions + +Only the latest revision on `main`, as deployed to **[xsltdebugx.pages.dev](https://xsltdebugx.pages.dev)**, is supported. Older commits are not patched. + +## Reporting a vulnerability + +Please use **[GitHub Security Advisories](https://github.com/linusdevx/XSLTDebugX/security/advisories/new)** for any sensitive report. Do **not** open a public issue for security problems. + +- **Acknowledgement target:** within 7 days of report. +- **Fix target:** depends on severity — critical issues are prioritised over feature work. +- Public disclosure is coordinated with the reporter after a fix is released. + +For non-sensitive bugs (broken UI, wrong output, etc.), use the regular [issue tracker](https://github.com/linusdevx/XSLTDebugX/issues). + +## Security posture + +XSLTDebugX is a **purely client-side** application. Knowing how it's built is the simplest way to evaluate whether it's safe for your environment. + +### No backend, no telemetry + +- There is **no server-side component**. The app is static HTML + JS served from Cloudflare Pages. +- The app does not send your XML, XSLT, headers, properties, or XPath expressions anywhere. Everything stays in your browser tab. +- The only data leaving your browser is what *you* trigger: clicking **Share** encodes the current state into a URL fragment (`#...`) that you copy and send yourself; URL fragments are never sent to the server. +- The deployed site uses **[GoatCounter](https://www.goatcounter.com/)** for anonymous, aggregate pageview counts. It does not set cookies, does not fingerprint visitors, and does not see editor content. Self-hosters can remove the GoatCounter `