TILLFORGE · CODE SCANNING

Find the flaw in the line that ships it.

GA

Every pushed commit’s source is checked for the mistakes that turn into incidents: input reaching a shell, a query or a file path; TLS and token checks switched off; unsafe deserialisation; broken ciphers; credentials in plain app storage; cleartext traffic; WebViews opened up. It covers server, web and mobile code, runs on TillDev’s own git servers, and your code never goes to a third-party scanner.

01When

What gets scanned, and when

Unless the workspace policy is off, every branch push, every green CI build and every release is scanned, and anyone with read access can start one by hand (30 an hour per workspace). After the first scan of a repository, a scan reads only the files changed since the last one and carries the rest. Each commit gets a tilldev/sast check, which a branch rule can require like any other.

JavaScript and TypeScript, Python, Go, Java, Kotlin, Swift and Dart are read, along with Android manifests and network security config, and iOS Info.plist. Comments are ignored, and so is text inside string literals. Tests, vendored and generated code, minified bundles and files over 1 MiB are skipped. A scan that passes a size limit is marked partial, so a clean result is never claimed for code that wasn’t read.

bash
# Scan the default branch head and list what was found.
tilldev forge sast acme-api

# A branch or tag; wait for the result. Exits 1 when a finding blocks, 2 while not scanned.
tilldev forge sast acme-api --ref feature/login --wait

# In CI: fail on anything high or worse, whatever the workspace policy says.
tilldev forge sast acme-api --commit "$GIT_COMMIT" --fail-at high --wait

# Every active finding across the default branches you can read.
tilldev forge sast findings --severity high
02Policy

Warn, or block merges

ModeWhat it does
warn (default)Every commit is scanned; the check passes and lists what was found.
blockThe check fails, and merges into protected branches are refused, while a finding at the bar or above is active (high by default; critical or medium also possible). A merge waits while its head commit is being scanned.
offScans run only when someone asks for one.

Owners and admins set the policy in TillForge → Code scanning, with the CLI or through the API. A change re-grades recent commits and re-posts their checks.

bash
# Owners and admins.
tilldev forge sast policy --mode block --block-at high
tilldev forge sast accept acme-api <scan-id> <finding-id> --reason "the id is parsed as an integer first"
tilldev forge sast exceptions acme-api
tilldev forge sast withdraw acme-api <exception-id>
03Decisions

Accepting a finding

When a finding is safe where it stands, an owner or admin accepts it with a reason from the repository’s Findings tab or with forge sast accept. The acceptance follows the rule, the file and the text of the line, so it survives edits elsewhere and lapses the moment that line changes. Withdrawing one makes the finding count again. Every decision is in the audit log.

To keep the reason next to the code, put an allow comment on the line or the line above:

typescript
// tillforge:allow-code sql-injection table name comes from a fixed list
db.query("select count(*) from " + TABLES[kind])
An allow comment is a code change
It lands like any other line, so branch protection and review apply to it. Findings accepted this way are shown as accepted, with the comment’s reason, never hidden.
04Rules

The 15 rules

Each rule names its CWE and its OWASP Top 10 and MASVS categories, so findings line up with the frameworks your auditors use. tilldev forge sast rules prints the same list.

RuleSeverityMaps toReads
Shell command built from a variable
command-injection
criticalCWE-78 · A05 · MASVS-CODE-4JS/TS, Python, Go, Java, Kotlin
Code evaluated from a variable
code-eval
highCWE-95 · A05 · MASVS-CODE-4JS/TS, Python
SQL built from a variable
sql-injection
highCWE-89 · A05 · MASVS-CODE-4JS/TS, Python, Go, Java, Kotlin, Dart, Swift
TLS certificate checks turned off
tls-verification-disabled
highCWE-295 · A04 · MASVS-NETWORK-1JS/TS, Python, Go, Java, Kotlin, Dart, Swift
Token signature or expiry not checked
jwt-verification-disabled
highCWE-347 · A07 · MASVS-AUTH-1JS/TS, Python, Go, Java, Kotlin
File path taken from the request
path-traversal
highCWE-22 · A01JS/TS, Python, Go
Server fetches a URL from the request
ssrf
highCWE-918 · A01JS/TS, Python, Go
Redirect target taken from the request
open-redirect
mediumCWE-601 · A01JS/TS, Python, Go
Untrusted data deserialised into objects
unsafe-deserialization
highCWE-502 · A08 · MASVS-CODE-4Python, JS/TS, Java, Kotlin
Broken or ECB-mode cipher
weak-cipher
highCWE-327 · A04 · MASVS-CRYPTO-1JS/TS, Java, Kotlin, Go, Python, Swift, Dart
Predictable random value used for a secret
insecure-randomness
mediumCWE-338 · A04 · MASVS-CRYPTO-1JS/TS, Python, Go, Java, Kotlin, Dart, Swift
Credential kept in plain app storage
token-plain-storage
mediumCWE-922 · A04 · MASVS-STORAGE-1JS/TS, Dart, Java, Kotlin, Swift
Cleartext HTTP allowed
cleartext-traffic
mediumCWE-319 · A04 · MASVS-NETWORK-1Android XML, iOS plist
WebView bridge, file access or debugging opened up
webview-unsafe
mediumCWE-749 · A02 · MASVS-PLATFORM-2Java, Kotlin, JS/TS, Dart, Swift, Android XML
HTML written from a variable
html-injection
mediumCWE-79 · A05 · MASVS-PLATFORM-2JS/TS, Python, Dart
What pattern rules can't see
These rules read one file at a time and look for a risky call fed by a variable or by request input. They don’t follow data across files, so they can miss a flaw whose input arrives from elsewhere, and they can flag a call whose input is already safe. Treat a clean scan as one layer, alongside review, secret scanning and dependency checks.

Next: Branch protection to require the tilldev/sast check, or the security model. Back to the TillForge overview.