Skip to content

Releases: HiveControlAgents/StingWard

Stingward v0.1.8

Choose a tag to compare

@github-actions github-actions released this 22 Oct 16:55
d103164

Added

  • DEP005, PHP version with known vulnerabilities: the PHP version a project runs on is looked up in OSV.dev, from the php image in a Dockerfile or docker-compose.yml (with ARG values filled in), .php-version, .tool-versions and mise.toml. A project on php:8.3.30-apache now gets CVE-2026-109618 and CVE-2026-109619, the remote code execution flaws in PHP disclosed on 2026-10-22, as critical, with the fix: PHP 8.3.36 (8.2.35, 8.4.27 and 8.5.12 in the other branches). A tag that follows a branch, such as php:8.3-apache, gets what the branch fixed in the last 90 days, one level lower, since only an image built before the fix has it; a branch with no fix, such as 8.1, gets the full severity.
  • Ad labels: a visitor who arrives from a link with utm_source, utm_medium, utm_campaign or utm_content (each a short plain word) keeps them on the links to the site's other pages and on the buy button, so the order and the payment can say which ad or post it came from. Nothing is stored on the visitor's device, other parameters are not passed on, and the privacy policy says what the label is and that the order keeps it.
  • A sample of the paid report on the website (/example/full/ and /pt/exemplo/completo/): the demo app's HTML report with a comment on every finding from the AI review and a summary on top, from the review and notes files in site/sample/, applied with --review and --notes as the report service does. The plain sample and this one link to each other, and the offer's "See a sample report" opens this one. The build stops if the demo app has a finding the review file does not cover.

Changed

  • The Portuguese site shows the report's price in reais, R$ 99, the amount Paddle charges buyers in Brazil, with a line saying that outside Brazil it is US$ 29. The English site still shows $29, and the terms in both languages give both prices.
  • The offer, the FAQ and the terms describe the paid report's review as an automatic review of every finding. The privacy policy still says which lines go to Anthropic's AI model for it.
  • Reports from a review file with "review_kind": "ai" say "automatic review" instead of "AI review", in the HTML, text and Markdown formats, as the website does; the scope section says the masked excerpt of each finding went to the review service. The review file format does not change.
  • The "Check its work" section of the website is more compact: the six tiles sit in three columns beside the heading and no longer grow taller as the screen gets wider, so the section stays short on wide displays.

What's Changed

Full Changelog: v0.1.7...v0.1.8

Stingward v0.1.7

Choose a tag to compare

@github-actions github-actions released this 22 Oct 14:26
f830694

Added

  • Terms of service, privacy policy and refund policy for the paid report, in English (/terms/, /privacy/, /refund/) and Portuguese (/pt/terms/, /pt/privacy/, /pt/refund/). They are built from site/legal.json, linked from the footer of every page, and load the site's stylesheet and no script; a link in them can only go to another of the three pages or to an https:// address.
  • AI review in the review file: "review_kind": "ai" (the default is "person"). The HTML, text and Markdown reports then say AI review instead of human review, and the scope section says what was checked, in which files and on what date. An AI review refuses accepted_risk, because only the client can accept a risk, and accepts fixed only for a finding that is gone from a scan that could see it: not hidden by .stingwardignore, a stingward:ignore comment or the size and file limits. The HTML report also says that the code excerpt of each finding, with secrets masked, went to the AI model. The JSON review block gains kind and masked, which is true when something in a comment, the notes or a name looked like a secret and was masked, in any of the formats.
  • --no-ignore, to audit someone else's project: its .stingwardignore and stingward:ignore comments hide nothing, so whoever wrote the code does not choose what the audit shows. When the project asked to hide findings, the HTML report says those requests were not applied. Since nothing is hidden, an AI review can mark fixed a finding that is gone even where an ignore line or comment would have covered it.

Changed

  • The website moved to https://stingward.com/. The old GitHub Pages address sends visitors there.
  • The website offers the Stingward report in place of the human-reviewed audit: US$ 29 ($29 in English), paid once. You send a zip or one GitHub repository, Stingward checks it, an automatic review goes over every finding, and the PDF report arrives in minutes, with one free new check of the fixed version within 30 days and a full automatic refund if it is not ready in 24 hours. The FAQ and the note on the sample report say the same. The buy button still reads "Coming soon" while links.audit_checkout is empty.
  • The language switch shows each language beside its flag (Brazil for Portuguese, the United States for English) and lists Portuguese first, since the site opens in English. The flags are two small SVG files published with the site.

Fixed

  • SEC001 no longer reports a password in a database URL with several hosts, such as postgresql://h1:5432,user:password@h2/db from pydantic's MultiHostUrl: the start used to be read as the user h1 with the password 5432,user:password. The credential after the last comma is checked as any other, and a user with no password is not reported. foo, bar, baz, qux and foobar count as sample passwords.
  • Language words beside a sensitive name, such as credentials: true in a CORS or fetch setting or password = None, are no longer masked as secrets in code excerpts and reports.
  • With an AI review, the text, Markdown and HTML reports say "fixed since the previous report" instead of "fixed during the audit", since nobody followed the fix: it is what a new scan no longer finds.

What's Changed

  • Add AI review to the review file and reports by @IsaqueMoutta in #9
  • Add --no-ignore to audit someone else's project by @IsaqueMoutta in #10
  • Site: US$ 29 report, legal pages, flags in the language switch by @IsaqueMoutta in #11
  • Release 0.1.7: multi-host URLs, language literals, AI review wording by @IsaqueMoutta in #12

Full Changelog: v0.1.6...v0.1.7

Stingward v0.1.6

Choose a tag to compare

@github-actions github-actions released this 21 Oct 10:02
2dd1691

Added

  • GitHub Action input category (default stingward), passed to the SARIF upload, so a workflow that audits several folders keeps one code scanning result per folder.
  • Human review for audits you hand over. --review-template FILE writes a JSON file with one entry per finding (and keeps what was already reviewed when it runs again); the reviewer sets each status to confirmed, false_positive, accepted_risk or fixed and writes a comment. --review FILE applies it to every report: the HTML shows the status and comment on each finding, moves false positives to an appendix and says in the scope section that a person reviewed the report and how many findings were confirmed or discarded. False positives and findings fixed during the audit leave the grade, the fix-first list and --fail-on; accepted risks still count toward the grade but leave the fix-first list, and the plan lists them, with what was fixed, under "no action planned". The text and Markdown reports follow the same rules, and the JSON gets each finding's review, a review summary and the grade after the review.
  • --client NAME puts "Prepared for" on the cover of the HTML report, and --notes FILE adds the analyst summary at the top of the executive summary, written in a small Markdown subset (paragraphs, - lists, **bold**, `code`). Comments, notes and the client and reviewer names are escaped and go through the same secret masking as code excerpts; on top of that, any value that masking removed from a flagged line of the audited project (or from any line of a small file flagged as a whole, such as .env) is masked wherever it shows up in them, even in pieces.
  • Every finding in the JSON output has a fingerprint, also in SARIF as properties.fingerprint. It comes from the rule, the file, the package, variable or table, and the masked text of the flagged line, not from the line number, so it survives edits elsewhere in the file. The rest of the JSON and SARIF output is unchanged.
  • DEP004 checks the lowest version each range allows when there is no lockfile: requirements*.txt and package.json without a lockfile beside them, and the [project] dependencies and optional dependencies of a pyproject.toml without poetry.lock, uv.lock or pdm.lock. Pillow>=10 lets a machine keep Pillow 10.0.0, which has 18 known vulnerabilities, one of them on the CISA KEV list; the finding says how many, names the worst and gives the new minimum (Pillow>=12.3.0). The lowest versions go to OSV.dev in the same batch as the pinned packages, and a package pinned elsewhere in the project is left to DEP001. Severity is medium at most, since the installed version is often newer, unless the range's upper bound leaves out the fix.
  • An exact version written in a way the lockfile readers did not catch, such as "Pillow==10.0.0" in pyproject.toml or foo (==1.0) in requirements.txt, is now audited by DEP001.
  • --format html and --html FILE: a single-file report in English or Portuguese to hand over or print to PDF (A4). It has a cover with the grade and verdict, an executive summary with what to fix first, a remediation plan with rough effort, findings grouped by area with the code excerpt, standards and references, and the scope, sources and limitations of the audit. It needs no network: no scripts, fonts or images are loaded, and a content security policy allows only its inline styles. Secrets in code excerpts are masked and everything from the audited project is escaped.
  • A new code check (--only code) that reads the project's own code: Python with ast, JavaScript and TypeScript (including the <script> of .vue, .svelte and .astro files) with tight patterns that follow request data inside each function. Tests, examples and fixtures drop to low, and minified bundles are skipped.
  • COD001 to COD011: SQL injection, shell command injection, code injection (eval, exec, new Function, render_template_string), pickle and unsafe YAML, XSS (innerHTML, dangerouslySetInnerHTML, v-html, {@html}), TLS checks turned off (also NODE_TLS_REJECT_UNAUTHORIZED=0 in .env files), path traversal, SSRF, open redirects, Math.random or random for secrets, and passwords hashed with MD5 or SHA.
  • APP009 to APP013, for code that calls a model: its answer reaching eval, a shell, SQL or HTML; request input inside the system prompt; AI routes with no login and no rate limit (OWASP LLM06); trust_remote_code=True, allow_dangerous_deserialization=True and torch.load without weights_only=True; agents with a Python REPL or shell tool, allow_dangerous_code=True or AutoGen without Docker.
  • The demo app built by scripts/demo/fixtures.py now also reports APP011 on its chat route, and has the mistakes the code check and DEP004 catch: an agent route that runs the model's answer in a shell, SQL built from the request, a PDF route that reads any path, a link preview that fetches any URL, a chat component that renders the model's answer as HTML, and a Python worker whose requests>=2.19.0 allows a version with known vulnerabilities. Every key in it is fake. The README demos were recorded again from it.
  • The website shows the code check, the AI-specific rules and DEP004, links to a sample report (/exemplo/ and /en/example/): the real HTML report of the demo app, built at deploy time, with a note on top and its content security policy kept. It also presents a security audit with a human review (US$ 149, delivered in 48 hours, with what it includes and what it does not cover) and a waitlist for a Team plan. Both buttons read their addresses from links in site/text.json; while an address is empty the button reads "Em breve" / "Coming soon" and is not a link, and a filled one must be an https:// address. Parts of the page more than a screen away no longer sit hidden while they wait for their entrance, so a page read without scrolling through it shows no blank stretch.
  • APP014, for MCP servers and agent tools: an argument the model writes reaching a shell command, eval/exec, a template, SQL, pickle or unsafe YAML, a file path, a URL the server fetches or HTML. Tool arguments are read from FastMCP @mcp.tool() and mcp.add_tool(f), low-level @server.call_tool() handlers and their arguments, TypeScript server.tool(...), server.registerTool(...) and CallToolRequestSchema handlers, LangChain @tool and BaseTool._run, AI SDK tool({ execute }), and tool_call.function.arguments or block.input from OpenAI and Anthropic responses, and are followed into helpers of the same file and into functions the tool imports from other files of the project, two levels deep. Critical when the argument is mixed into a command or code written in the code, high for SQL, deserialization and a path joined to the code's own folder, medium for other paths, URLs and HTML. Typed arguments (numbers, Literal, Enum, Field(pattern=...), z.number(), z.enum()), injected parameters such as ctx, query parameters, argument lists whose program is written in the code, an argument passed first to a check such as validate_name(arg) or validatePath(p), shlex.quote, basename, a resolve-and-prefix check, a fixed file name, a fixed host and an allow list of hosts are not reported. Each finding carries the CWE and OWASP Agentic entry of its sink besides LLM03:2026, in every report format, and keeps its full severity in stingward skill.
  • COD002 also catches ["sh", "-c", cmd] in Python and spawn("sh", ["-c", cmd]), spawn(cmd, { shell: true }) and execa with shell: true in JavaScript.
  • COD005 also catches HTML built from request data in Express res.send/res.write/res.end (with .status() and similar chained before), Hono c.html, and FastAPI routes with response_class=HTMLResponse; a Flask route that returns the HTML in a variable or in a (body, status) tuple counts too.
  • COD010 also catches Math.random() in a module-level value or inside a callback that builds it, and a session id (session_id, sessionId, sid) made with Math.random() or random that goes into a cookie.
  • COD001 in Python also catches SQL built from request data and passed to the project's own query helpers (execute_query(f"..."), run_sql(...)). COD007 in JavaScript also reads fsp, fsPromises and fs-extra calls and counts checks such as validatePath(p) or isAllowedPath(p) before the call. COD008 in JavaScript no longer takes the word private (a TypeScript private field) as a check of the address.
  • SEC001 finds Replicate (r8_), Pinecone (pcsk_), Shopify (shpat_, shpss_, shpca_, shppa_), Notion (ntn_), Linear (lin_api_) and Resend (re_) keys as critical, and Google OAuth client secrets (GOCSPX-) as high. Each format has its exact length, and the short prefixes (r8_, re_) also need digits and both letter cases, so names in code are not taken for keys.

