Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SemgrepRules

Semgrep ruleset for C++ market-data / FIX feed handlers.

The rules encode 15 Cycode SAST findings as reusable static-analysis patterns so the same classes of defect are caught in CI rather than in the next scan cycle. They cover three themes: unchecked lengths on the wire-decode path, missing TLS peer and hostname verification, and unsynchronised ring-buffer state.

Layout

One rule per file, 17 files at the repository root. The filename prefix is the Cycode severity tier and the finding number, so files sort into tier order and any single rule can be enabled, pinned, or disabled on its own.

Prefix Files Findings Semgrep severity Remediation window
critical- 5 1-4 ERROR Before next deployment
high- 9 5-12 WARNING Within current sprint
medium- 3 13-15 INFO Medium-term

All rules are languages: [cpp] and match .cpp, .cc, .cxx, .h, .hpp, and .hxx. Findings 3 and 5 each have two rules (03/03b and 05/05b) because they need distinct patterns for the call site and the definition, which is why 15 findings produce 17 rules. Each file opens with a three-line header naming the finding, both severities, and the command to run that rule alone.

Usage

Run every rule by pointing at the directory:

semgrep scan --config path/to/SemgrepRules/ path/to/src

Run one rule:

semgrep scan --config critical-01-venue-code-overflow.yaml path/to/src

Run one tier. Semgrep takes --config once per file rather than a glob, so expand the prefix in the shell:

semgrep scan $(printf -- '--config %s ' critical-*.yaml) path/to/src

Block a build on the critical tier while leaving the rest advisory:

semgrep scan $(printf -- '--config %s ' critical-*.yaml) --error path/to/src
semgrep scan $(printf -- '--config %s ' high-*.yaml medium-*.yaml) path/to/src

Consume a rule straight from GitHub without cloning:

semgrep scan --config https://raw.githubusercontent.com/dmancloud/SemgrepRules/main/critical-01-venue-code-overflow.yaml path/to/src

Rules

Rule IDs keep the cycode-NN- naming independently of the filename, so existing baselines, nosemgrep comments, and triage history stay valid.

Critical

File Rule ID Finding What it catches
critical-01-venue-code-overflow.yaml cycode-01 1 Unchecked wire length from readRaw<> passed to readBytesRaw() in pullVenueCode
critical-02-instr-code-overflow.yaml cycode-02 2 Unclamped codeWidth in assignCode, memcpy() into a fixed-size struct field
critical-03-tls-permissive-verify-cb.yaml cycode-03 3 SSL_CTX_set_verify() installed with a permissive verify callback
critical-03b-tls-verify-cb-returns-1.yaml cycode-03b 3 Verify callback that ignores preverify_ok and is hardcoded to return 1
critical-04-tls-verify-none.yaml cycode-04 4 TLS peer verification disabled via SSL_VERIFY_NONE

High

File Rule ID Finding What it catches
high-05-readraw-callsites.yaml cycode-05 5 Every readRaw<T>() call site (audit rule, see below)
high-05b-readraw-no-bounds-check.yaml cycode-05b 5 readRaw<T>() definition with no bounds check against length_
high-06-sbe-header-null-deref.yaml cycode-06 6 decodeSbeHeader() missing null and minimum-length checks
high-07-ring-non-atomic-pos.yaml cycode-07 7 Ring-buffer positions declared as plain size_t instead of std::atomic
high-08-tls-no-hostname-check.yaml cycode-08 8 SSL_connect() without SSL_set1_host() or SNI, so the hostname is never checked
high-09-ssl-ctx-no-verify.yaml cycode-09 9 SSL_CTX factory that never sets verification or loads a trust store
high-10-framelen-not-validated.yaml cycode-10 10 SBE payload offsets used without validating frameLen
high-11-cursor-memcpy-oob.yaml cycode-11 11 Successive cursor memcpy() reads with no cumulative bounds guard
high-12-readbytesraw-struct-oob.yaml cycode-12 12 readBytesRaw(&struct, sizeof(T)) without a remaining() check

Medium

File Rule ID Finding What it catches
medium-13-ring-push-toctou.yaml cycode-13 13 Ring::push TOCTOU in the gap between the atomic load and store
medium-14-buffer-ctor-null.yaml cycode-14 14 ByteBuffer constructor that stores the data pointer without a null check
medium-15-tls-min-version.yaml cycode-15 15 SSL_CTX created without SSL_CTX_set_min_proto_version()

Each rule carries metadata with the originating cycode-finding number, CWE identifiers, OWASP Top 10 mapping where one applies, and confidence / likelihood / impact ratings, so results can be routed by CWE or filtered by confidence in a pipeline.

Tuning

The ruleset is deliberately strict and low-noise. Patterns are tied to the specific APIs and identifiers named in the findings (readRaw, readBytesRaw, decodeSbeHeader, SSL_CTX_set_verify, and so on), which means they will not fire on unrelated code and will correspondingly miss renamed variants. If your codebase uses different names, widen the relevant pattern or metavariable-regex rather than loosening the guard clauses.

Two rules need particular attention:

  • cycode-05 is an audit rule and flags every readRaw<T>() call site by design, since the finding calls for auditing roughly 15 of them. Once the bounds check is added inside readRaw() (cycode-05b), drop high-05-readraw-callsites.yaml from the config list.
  • cycode-14 enumerates constructor initialiser-list shapes with zero to four initialisers, because Semgrep's C++ parser rejects ... inside an initialiser list. Add another pattern-either branch if a buffer class initialises more than four members.

Validation

Every rule was validated against synthetic vulnerable and remediated C++ fixtures: it fires on the vulnerable form and stays silent on the remediated form of the same code. The split into one file per rule was a repackaging only, and the rule bodies are unchanged from the validated versions.

About

Semgrep rules for C++ market-data / FIX feed handlers

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors