SESTRAV is a solo-maintained, academic research project developed at the University of Rhode Island. There is one active maintainer. Please keep this in mind when setting expectations around response timelines.
Only the latest major release of SESTRAV is actively supported with security updates.
| Version | Supported |
|---|---|
| 2.0.x | ✅ |
| < 2.0 | ❌ |
Please do NOT open a public GitHub Issue for security vulnerabilities. Public disclosure before a fix is available puts all users at risk.
Send a confidential report to the maintainer directly:
Email: gavinmborges1104@gmail.com
Please include the following in your report:
- Summary: A clear description of the vulnerability and its potential impact.
- Reproduction steps: Step-by-step instructions to reproduce the issue, including any sample inputs, scripts, or configuration needed.
- Environment: Python version, OS, relevant package versions.
- Proposed fix (optional): Any remediation ideas or patches you have.
GitHub's built-in private reporting is also available:
- Navigate to the SESTRAV Security tab.
- Click "Report a vulnerability".
- Fill in the advisory form - this is end-to-end encrypted between you and the maintainer.
As a solo-maintained project, the maintainer commits to:
- Acknowledge receipt of your report within 3-5 business days.
- Provide an initial assessment (severity, scope, reproducibility) within 10 business days of acknowledgement.
- Coordinate a fix and disclosure timeline with you collaboratively.
- Credit reporters in the release notes (unless you prefer anonymity).
Responsible disclosure helps keep SESTRAV and its users safe. Thank you for taking the time to report vulnerabilities privately.
SESTRAV is led by a single active maintainer; the v1 collaborators credited in
CONTRIBUTORS.md are no longer active. There is no backup maintainer and no
succession arrangement, and none is planned - GOVERNANCE.md and BUS_FACTOR.md
record that honest status rather than a continuity plan.
The project therefore cannot survive the loss of the maintainer as a maintained project. What it does have is weaker but real: the source, full history and build procedure are public and MIT-licensed, so a third party may fork and continue the work independently. If you are assessing whether a security report will be actioned in the maintainer's absence, assume it will not be.
All accounts with write access to this repository MUST have Two-Factor Authentication (2FA) enabled on GitHub. In practice that is one account, the sole maintainer's.
Release artifacts are distributed via GitHub Releases over HTTPS and ship with a
SHA-256 checksum manifest generated by src/release_bundle.py, which lets
consumers verify integrity:
sha256sum -c <manifest-file> # confirm the downloaded ZIP matches the manifestRelease authenticity (signing) is automated by
.github/workflows/release.yml: pushing a version
tag builds the distribution and produces a keyless SLSA build-provenance
attestation (Sigstore, via GitHub OIDC - no maintainer-managed keys). From the
release at which signing is introduced onward:
-
Tags are annotated but not yet signed (
version_tags_signed, an OpenSSF SUGGESTED criterion, is currently Unmet - seedocs/releasing.md). Once tag signing is introduced they will be verifiable withgit tag -v vX.Y.Z. -
Artifacts carry a Sigstore provenance attestation, verifiable with:
gh attestation verify sestrav-<version>-py3-none-any.whl --repo Gavin-Borges/SESTRAV
The full release procedure is documented in docs/releasing.md.
Maintainer note: artifact attestation is keyless, so there is no artifact-signing key to record. When tag signing is introduced, note the first signed version here and record the signing identity per
BUS_FACTOR.md.
SESTRAV is designed as a standalone, offline bioinformatics pipeline.
- Data Privacy by Design: All scoring and feature extraction processes execute strictly on the local machine or host environment. SESTRAV does not transmit, upload, or collect any sequence data, user parameters, or predictive outputs.
- No PII/PHI Requirement: The pipeline accepts standard FASTA, CSV, and YAML configurations. It does not require, accept, or process personally identifiable information (PII) or protected health information (PHI). Users are cautioned against introducing patient metadata or identifying fields into sequence inputs.
- Credential Safety: The pipeline does not connect to external patient databases and has no credential store or public telemetry APIs.
How findings from Dependabot, code scanning, and the CI security workflows are
prioritized and acted on. The policy is deliberately two-tiered, but "blocking"
here means one specific, verifiable thing: gating the merge button via the
Protect Main Branch ruleset (id 16846770) - its four required status checks
(test (3.13), Require human review, check_dco, Cited commits resolve) plus
its code-scanning rule, which names CodeQL only. A tool that is not on either of
those two lists cannot block a merge, even if it fails its own CI job red.
| Severity | Action | Target SLA | Gate |
|---|---|---|---|
| Critical | Patch or documented mitigation before the next merge to main |
48 hours | Blocking |
| High | Patch or mitigation within the current release cycle | 7 days | Blocking |
| Medium | Scheduled fix; risk-acceptable with written justification | 30 days | Advisory |
| Low | Best-effort; batched with routine dependency updates | Next cycle | Advisory |
Timelines follow the solo-maintainer cadence described under Response Commitment above. The Severity column states intent; the CI gate map below states what is mechanically enforced today, and the two are not yet the same for every row.
| Tool / workflow | What it checks | Tier |
|---|---|---|
Bandit (security.yml, -ll) |
Python SAST, MEDIUM+ severity | Advisory - fails its own CI job on a finding, but is not a required status check, so it does not gate the merge button |
Dependency Review (dependency-review.yml) |
New deps introduced in a PR (fail-on-severity: moderate) |
Advisory - fails its own CI job on a finding, but is not a required status check, so it does not gate the merge button |
CodeQL (security.yml) |
Deep SAST -> Security > Code scanning | Blocking - the ruleset's code-scanning rule names CodeQL |
Semgrep (security.yml) |
SAST ruleset p/python -> Security > Code scanning |
Advisory |
pip-audit (security.yml, weekly + PR) |
CVEs in the pinned requirements.lock -> run summary |
Advisory - fails closed (non-continue-on-error) on any lockfile advisory absent from environments/accepted_advisories.toml, but is not a required status check |
| Dependabot alerts | Known CVEs in dependencies -> Security > Dependabot | Advisory (triaged) |
Advisory findings never block a merge on their own - none of them is a required
status check or a code-scanning rule on Protect Main Branch. Three of them
(Bandit, Dependency Review, pip-audit) still turn their own CI job red on a
finding rather than merely reporting one; that failure is visible in the run and
in branch-status UI, but does not prevent the merge button from going green.
Findings surface as (a) tracked, dismissable alerts in Security > Code
scanning (Semgrep/CodeQL SARIF), (b) a red or markdown-annotated
security.yml job run (Bandit, Dependency Review, pip-audit), and (c)
Dependabot alerts/PRs. They are reviewed on the weekly cadence and logged in the
register below whenever consciously deferred.
When a finding is intentionally left unfixed (no upstream patch, not reachable in SESTRAV's offline model, etc.):
- Add an entry to the Risk-Acceptance Register below: identifier, component, rationale, and a re-review trigger or date.
- If it is noisy in CI, suppress it at the source with the verified advisory ID
and a pointer back to this register entry:
- For a
pip-auditfinding onenvironments/requirements.lock(the production lockfile), add an entry toenvironments/accepted_advisories.toml-.github/workflows/security.yml'spip-auditjob fails closed on any finding not listed there (tools/check_lockfile_advisories.py). Do not use pip-audit's--ignore-vulnflag for this: it is applied before pip-audit writes its own report, so a suppressed finding becomes invisible to every tool that reads that report, including the ones meant to notice when it gets fixed upstream. That gap is exactly how CVE-2025-3000 sat patched-but-unnoticed for four weeks; see the entry below. - For anything else (Semgrep/CodeQL SARIF, Dependabot), dismiss-with-reason in the Security tab, citing this register entry in the dismissal comment.
- Never suppress without a register entry.
- For a
- Note material changes in the
CHANGELOG.mdUnreleased / Securitysection as the audit trail.
As a standalone, offline scientific tool, SESTRAV occasionally relies on complex third-party libraries (e.g., PyTorch) that may contain upstream vulnerabilities with no available vendor patch. Each consciously-deferred advisory is logged here.
-
CVE-2025-3000 (PyTorch JIT script memory corruption): RESOLVED 2026-08-05 - no longer risk-accepted. PyTorch
<= 2.12.1contains a memory corruption flaw insidetorch.jit.script.- Identifiers:
CVE-2025-3000,GHSA-rrmf-rvhw-rf47,PYSEC-2025-194. - Resolution: upgraded to
torch==2.13.0, the first patched release (published 2026-07-08), acrossrequirements.in,requirements.txt,environments/requirements.lockandenvironments/requirements-ci-torch-cpu.txt, plus atorch>=2.13.0floor inpyproject.toml. The lockfiles only govern hash-pinned installs; thepyproject.tomlfloor is what stopspip install -e .or a downstream consumer from resolving back into the affected range (<= 2.12.1). - How this entry went stale, recorded deliberately: it asserted "No upstream patch
is available" and set a re-review trigger of "publication of a patched release." That
trigger fired on 2026-07-08 and went unnoticed for four weeks, because nothing
re-evaluates this register on a schedule - the suppression was set once and never
revisited. The advisory's own metadata (
firstPatchedVersion: 2.13.0) was the authoritative signal and was queryable the whole time. - Suppressions removed: the
--ignore-vuln PYSEC-2025-194/GHSA-rrmf-rvhw-rf47flags have been deleted from.github/workflows/security.yml, so pip-audit now reports this advisory again if it ever reappears. Any previously dismissed Dependabot alerts for it are superseded by the upgrade. - Side effect, intentional: torch 2.12.0 declared a
setuptools<82build-metadata cap that collided with this repo'ssetuptools>=83.0.0floor (GHSA-h35f-9h28-mq5c) and forced every lockfile recompile through auvoverride file. torch 2.13.0 declaressetuptools>=77.0.3, sooverrides.txthas been retired and both application lockfiles now resolve unaided. The setuptools floor itself is unchanged - it was the security constraint, not the workaround.
- Identifiers:
-
Standing lesson from the entry above: a risk acceptance with no scheduled re-review is a claim that decays silently. Every live entry in this register carries a re-review trigger; none of them fire on their own. (Writing this sentence exposed a counter-example: the
-W errorbypass below had no trigger at all. One was added rather than weakening the rule.) Re-check this register whenever dependencies are audited, and treat an advisory'sfirstPatchedVersionfield as the authoritative test of "is a patch available yet," not the prose in this file. -
Semgrep
dangerous-subprocess-use-tainted-env-args(external-tool wrappers): Risk-accepted false positive. The benchmark wrappers shell out to external binaries (PRIME, PredIG/Docker) viasubprocess.run.- Identifiers: Semgrep
python.lang.security.audit.dangerous-subprocess-use-tainted-env-args, BanditB603. - Scope:
scripts/run_prime_wrapper.py,scripts/run_predig_wrapper.py,scripts/run_predig_batched.py. - Severity: Error (Semgrep default); not exploitable in SESTRAV's model.
- Mitigation: All calls use the list/argv form (
shell=False), so no shell interpretation occurs. Command arguments are sourced from the operator's local CLI (argparse) and constant literals - never from untrusted or network input. - Suppression: An inline
# nosemgrepon all three call sites, and a CI step that makes GitHub honour it. Corrected 2026-08-17: this entry previously stated that an inline# nosemgrepdoes not clear the taint-mode finding, and that Security-tab dismissal was therefore the mechanism. The marker does clear it - the scanner's own verdict isRan 154 rules on 164 files: 0 findings.What did not happen was GitHub acting on it: semgrep still wrote each finding into the SARIF tagged"suppressions": [{"state": "accepted"}], and code scanning ingested it regardless, so the alerts were held closed only by manual dismissals that a single edit to the suppressed line could invalidate.security.ymlnow drops suppressed results before the SARIF upload, so the uploaded analysis matches the scan and no per-alert dismissal is required. Unsuppressed findings are untouched and still raise alerts. Seedocs/security_compliance.mdfor the measurement. - Re-review trigger: if any wrapper begins accepting subprocess arguments from
untrusted/remote input, or switches to
shell=True.
- Identifiers: Semgrep
-
MCP SDK transport vulnerabilities (session hijacking / origin validation): Risk-accepted. The
mcppackage is pulled in transitively as a dev/CI dependency ofsemgrep; it is not an application dependency and no MCP server transport is ever invoked by SESTRAV.- Identifiers:
GHSA-vj7q-gjh5-988w,GHSA-jpw9-pfvf-9f58,GHSA-hvrp-rf83-w775. - Scope:
mcp(transitive, viasemgrep) in the CI/dev dependency closure. - Severity: High (per GitHub advisory). All three are server-transport vulnerabilities (session-ID authentication bypass, WebSocket origin validation); SESTRAV never starts an MCP server, so the vulnerable code path is unreachable.
- Mitigation: Not used. SESTRAV imports
mcponly as a side effect of installingsemgrepfor CI static analysis; nomcp.server.*transport is constructed or run anywhere in the codebase or CI. - Suppression: Dependabot alerts dismissed as
not_used. This entry is the authoritative record; the dismissal comment on each alert points back here. - Re-review trigger: if
mcpever becomes a direct/runtime dependency, or an MCP server transport is added to the codebase.
- Identifiers:
-
Strict Warning Enforcement (
-W errorbypass) for PyTorch Ecosystem: Risk-accepted. OpenSSF Silver requires strict compiler/linter warnings to be enabled and addressed.- Scope:
pytesttest collection and runtime. - Rationale: Deep dependencies within
torch_geometricraise unpatchableDeprecationWarnings during import (e.g.,torch_geometric.distributeddeprecation since 2.7.0). Enforcing-W errorglobally breaks the CI pipeline. - Mitigation: We enforce strict warnings exclusively through our linting pipeline (Ruff) which is set to fail on any warning or error, satisfying the Silver criteria for static analysis, while allowing runtime PyTorch deprecation warnings to pass in test execution.
- Re-review trigger: any
torchortorch-geometricmajor/minor upgrade (which may drop the import-timeDeprecationWarnings this bypass exists for), or any narrowing of the pytest warning filter. Added 2026-08-05: this entry previously carried no trigger, which the standing lesson above says is exactly how a risk acceptance decays silently.
- Scope: