How We Secure GoAhead, Appweb and Ioto
EmbedThis continuously audits and tests its embedded web servers: GoAhead, Appweb and Ioto. Specialist AI auditors review the source code, while C test harnesses check parser behavior using fuzzing, protocol tests and tools that detect memory errors. Confirmed defects go through our normal fix and release process, with permanent regression tests to catch any recurrence.
Why Embedded Servers Need Targeted Testing
An embedded web server accepts untrusted network input before authentication. Our servers use C to meet memory and portability requirements, and often run on devices that stay deployed for years and are hard to update. One remotely reachable parsing defect can affect an entire product fleet.
Tests sent over a network connection leave many internal parser branches and malformed-input paths unexplored. Our program also tests parsers directly, generates inputs and checks that protocol rules and memory-safety requirements hold.
What We Examine
The audit covers 20 security domains across source code, configuration, deployment and build processes, grouped below:
| Area | Examples |
|---|---|
| Protocol | Request-line and header parsing, chunked transfer encoding, response generation |
| URL and routing | URL parsing, filesystem mapping, route and handler selection, canonicalization and encoding |
| Authentication | Basic and Digest authentication, sessions and cookies, authorization policy, password and secret handling |
| Dynamic execution | CGI arguments and environment, templates, uploads, form and query parsing |
| Memory safety | Buffer bounds, allocation lifetime, integer arithmetic, error-path cleanup |
| Transport | TLS configuration across OpenSSL and MbedTLS, certificate handling, socket I/O |
| Deployment | Default configuration, logging and error disclosure, static files, administrative interfaces, proxies and caching |
| Platform | Windows, POSIX and RTOS behavior, 32-bit builds |
| Resilience | Connection and request limits, slow clients, algorithmic complexity |
| Build and supply chain | Hardening flags, compiler warnings, dependencies, feature-flag combinations |
| Regression | Replay tests for every past advisory, with searches for similar defects elsewhere in the code |
We check that components interpret requests consistently, so differences in URL decoding, path normalization or message framing cannot bypass security checks.
How an Audit Runs
An automated coordinator schedules 41 specialist AI auditors alongside the C testing tools. Each auditor has a focused assignment, such as transfer encoding, Digest authentication or CGI, and read-only access to the source. Auditors compare required behavior with the implementation, then propose tests for potential vulnerabilities.
The specialists are grouped by their primary responsibilities. Each has its own checklist, and several domains draw on more than one specialist:
| Area | Specialists |
|---|---|
| HTTP and socket I/O | HTTP parsing, transfer encoding, response generation, socket I/O |
| URL and routing | URL canonicalization, routing, filesystem mapping, range and conditional requests |
| Authentication and authorization | Basic authentication, Digest authentication, sessions and cookies, authorization policy |
| Dynamic execution | CGI, templates, uploads, form and query parsing, process spawning |
| Memory safety | Buffer bounds, allocation lifetime, integer arithmetic, error paths |
| TLS | TLS configuration and certificate handling |
| Configuration and logging | Configuration defaults, logging and error disclosure |
| Platforms | Windows, POSIX, RTOS |
| Fuzzing and dynamic testing | HTTP fuzzing, URL fuzzing, authentication fuzzing, CGI fuzzing, differential testing, leaks |
| Build and supply chain | Build hardening, static analysis, dependencies and SBOM, feature-flag combinations |
| Clients and proxies | Web client security, caching and proxy behavior |
| Regression | Historical vulnerabilities and related-defect searches |
| Documentation | Security contract and deployment guidance |
Specialists examine the functions that call or are called by the code under review, along with related code paths, protocol variants and build configurations. They must also report relevant code that falls outside every specialist's assignment.
Each scan records the audited commit, platform, compiler, sanitizers, feature flags and tool versions, so a later reviewer can see exactly what was tested on which build.
Testing Techniques
- In-process parser harnesses call parser code directly on raw bytes, reaching boundary values and internal branches that network tests rarely hit.
- Coverage-guided fuzzing uses libFuzzer with AddressSanitizer and UndefinedBehaviorSanitizer to explore code paths and detect memory errors and undefined behavior. Without a starting input that triggered either defect, it rediscovered a historical GoAhead chunk-size integer overflow in about 1,300 to 5,500 executions and a Digest authentication out-of-bounds read in 4 to 22 executions.
- Differential testing compares the chunk-size parser with a strict model of the RFC 9112 grammar to expose message-framing inconsistencies that fuzzing for crashes can miss.
- Stateful keep-alive testing sends pipelined requests through a single connection and checks that request-specific state does not carry over to the next request.
- Leak detection combines allocation accounting with LeakSanitizer, because small repeated leaks can exhaust a device.
- Static analysis and expanded compiler warnings compare results with a reviewed baseline, so new diagnostics are flagged for review. We are introducing these baselines.
Parser harnesses, fuzzing, differential testing and keep-alive testing are in use on all three servers today.
How We Fix Security Issues
A finding is confirmed only when a test shows an observable violation: a sanitizer report, a failed correctness check, an incorrect authorization decision, disclosure of a sensitive file, or a parser disagreement. Each confirmed finding records the affected code, severity, Common Weakness Enumeration (CWE) category, root cause, evidence, regression test and proposed fix.
Confirmed defects then follow the same path as customer and researcher reports:
- Assess. Maintainers verify the defect, determine whether an attacker can reach it and assess its severity.
- Fix and verify. The full test suite runs under sanitizers. The regression test must fail before the fix and pass after it.
- Check related code. We search the product and the other two servers for the same root cause. We generalize the issue and look for similar cases with a similar underlying cause.
- Human review. A person reviews every ticket and every code patch before release.
- Release. The fix ships through the Builder with release notes and, where warranted, a security advisory. See our Security Policy.
How the Audit Program Improves
After each audit, an automated improvement process reviews the results for missed defects and gaps in coverage. It proposes changes to specialist instructions and priorities, or additional specialists. Each proposed change is tested separately before it is accepted.
Improvements are scored on new, confirmed findings backed by reproducible evidence, such as a sanitizer failure, a confirmed memory leak or a parser disagreement. Unverified and already known findings earn no credit; retracted findings reduce the score. To be accepted, each change must also:
- continue to detect the historical and withheld validation defects already detected by the framework;
- pass the checks that verify sanitizer and leak detection work;
- keep every security domain covered;
- maintain its score on a fixed validation set while staying within the permitted false-positive rate.
The automated process can change only auditor instructions and configuration. Server source, test harnesses, fuzzers, test input collections and scoring code are maintained by people and protected against automated writes. A change that would loosen a check, remove an assertion or reduce coverage cannot be applied automatically; it becomes a proposal for human review. Every accepted change is recorded as its own commit with its rationale and check results. A failed change is reverted to restore the last accepted state.
More capable AI models may also improve the audits. Each model upgrade must pass the same evaluation and meet the same evidence requirements.
The first iteration using these acceptance checks ran in October 2026 and produced three proposed specialist improvements, which are under human review.
Scope and Limits
- Code you write on top of the servers, such as handlers, actions and pages, is outside the audit. Apply the same direct parser testing and sanitizer-backed fuzzing to it.
- Operating system, network and physical security remain the device maker's responsibility.
- No audit proves the absence of defects. Stay current with releases through the Builder, and report suspected issues to security@embedthis.com.
For details on how this program supports your Cyber Resilience Act obligations, see CRA Support.