Thick client applications are uniquely exposed to code-level attacks because they execute locally on user-controlled hardware, often include unmanaged native code, and process untrusted input from local filesystems, IPC channels, clipboard data, and network sources simultaneously. Unlike server-side applications protected by network perimeters and managed runtimes, thick clients must defend against attackers who can inspect binaries, manipulate memory, inject malformed files, and tamper with the running process. This chapter ensures that thick client code is hardened against injection, memory corruption, unsafe deserialization, and runtime tampering — and that code quality practices are sufficient to prevent exploitable defects from reaching production. Server-side API and service-level testing is deferred to the OWASP ASVS; this chapter focuses exclusively on the client binary, its local processing logic, and the interaction surfaces unique to thick client deployment.
Thick clients consume input from far more sources than web applications: file parsers, IPC channels, named pipes, shared memory, clipboard, drag-and-drop, COM/D-Bus interfaces, command-line arguments, and custom URL scheme handlers all feed data into the application. Each of these paths represents a potential injection vector if input is not rigorously validated before processing. These requirements ensure that all input — regardless of source — is validated, sanitized, and constrained before it reaches application logic.
| # | Description | Level | Source |
|---|---|---|---|
| V4.1.1 | Verify that untrusted data passed through macro engines, templating systems, or expression evaluators is protected against injection by using parameterization, sandboxed execution, or context-aware escaping. | 1 | TASVS |
| V4.1.2 | Verify that the application protects against OS command injection by avoiding shell invocations with user-controlled input, or where unavoidable, by using parameterized APIs and strict allowlist validation of arguments. | 1 | TASVS |
| V4.1.3 | Verify that all unstructured input is validated against an allowlist of permitted characters and constrained to a maximum length appropriate for the field's purpose before further processing. | 1 | TASVS |
| V4.1.4 | Verify that all process spawning and external program execution uses validated, fully-qualified paths and that all arguments are sanitized or parameterized to prevent argument injection and arbitrary command execution. | 1 | TASVS |
| V4.1.5 | Verify that user-submitted filename metadata is never used directly in filesystem operations, and that path traversal sequences, null bytes, and archive-relative paths (ZipSlip) are rejected or neutralized before file extraction or access. | 1 | TASVS |
| V4.1.6 | Verify that files imported or opened by the application are validated and parsed safely, ensuring that malformed, oversized, or malicious file content cannot trigger code execution, denial of service, or memory corruption in the thick client. | 1 | TASVS |
| V4.1.7 | Verify that the application validates and sanitizes all data received through inter-process communication channels (named pipes, shared memory, COM/D-Bus interfaces, clipboard) before processing, with the same rigour applied to network input. | 1 | New |
| V4.1.8 | Verify that the application does not construct or evaluate dynamic code (e.g., eval(), dlopen() with user paths, LoadLibrary() with user-controlled names, JIT compilation of user input) unless strictly required, and that any such usage is sandboxed and input-validated. | 1 | New |
Many thick client applications include native code components — whether written directly in C/C++, accessed through FFI bindings, or inherited from legacy libraries. Memory corruption vulnerabilities in these components represent the highest-severity risk class for thick clients because they enable arbitrary code execution with the application's privileges. These requirements ensure that unmanaged code follows memory-safe patterns and that compiler/runtime mitigations are in place to increase the cost of exploitation.
| # | Description | Level | Source |
|---|---|---|---|
| V4.2.1 | Verify that the application uses memory-safe string operations, bounds-checked memory copy functions, and safe pointer arithmetic to prevent stack-based, buffer-based, and heap-based overflow vulnerabilities. | 1 | TASVS |
| V4.2.2 | Verify that format string functions do not accept user-controlled format specifiers, and that all format strings are compile-time constants or are validated against a strict allowlist. | 1 | TASVS |
| V4.2.3 | Verify that sign, range, and input validation techniques are applied to all arithmetic operations to prevent integer overflows, underflows, and truncation that could lead to memory corruption or logic errors. | 1 | TASVS |
| V4.2.4 | Verify that in unmanaged or native code, dynamically allocated memory is freed exactly once, that pointers to freed memory are immediately nullified, and that use-after-free, double-free, and dangling pointer conditions are prevented through consistent ownership semantics. | 1 | TASVS |
| V4.2.5 | Verify that the application uses safe file operation patterns to prevent symlink and hard link attacks, including verifying the final resolved path before access and using exclusive file creation flags where supported by the OS. | 1 | TASVS |
| V4.2.6 | Verify that stack buffer overflow protections are validated at the binary level (e.g., presence of /GS cookies, _FORTIFY_SOURCE, -fstack-protector-strong) for all compiled modules, complementing V2.2.1 build-time requirements with runtime verification. | 1 | New |
| V4.2.7 | Verify that heap allocator hardening features are enabled where available (e.g., Windows Segment Heap, glibc heap checking, guard pages between allocations) to increase the difficulty of heap exploitation. | 2 | New |
Thick clients frequently consume serialized data from multiple sources: configuration files, saved state, IPC messages, network responses, and plugin data. Unlike server applications that primarily deserialize HTTP request bodies, thick clients may process serialized objects from local storage, clipboard, drag-and-drop, or named pipes — all of which may be attacker-controlled. Unsafe deserialization in these contexts can lead to remote code execution, privilege escalation, or arbitrary object instantiation. These requirements ensure that all deserialization is performed safely regardless of data source.
| # | Description | Level | Source |
|---|---|---|---|
| V4.3.1 | Verify that XML parsers are configured to use the most restrictive settings available, including disabling external entity resolution (XXE), DTD processing, XInclude, and XSLT where not required. | 1 | TASVS |
| V4.3.2 | Verify that serialized objects transmitted or stored include integrity verification (e.g., HMAC or digital signature) to detect tampering, and that the integrity check is validated before deserialization. | 1 | TASVS |
| V4.3.3 | Verify that deserialization of untrusted data is avoided where possible, and where required, uses safe deserialization mechanisms such as allowlists of permitted types, restricted class resolution, and isolated execution contexts. | 1 | TASVS |
| V4.3.4 | Verify that the application does not deserialize data from unauthenticated or integrity-unverified IPC sources, and that all inter-component serialized data uses a well-defined schema with strict type enforcement. | 2 | New |
Because thick clients run on user-controlled hardware, adversaries can attach debuggers, patch binaries, hook API calls, and modify application memory at runtime. While no client-side protection is unbreakable, layered integrity checks significantly raise the cost of tampering and detect unsophisticated attacks. These requirements are particularly relevant for applications handling sensitive data, implementing licensing controls, or operating in adversarial environments where client integrity directly affects security decisions.
| # | Description | Level | Source |
|---|---|---|---|
| V4.4.1 | Verify that the application validates the integrity of its own executable files, libraries, and critical data files at load time using cryptographic hashes or signatures, and fails safely if tampering is detected. | 2 | TASVS |
| V4.4.2 | Verify that the application performs runtime integrity self-checks (e.g., code section checksums, anti-debugging detection, hook detection) and responds to detected tampering with appropriate countermeasures such as graceful shutdown or reduced functionality. | 3 | TASVS |
| V4.4.3 | Verify that the application detects and responds to debugger attachment in production builds by restricting functionality or terminating, and that anti-debugging measures cannot be trivially bypassed by patching a single check. | 3 | New |
Thick clients interact with users, the operating system, and other applications through rich interfaces that web applications do not expose: custom URL scheme handlers, protocol handlers, drag-and-drop targets, clipboard monitors, and plugin ecosystems. Each interaction surface represents both a usability feature and a potential attack vector. These requirements ensure that interaction surfaces cannot be abused to trick users, escalate privileges, or bypass security controls.
| # | Description | Level | Source |
|---|---|---|---|
| V4.5.1 | Verify that the application does not employ deceptive user interface patterns (dark patterns) that mislead users into granting excessive permissions, sharing sensitive data, or bypassing security warnings. | 1 | TASVS |
| V4.5.2 | Verify that application workflows do not violate established security principles, such as requiring users to disable security features, store credentials insecurely, or bypass certificate warnings to complete normal operations. | 1 | TASVS |
| V4.5.3 | Verify that custom URL schemes and protocol handlers registered by the application validate all parameters before processing, cannot trigger dangerous actions (e.g., file deletion, code execution, privilege escalation) without explicit user confirmation, and reject unexpected or malformed URIs. | 1 | TASVS |
| V4.5.4 | Verify that the application restricts or sandboxes plugin and extension loading to prevent untrusted third-party plugins from accessing sensitive application data, elevated privileges, or bypassing security controls. | 2 | New |
| V4.5.5 | Verify that drag-and-drop, paste-from-clipboard, and other user-initiated data import paths apply the same input validation and sanitization as file open operations. | 1 | New |
Exploitable vulnerabilities in thick clients frequently originate from preventable code quality failures: unhandled exceptions that leak state, missing error checks on system calls, dead code that contains deprecated insecure patterns, and insufficient testing of input-processing routines. These requirements ensure that the development and release process includes systematic checks — static analysis, fuzzing, and secure coding validation — that catch exploitable defects before they ship in production binaries.
| # | Description | Level | Source |
|---|---|---|---|
| V4.6.1 | Verify that the application handles all exceptions and errors securely without exposing sensitive system information, stack traces, or internal paths to users, and that unhandled exceptions cannot leave the application in an insecure state. | 1 | TASVS |
| V4.6.2 | Verify that binary static analysis has been performed on the compiled application to confirm the absence of known vulnerable coding patterns, and that identified findings are triaged and remediated according to severity. | 2 | TASVS |
| V4.6.3 | Verify that Static Application Security Testing (SAST) is integrated into the development pipeline and executed against every release candidate, with blocking thresholds for critical and high-severity findings. | 1 | TASVS |
| V4.6.4 | Verify that documented secure coding policies and security test cases exist, are maintained alongside the codebase, and are validated as part of the release process. | 2 | TASVS |
| V4.6.5 | Verify that dead code, unreachable code paths, and unused dependencies are identified and removed to minimize the application's attack surface. | 2 | TASVS |
| V4.6.6 | Verify that randomized input fuzzing (mutation-based) has been performed against all file parsers, protocol handlers, and IPC interfaces exposed by the application, and that identified crashes are triaged for exploitability. | 2 | TASVS |
| V4.6.7 | Verify that coverage-guided fuzzing (generation-based or feedback-driven) has been performed to maximize code path coverage of input parsing and data processing routines, with crash analysis and remediation of all exploitable findings. | 3 | TASVS |
| V4.6.8 | Verify that the application implements defensive error handling for all native API calls, including checking return values from memory allocation, file operations, and system calls, and failing safely when unexpected errors occur. | 1 | New |