Changed

  • The DEP003 docs no longer list pyproject.toml: it never raised DEP003, since libraries declare ranges on purpose.
  • Text and Markdown reports list the same problem (same rule, title and explanation) once, with every place it was found, and start with a short "fix these first" list when there are critical or high findings. JSON and SARIF still have one record per finding.
  • Test and example code is recognized in more places (e2e/, samples/, testdata/, __mocks__/, cookbooks/, test_*.py, conftest.py), and findings there are lowered as they already were in tests/ and examples/.
  • The source package on PyPI no longer ships tests/: those tests read files that only the repository has, so they could not run from it. CI now checks what the sdist and the wheel hold.
  • Python 3.14 is tested in CI on Linux, macOS and Windows and listed in the package classifiers. Python 3.9 is still the oldest supported.
  • DEP002 on the lowest version of a range without a lockfile is critical only when ev...
Read more

Stingward v0.1.5

Choose a tag to compare

@github-actions github-actions released this 20 Oct 03:44

Changed

  • Stingward is now under the Apache 2.0 license, which adds an explicit patent grant and states that the license does not cover the Stingward name. Version 0.1.4 and earlier stay under MIT.

Added

Full Changelog: v0.1.4...v0.1.5

Stingward v0.1.4

Choose a tag to compare

@github-actions github-actions released this 20 Oct 02:39

Changed

  • The secret masking module is now stingward/_redact.py. Reports and behavior are the same.

Full Changelog: v0.1.3...v0.1.4

Stingward v0.1.3

Choose a tag to compare

@github-actions github-actions released this 20 Oct 02:21

Added

  • SKL011 flags reverse shells in skills and agent scripts (bash -i >& /dev/tcp/..., nc -e, socat exec:, Python pty.spawn, PowerShell TCPClient).
  • SKL002 also catches downloading a file and running it on the same line (curl -o x ... && chmod +x x).
  • SKL005 understands "follow the instructions on the page".

Changed

  • SKL009 is high, not medium, when an install script downloads and runs code from the internet.
  • SKL004 no longer treats env=dict(os.environ) as reading credentials: copying the environment to a child process is normal. Sending the whole environment (json=dict(os.environ), json.dumps(os.environ), params=os.environ) is still critical.

What's Changed

  • Bump the actions group with 4 updates by @dependabot[bot] in #1

New Contributors

Full Changelog: v0.1.2...v0.1.3

Stingward v0.1.2

Choose a tag to compare

@github-actions github-actions released this 20 Oct 01:47

Changed

  • The Action's description is shorter, within the GitHub Marketplace limit of 125 characters.
  • GitHub release notes now come from this changelog.

Full Changelog: v0.1.1...v0.1.2

Stingward v0.1.1

Choose a tag to compare

@github-actions github-actions released this 20 Oct 01:35

Full Changelog: v0.1.0...v0.1.1

Stingward v0.1.0

Choose a tag to compare

@github-actions github-actions released this 20 Oct 00:34