SAST languages
Agentic SAST in Workbench hunts across the languages present in the cloned repository. Class hunters and language-aware research agents share one worker cap (maximum eight).
Research agents may only list, search, and read the pinned clone. Shell, network, package audit, third-party scanners, and write tools are unavailable. Each language family below is the same matrix the agents receive: typical files, frameworks, attacker-controlled sources, and sensitive sinks.
Start a run from Source analysis in Workbench with a credential-free HTTPS repository URL.

Language families
| Family | Typical files | Frameworks | Typical sources | Typical sinks |
|---|---|---|---|---|
| Go | .go | net/http, chi, gin, echo, fiber, gorilla, gRPC, sqlc, ent, buffalo | request fields, router params, gRPC metadata, env, flags, queue payloads, deserialized JSON | database/sql, sqlx, GORM raw, os/exec, templates, http.Client, file I/O, path joins, gob/yaml/interface{} JSON |
| JVM | .java, .kt, .kts, .scala, .groovy, .clj, .jsp, Gradle/Maven, Jenkinsfile | Spring, WebFlux, Jakarta EE, Micronaut, Quarkus, Play, Struts, Hibernate, MyBatis | HttpServletRequest, @RequestParam / @PathVariable, Kafka/JMS, ObjectInputStream cousins | JDBC/JdbcTemplate, Runtime.exec, ObjectInputStream, XMLDecoder, SnakeYAML, ScriptEngine, SpEL, OGNL, JNDI, Freemarker/Velocity |
| JavaScript / TypeScript | .js, .mjs, .cjs, .ts, .mts, .cts, .jsx, .tsx, Vue, Svelte, Astro, MDX, CoffeeScript | Express, Fastify, Koa, Nest, Next.js, Nuxt, Remix, SvelteKit, Angular, React Router, Hono | req.body / query / params / headers, URLSearchParams, postMessage, location.hash, cookies, GraphQL variables, Next.js searchParams | eval / Function, child_process, innerHTML, ORM raw SQL, res.redirect, user-controlled fetch, vm, YAML load, dangerouslySetInnerHTML |
| Python | .py, .pyi, .pyw, python shebangs | Django, Flask, FastAPI, Tornado, Celery, Starlette, Pyramid, SQLAlchemy, Pandas | request.args / form / json, Django GET/POST, FastAPI Depends, Celery args, pickle, YAML | cursor.execute, subprocess, os.system, eval/exec, pickle.loads, yaml.load, Jinja2, send_file, user-controlled HTTP, tarfile.extract |
| PHP | .php, .phtml, .inc, Drupal .module / .theme | Laravel, Symfony, WordPress, Magento, Yii, CodeIgniter, Drupal | $_GET / $_POST / $_REQUEST / $_COOKIE / $_FILES / $_SERVER, php://input, Laravel request() | mysqli_query, PDO exec, unserialize, eval, include/require, system/exec, file_get_contents, curl_exec, preg_replace /e, extract |
| Ruby | .rb, .erb, .rake, Haml, Slim, Gemfile, Rackup | Rails, Sinatra, Hanami, Rack, Sidekiq | params, cookies, request.env, Sidekiq jobs, YAML, Marshal | ActiveRecord.execute, system/exec/backticks, eval, Marshal.load, YAML.load, inline render, send_file, constantize |
| .NET | C#, F#, VB.NET, Razor, .aspx, ASHX/ASMX | ASP.NET Core, MVC, Web API, Blazor, WCF, Entity Framework, Nancy | HttpRequest, [FromBody] / [FromQuery], SignalR, gRPC, BinaryFormatter cousins, ViewState | SqlCommand, Process.Start, BinaryFormatter, Newtonsoft TypeNameHandling, XSLT, file writes, HttpClient, Assembly.Load, LDAP paths |
| C / C++ / Objective-C | .c, .cpp, .h, .m, .mm, CUDA | POSIX daemons, CGI, Qt, JNI bridges, Apache modules, CUDA | argv, getenv, recv, fread, CGI query, JNI, protobuf parse, CUDA buffers | strcpy/sprintf/gets, system/popen, unbounded memcpy, format-string printf, mmap, execve, SQL concat, XML entity parsers |
| Rust | .rs | actix-web, axum, rocket, warp, tonic, diesel, sqlx | actix/axum extractors, clap args, serde JSON, env | Command::new, std::fs, sqlx/diesel raw, unsafe / transmute, user-controlled reqwest, shell-bound format_args |
| Swift | .swift | Vapor, Kitura, Perfect, UIKit/SwiftUI backends | URL query, JSONDecoder, UserDefaults, deep links, IPC | Process / NSTask, sqlite3, FileManager, WKWebView loadHTMLString, keychain writes, user-controlled URLSession |
| Mobile | Dart / Flutter, Godot, QML, AIDL, Smali, AndroidManifest.xml, Info.plist | Flutter, Android (also JVM), React Native JS, Godot, Qt Quick | Intent extras, deep links, MethodChannel, isolate messages, Godot signals | Process.run, dart:io File, user-controlled HTTP, SQL concat, WebView JavaScript, secrets in SharedPreferences |
| Functional | Elixir, Erlang, Haskell, Elm, OCaml, Lisp, Gleam, ReScript, Mix/Rebar | Phoenix, Plug, Cowboy, LiveView | Plug.Conn params, cowboy req, Phoenix socket, BEAM messages | os:cmd, Ecto raw SQL, Code.eval_string, File.write!, user-controlled HTTP, :erlang.binary_to_term |
| Systems | Zig, Nim, Crystal, D, Ada, Fortran, Pascal, assembly, WASM text, Haxe, Vala | Infer from neighboring build files | argv, sockets, FFI buffers, WASM imports | system()/exec, unbounded copies, format strings, FFI into libc, wasm memory.grow |
| Scripting | Shell, PowerShell, Perl, Lua, R, Julia, Tcl, Awk, batch, VBScript, AppleScript | Infer from shebang and callers | positional args, env, curl bodies, config files | eval, unquoted expansions, Invoke-Expression, system(), backticks, os.execute, source of a user path |
| Templates (SSTI) | Jinja, Nunjucks, Handlebars, EJS, Pug, Liquid, Twig, Freemarker, Velocity, ColdFusion, XSLT | Same engines plus CMS/email merge | template context from request, CMS fields, email merge fields | unescaped HTML, {{constructor}}, Twig/Freemarker/Jinja SSTI, cfinclude, XSLT document(), eval in filters |
| Notebooks | Jupyter .ipynb, R Markdown, Quarto | Jupyter, R Markdown, Quarto | notebook parameters, widgets, uploaded data frames | shell magics, pickle, pandas reads of a user path, eval of cells, IPython !system |
| Salesforce | Apex .cls / .trigger, Visualforce .page / .component | Salesforce, Visualforce, Lightning | ApexPages params, Trigger.new, REST @HttpGet, concatenated SOQL | Database.query(string), executeAnonymous, eval, callout to a user URL, without sharing classes |
| IaC / CI | Terraform, Dockerfile, Helm, GitHub Actions, GitLab CI, Ansible, Bazel, Jsonnet, YAML/TOML, Makefile | Terraform, Pulumi, Helm, Kubernetes, GitHub Actions, GitLab CI, CloudFormation, Ansible, Bazel | var interpolations, Helm values, Actions inputs, CI secrets context | privileged containers, hostPath, wildcard IAM, public buckets, unpinned actions, local-exec, curl | sh, unquoted script: |
| Data | SQL, GraphQL, protobuf, Prisma, Thrift, Avro, Cypher, SPARQL, PL/SQL | Infer from neighboring application code | bound parameters that became concatenation, GraphQL variables | dynamic SQL, unauth GraphQL mutations, giant nested proto parsers, Prisma $queryRaw |
| Smart contracts | Solidity, Vyper, Move, Cairo, Clarity, Cadence, TON FunC/Tact, Yul | Foundry, Hardhat, and the chain SDKs above | msg.sender, calldata, token amounts, signatures | delegatecall, call.value, unauthorized initialize, reentrancy, tx.origin auth, unchecked transfers |
| Markup | HTML, CSS/SCSS, SVG, XML, XSD, WSDL | Infer from the serving application | reflected query into templates, CSS expression leftovers, SVG onload, XML entities | inline event handlers, javascript: URLs, unescaped template holes, CSS url() to internal, XXE |
| App config | JSON/JSONC, INI, properties, plist, .env.example, package.json, go.mod, Cargo.toml, pyproject.toml | Package and policy manifests next to application source | config values interpolated into commands or URLs | hardcoded secrets, wildcard CORS, debug=true, 0.0.0.0 binds, overly broad IAM JSON |
| Other textual source | Extensionless or uncommon UTF-8 source | Infer from syntax and neighboring files | Infer from the repository | Infer from the repository |
Unrecognized textual files are still offered to a research agent as Other textual source. Binary, lock, and generated files are skipped.
How files are classified
- Match a known extension (
.go,.tsx,.tf, …). - Else match a known basename (
Dockerfile,Jenkinsfile,mix.exs,androidmanifest.xml, …). - Else sniff a shebang (
python,bash,ruby, …). - Else, if the file is non-empty valid UTF-8 with no NUL bytes, treat it as other textual source.
Classification stops at 4,000 files. Higher-risk paths (auth, handlers, routes, upload, CI workflows, Terraform) are ranked first when workers pick anchors.
What is skipped
Directories: .git, node_modules, vendor, dist, build, target, out, coverage, .next, .nuxt, virtualenvs, __pycache__, testdata/fixtures, .gradle, .idea, .terraform, Pods, Carthage, bower_components, and other hidden directories except CI roots (.github, .gitlab, .circleci, .buildkite, .woodpecker).
Files: README/license/changelog, lockfiles (package-lock.json, go.sum, Cargo.lock, …), minified *.min.*, generated stubs (.pb.go, .g.cs, .designer.cs), docs/spreadsheets, and binaries (images, archives, .wasm, .class, .jar, native objects). Empty files, files over 2 MiB, and symlink trees are ignored.
How a run is assigned
- Recon maps attack surface and emits class hunts (injection, authz, SSRF, and the rest of the SAST taxonomy).
- The same hunt stage adds research workers for the language families actually present, then fills remaining slots with domain focus (authorization, injection, request forgery, deserialization, crypto, business logic, supply chain).
- Candidates must cite a real file, line, and snippet. Inflated “zero-day” or CVE claims are dropped.
- Survivors still pass Validate and Trace before they are stored as findings.
Need a workflow that is not documented here? Email contact@eresussec.com.