Report a vulnerability privately, not in a public issue or pull request: open a private report. Only the maintainer sees it. Include the release you used, the code or workbook that shows the problem, and what you expected to happen, with credentials and private data removed.
A confirmed vulnerability is fixed in a release on the GitHub releases page, and the advisory is published with it, crediting you unless you ask otherwise.
Only the latest release on the GitHub releases page receives security fixes. Older releases are not maintained separately; update when a fix ships.
The runtime is src/ROneCOne.cls, one VBA class that runs inside Excel
with the rights of the person who opens the workbook. The demo workbooks
in demo/ embed it. A vulnerability here is the runtime reaching
something your code did not ask it to, or doing more with what you pass
it than its documentation says.
ROneCOne.cls runs only when your code calls it. It has no
Workbook_Open, Auto_Open, or event handler that Excel starts on its
own, and it reaches the machine only through the members your code uses:
| Reach | Only through |
|---|---|
| Network | HttpClient over WinHTTP for the URLs you request, and Xml.Load if you pass it a URL |
| Processes | Process.RunAsync, which runs your command line through cmd.exe and captures its output in temporary files that it deletes, and Process.StartSession, which keeps cmd.exe running and talks to it over pipes |
| Files | File, Directory, Path, Csv, ZipFile, Logger, FileWatcher, Xml.Load, and HttpClient.DownloadFileAsync, on paths you pass |
| Databases | DbConnection and the other ADO members, with the connection string you supply |
| Native code | Declare PtrSafe calls into kernel32, oleaut32, ole32, and bcrypt |
It sends no telemetry, never reads or writes the registry, never uses the
VBIDE at run time, and never starts a second Excel. The demo workbooks go
further only because their demos do: the HTTP demo downloads from
https://pokeapi.co, the Process demo runs commands through cmd.exe,
the Zip demo runs PowerShell's Compress-Archive and Expand-Archive,
and several demos write scratch files beside the workbook and delete them.
Three workflows check every pull request and every push to main, and
their gates decide whether a change can merge: CI passed,
Security passed and Malware scan passed. A gate passes only when
every job before it did, and any unexpected finding fails it, whatever its
severity. Security and Malware scan also run daily at 19:17 UTC.
- Code: olevba and mraptor (MacroRaptor), both from oletools, scan
ROneCOne.clsand every demo workbook.tools/security_scan.pycompares each file's olevba findings and mraptor flags with the reviewed baseline and fails on any change in either direction, on any code that runs on its own, such as aWorkbook_Openhandler, and on any P-code its source does not explain. olevba's own VBA stomping flag is replaced by that last check, which sets aside the trailing type character pcodedmp prints on some names (payload$) and fails on any other P-code name or string the source lacks. The results are in the job's log, not in code scanning. CI also runs pyVBAanalysis over the sources and every demo workbook. - Workflows: zizmor audits the GitHub Actions workflows; a finding fails Security.
- Dependencies: there is nothing to audit. The runtime has no dependencies, and the Python tools the workflows run come from hash-locked files (see Pinning and updates).
- Malware: ClamAV, with signatures freshclam fetches and verifies on
every run, and YARA-X, with the YARA Forge rules pinned to a release and
its SHA-256, scan the shipped
src/ROneCOne.clsand everydemo/*.xlsm. YARA-X scans each workbook as a file and also scans its decompressed ZIP members, includingxl/vbaProject.bin; ClamAV handles its own archive inspection. A new detection fails Malware scan, and so does a scanner, signature update, rule download, compilation, or workbook read error. A match from a public collection can be heuristic: it warrants review, not an automatic malware verdict. - OpenSSF Scorecard rates the repository's security practices on every
change to
mainand weekly, and the README badge shows the result. Some of its checks do not fit this project. A single maintainer cannot have a second person approve every change. Fuzzing does not apply: ROneCOne is VBA, which runs only inside Office. Signed-Releases rises as releases carry the provenance bundle; it counts the last five.
A finding is fixed, or accepted with a written reason in
tools/security_baseline.json (olevba and mraptor) or
tools/malware_exceptions.json (ClamAV and YARA-X).
The baseline records each shipped file's olevba findings and mraptor flags by file name, not by the file's content. A new finding is accepted only by reviewing it and updating the baseline in the same change, and a recorded finding that no longer appears fails the scan too. The baseline never records code that runs on its own or P-code its source does not explain.
A malware exception names the scanner, path, detection, the shipped
file's sha256, and a specific reason. For a workbook member, path
has the form demo/Name.xlsm!xl/vbaProject.bin, and its hash is the whole
workbook's hash. An exception applies only to that detection in those
exact bytes, so a changed file needs another review, and an exception that
no longer matches fails the scan. A failed signature download or scanner
error is never bypassed with an exception.
zizmor keeps its exceptions in .github/zizmor.yml or inline beside the
line they excuse, each with its reason. There are none: the repository has
no .github/zizmor.yml and no inline exceptions.
The baseline holds these results, by design:
- Suspicious keywords such as
Shell,Lib,CreateObject,Kill, andSaveToFilename the capabilities in the table under Scope. - IOCs are the libraries and programs those capabilities use:
bcrypt.dll,oleaut32.dll, andcmd.exe. - Hex and Base64 strings are ordinary words and numbers in the code,
such as
SHA1and2147483647, that happen to decode. - VBA stomping is flagged on the demo workbooks because pcodedmp
prints eight names with a trailing type character, such as
payload$, that the source never spells. Every name without its suffix is in the source. - mraptor's W and X flags mark code that writes files or memory, such
as
SaveToFileandKill, and code that runs something outside VBA, such asCreateObject,Shell, and theDeclarestatements. Every file is-WX. mraptor calls a file suspicious only when its A flag, for code that runs on its own, joins W or X, and no file sets A, so every verdict is Macro OK.
The malware exception list is empty. The 1.10.2 demo workbooks matched
YARA Forge rule ARKBIRD_SOLG_TA505_Maldoc_21Nov_2 on four ordinary
Office/VBA library reference strings; its sample-specific paths and long
payload strings did not match. Repackaging the 1.10.3 workbooks removed
the match. ClamAV found no infections in the repackaged files when scanned
with engine 1.5.4 on 2026-09-29.
A rule that matches VBA's ReDim or ReDim Preserve is matching expected
code: SessionAppendBytes doubles a byte buffer's capacity before
appending data, and the CSV parser grows its field and quote-state arrays
when a row has more than eight fields. Such a match still needs its full
condition and the surrounding code reviewed before any exception is added.
Everything the workflows run is pinned: actions to full commit SHAs,
runners to named OS releases, the ClamAV image to a digest, Python tools
(oletools, YARA-X, zizmor, pyVBAanalysis) to hash-locked lock files in
.github/requirements/, the local development tools to the hash-locked
requirements-dev.txt, and the YARA Forge rules to a release and its
SHA-256 in .github/security/yara.json. ClamAV's signatures change too
often to pin, so freshclam fetches and verifies them on every run.
Dependabot proposes updates to GitHub Actions, the Python lock files
(.github/requirements/ and requirements-dev.txt) and the ClamAV image
once a version is a week old (the owner's own packages, such as
pyVBAanalysis, at once), and at once for a security advisory. The Update
YARA rules workflow proposes new YARA pins each week. A minor or patch
update, and the YARA pull request, merges itself once CI, Security and
Malware scan pass; a third-party major version waits for review.
Pushing a vX.Y.Z tag runs the Publish workflow. It refuses a tag that
is not the version in src/ROneCOne.cls's release header, and fails if
restamping the release headers would change a committed module. It writes
ROneCOne.cls from the tagged commit, with the CRLF line endings the
Visual Basic Editor imports, runs Security and Malware scan on that commit,
scans the built file with olevba and mraptor, and only when all of that
passes signs the build provenance and creates the GitHub release with:
ROneCOne.cls: the runtime.vX.Y.Z-sha256.txt: its SHA-256.ROneCOne-X.Y.Z.sigstore.json: the signed build provenance of both.vX.Y.Z-security-report.md: what olevba and mraptor find inROneCOne.cls, its hash, and whether the results match the reviewed baseline at the tag. Releases from 1.10.2 on carry it.
Releases no longer attach the demo workbooks. They are in the repository's
demo/ folder, and every change to them is scanned as described above.
Releases up to 1.10.3 were built locally, carry no provenance, and also
attach the demo workbooks.
Started by hand, Publish is a dry run: it builds, scans and assembles the same files and keeps them as a workflow artifact instead of releasing anything.
To check that a file was built by this repository's Publish workflow from a tagged commit:
gh attestation verify ROneCOne.cls --repo WilliamSmithEdward/ROneCOneWithout the GitHub CLI, compare a download's SHA-256 with
vX.Y.Z-sha256.txt or the security report:
Get-FileHash .\ROneCOne.cls -Algorithm SHA256mainaccepts changes only through a pull request that passes CI passed, Security passed and Malware scan passed. The ruleset has no bypass, for the owner either, and refuses force-pushes and deleting the branch.- A
v*release tag cannot be moved or deleted once pushed, except by a repository admin. - A workflow that uses an action not pinned to a full commit SHA fails to run. Workflow tokens are read-only unless a job is granted more for itself.
- Secret scanning with push protection, Dependabot alerts and security updates, and private vulnerability reporting are on.