
Are you testing desktop app security and need to know what process to follow? That’s what this desktop application security testing checklist is for.
Desktop applications are fundamentally different from web and mobile apps – and those differences create unique security challenges.
Web applications run mostly server-side, behind your firewalls and security controls. The browser is just a client. Mobile apps run locally, sure, but the platform sandboxes them heavily – iOS and Android enforce strict boundaries on what apps can touch.
Desktop apps have neither advantage. They execute on local machines with broad access to system resources, writing to the file system wherever needed and calling OS services directly. Many run with elevated privileges just to function properly. Some interact with hardware – USB devices, printers, and biometric sensors. The security boundaries that exist for web and mobile? They’re not there.
This creates risks you won’t find in web application testing guides. Local storage isn’t protected by server-side controls. Authentication happens offline. Updates don’t go through curated app stores. Sensitive data sits on machines you don’t control, in environments that might be running outdated operating systems or worse – they can be compromised by malware.
So you need different checks. Not adaptations of ASVS or mobile testing frameworks – actual desktop-specific verification requirements, that address what breaks when code runs locally.
This desktop application security testing checklist provides those requirements organized by what actually matters for desktop security. It’s based on 10 years of practical desktop application security assessments at AFINE, where we’ve published 150+ CVEs and tested applications for major enterprises including banks, healthcare providers, and critical infrastructure.
Desktop Application Security Testing Levels
This desktop application security testing checklist is organized into three levels, matching testing depth to your application’s risk profile.
- L1 = Baseline – contains common desktop vulnerabilities. Implement basic input validation, simple authentication, and essential data protection. Every desktop application should meet these requirements at a minimum. They protect against widespread attacks that show up repeatedly in assessments. Most can be verified through black-box testing.
- L2 = Enhanced – is for applications handling sensitive data or performing business-critical operations. Implement more sophisticated authentication, granular access controls, comprehensive logging, and thorough input validation. You’re integrating security throughout development – threat modeling during design, security-focused code reviews, testing beyond automated scanning.
- L3 = High-risk – has to be implemented when a breach would be catastrophic. Think of financial systems, healthcare apps, defense software, and critical infrastructure. Assume that skilled attackers will specifically target your application. Implement stringent crypto requirements, minimal attack surface, layered defenses, and thorough monitoring. Security experts have to be involved directly in the development.
Start with L1 in this desktop application security testing checklist. These baseline checks catch most of what goes wrong in production, regardless of what your application does.
Network and Communication
TLS and Certificates
- L1, L2, L3 – All network traffic uses TLS with proper certificate validation
Fire up your proxy. If the app connects with a self-signed cert without complaining, certificate validation is broken. This is surprisingly common. - L2, L3 – Critical connections use certificate pinning
Banking apps? Healthcare? Financial trading? These need certificate pinning. Otherwise, MITM attacks work even with valid certificates. - L1, L2, L3 – Strong cipher suites only, no weak TLS versions
Check with sslyze or similar. Finding SSLv3, RC4, or weak DH groups? That’s a problem.
API Security
- L1, L2, L3 – API calls properly authenticate with secure credential management
Capture API traffic. Are credentials hardcoded in requests? Tokens stored insecurely? Auth headers predictable? - L1, L2, L3 – API keys and secrets never exposed in binaries or config files
Decompile the app and search through the config files. You’d be shocked at how often API keys sit in plaintext. - L1, L2, L3 – API responses validated before processing
Send malformed responses. Does the app crash? Execute unexpected code? Expose errors?
Inter-Process Communication
- L1, L2, L3 – IPC channels have proper access controls
Can any process connect to your named pipes, sockets, or message queues? Or is there actual authentication? - L1, L2, L3 – All IPC data validated before use
IPC is just another input source. Treat it like user input. Validate everything.
Local Storage and Files
Configuration Files
- L1, L2, L3 – No cleartext credentials in config files
Check AppData, ProgramData, and user directories. Open every .config, .xml, .json, .ini file. Finding passwords? That’s your first finding. - L1, L2, L3 – Sensitive config files have restricted permissions
On Windows, check ACLs. On Linux/Mac, check with ls -la. Can other users read sensitive config? Problem. - L2, L3 – Configuration with sensitive data is encrypted
Database paths, API endpoints, and internal URLs might not need encryption. But credentials, tokens, and keys absolutely do.
User Data Storage
- L1, L2, L3 – Sensitive data encrypted at rest
Found a local database? User files? Cached data? Open them. If you can read sensitive information without decryption, report it. - L1, L2, L3 – Platform-appropriate storage used (Keychain, Credential Manager, etc.)
Windows has a Credential Manager. macOS has Keychain. Linux has a Secret Service. Apps should use these, not roll their own. - L2, L3 – Temp files cleaned up and don’t contain sensitive data
Check system temp and app-specific temp folders. Apps love to leave sensitive data in temp files that never get deleted.
File Operations
- L1, L2, L3 – File paths from users are validated (prevent path traversal)
Try opening ../../../etc/passwd or C:\Windows\System32\config\SAM. If that works, you’ve got path traversal. - L1, L2, L3 – Files created by app have appropriate permissions
The app creates a file with user data. Can other users read it? That’s data leakage. - L1, L2, L3 – File uploads validate content, not just extensions
Rename a malicious file to safe.pdf. Does the app check actual content or just trust the extension?
Authentication and Credentials
Credential Storage
- L1, L2, L3 – Zero plaintext credentials anywhere
Binaries, config files, registry, databases, and memory dumps. If you find plaintext passwords, that’s a critical vulnerability. - L1, L2, L3 – No hardcoded credentials in the application
Decompile or disassemble. Search for “password”, “secret”, “key”, “token”. Check for Base64 strings (they often encode credentials). - L2, L3 – Are cached authentication tokens properly protected?
Apps that work offline cache authentication somehow. How is that cache protected? Encrypted? Integrity-checked?
Authentication Logic
- L1, L2, L3 – Authentication failures include rate limiting
Try logging in wrong 100 times. If there’s no lockout or delay, that’s an unlimited brute force opportunity. - L2, L3 – Biometrics are a second factor only, not primary
Face/Touch ID should unlock a real credential, not replace it. You can’t change your face if it’s compromised. - L2, L3 – Offline authentication as strong as online
How does the app verify credentials when offline? If your app uses online authentication, verify the offline fallback can’t be bypassed by patching the binary to skip authentication checks entirely or always return “success”.
Memory and Runtime
Memory Protection
- L2, L3 – Sensitive data cleared from memory after use
Attach a debugger. Dump memory. Search for passwords, credit cards, and tokens. If they’re sitting there in cleartext, write it up. - L2, L3 – Memory dumps don’t expose secrets
Force a crash. Check if crash dumps contain passwords or keys. - L1, L2, L3 – Standard memory protections enabled (ASLR, DEP/NX)
Use checksec (Linux), checksec (Windows), checksec anywhere or similar tools. Missing ASLR or DEP makes exploitation much easier.
Binary Analysis
- L1, L2, L3 – No hardcoded secrets in the binary
Run strings on the executable. Search the decompiled code. Look for crypto keys, passwords, and API secrets. - L1, L2, L3 – Crypto uses standard libraries with strong algorithms
Custom crypto is almost always broken. DES, MD5, RC4 in 2025? Those are findings. See the OWASP Cryptographic Storage Cheat Sheet for current best practices. - L2, L3 – Update mechanism validates signatures before installing
MITM the update check. Can you serve a malicious update? If signature verification is missing or broken, you can backdoor every user.
Access Control and Privileges
Privilege Management
- L1, L2, L3 – Application requests minimum necessary permissions
Does it really need admin rights? Full file system access? Or is it requesting permissions “just in case”? - L1, L2, L3 – Privilege elevation only when needed, with user notification
When the app requests admin, users should know why. Silent elevation is suspicious. - L2, L3 – Administrative functions separated from normal operations
Can regular users somehow trigger admin functions? Through UI manipulation? Direct function calls? IPC?
Authorization
- L1, L2, L3 – Authorization checks in business logic, not just UI
Disabled buttons and hidden menus aren’t security. Can you bypass UI restrictions and call protected functions directly? - L1, L2, L3 – Access control fails closed (deny by default)
- What happens when access control checks fail or error out? If it defaults to “allow”, that’s a problem.
- L2, L3 – Sensitive operations require re-authentication
Deleting all data? Changing security settings? These shouldn’t work with just the initial login.
Input Validation
File Input
- L1, L2, L3 – File uploads validate content, not just extension
Send a malicious PDF. A ZIP bomb. An XML file with XXE payloads. Does the app validate actual content? - L1, L2, L3 – File parsers handle malformed input safely
Fuzz the file parsers. Send corrupted files. Does it crash? Expose errors? Execute unexpected code? - L1, L2, L3 – XML parsing prevents XXE attacks
Send an XML file with external entity references. Can you read local files? Make the app hit external URLs? See the OWASP XXE Prevention Cheat Sheet for detailed prevention techniques.
User Input
- L1, L2, L3 – All input validated before processing
Every text field, every file path, every IPC message. Validate type, length, format, and range. - L1, L2, L3 – No eval() or similar dangerous functions with user input. Search the codebase for functions that execute code from strings:
eval(), exec(), system(), shell_exec(), popen(), CreateProcess(), ShellExecute(), Runtime.exec(), Function() constructor, os.system(), subprocess.call(), Invoke-Expression(). If user input reaches any of these, attackers can execute arbitrary code on your system. - L1, L2, L3 – Command injection prevented (no unsanitized input in OS commands)
If the app shells out to the OS, test with command injection payloads. ; whoami, | ls, && id.
Installation and Updates
Installation Security
- L1, L2, L3 – Installer package is signed and signature verified
Can you modify the installer? Does it verify integrity before running? Unsigned installers are malware distribution waiting to happen. - L1, L2, L3 – Installation runs with minimum necessary privileges
Does the entire install need admin? Or just specific steps? Excessive privileges create an attack surface. - L2, L3 – Installation validates system meets minimum security requirements
Does it check the OS version? Security patches? Or will it install on an unpatched Windows XP box?
Update Security
- L1, L2, L3 – Updates downloaded over HTTPS with certificate validation
MITM the update check. Can you serve fake updates? - L1, L2, L3 – Update packages cryptographically signed and verified
Modify an update package. Does the app install it? Signature verification prevents supply chain attacks. - L2, L3 – Update mechanism can’t be used to install arbitrary code
Can you trick the updater into installing malicious payloads from unexpected locations?
Uninstallation
- L1, L2, L3 – Uninstall removes all components and data
Uninstall the app. What’s left behind? Config files with secrets? Cached credentials? Leftover data? - L2, L3 – Uninstall securely wipes sensitive data
Does uninstall just delete files? Or does it securely wipe sensitive information so it can’t be recovered?
Hardware and Devices
- L1, L2, L3 – Proper access controls for hardware resources
Camera, microphone, location. Does the app ask permission? Can users see when hardware is accessed? - L2, L3 – Device data validated before processing
USB drives, external devices, scanners. Data from hardware should be treated as untrusted input. - L2, L3 – Biometric authentication properly implemented
Using Touch ID or Face ID? Check for proper fallback, liveness detection, and that biometrics unlock a real secret, not replace it. - L2, L3 – Hardware security features used when available (TPM, Secure Enclave)
If the platform has hardware key storage, crypto acceleration, or secure enclaves, the app should use them.
Logging and Monitoring
Log Content
- L1, L2, L3 – Security events logged (auth attempts, privilege changes, access failures)
What gets logged? Can you detect suspicious activity from the logs? - L1, L2, L3 – Logs don’t contain sensitive data
Check log files for passwords, tokens, credit cards, PII. These shouldn’t be in logs ever. - L1, L2, L3 – Error messages don’t expose sensitive information
Force errors. Do they include stack traces? Database errors? File paths? Internal details attackers can use?
Log Security
- L2, L3 – Log files have restricted access
Can any user read logs from privileged operations? That’s information leakage. - L2, L3 – Logs protected from tampering
Can you modify or delete logs? If there’s no integrity protection, attackers can cover their tracks. - L1, L2, L3 – Log rotation prevents disk exhaustion
Can you fill the disk by triggering excessive logging? That’s denial of service.
UI Security
Data Display
- L1, L2, L3 – Passwords and PINs masked in UI
Password fields should mask input. But also check accessibility APIs. Can other apps read the “hidden” password? - L1, L2, L3 – Sensitive data not exposed in window titles or notifications
Window titles appear in screenshots, screen sharing, task switchers. Don’t put account numbers or PII there. - L2, L3 – Screenshots prevented or obscured for sensitive screens
Payment screens, medical records, confidential data. Can you screenshot these? Should you be able to?
Clipboard and Copy/Paste
- L2, L3 – Copy/paste controlled for sensitive fields
Can you copy passwords? Credit cards? Should be disabled for these fields. - L2, L3 – Clipboard cleared after timeout for sensitive data
If you do allow copying sensitive data, the clipboard should auto-clear after a short time.
Self-Protection
Integrity Checks
- L2, L3 – Runtime integrity checks for critical code
Does the app verify its own integrity while running? Can you modify memory without detection? - L1, L2, L3 – Tampering with executables detected
Modify the binary. Does the app detect it? Refuse to run? Or just work with your modifications? - L2, L3 – Dependencies verified for integrity
Are library signatures checked? Can you substitute malicious DLLs?
Reverse Engineering Resistance
- L2, L3 – Debugging detection for sensitive operations
Attach a debugger. Does the app detect it when handling sensitive data? - L2, L3 – Appropriate obfuscation for sensitive logic
Not foolproof, but it makes reverse engineering harder. Especially important for license checks or DRM. - L3 – Environment checks for VMs or analysis tools
High-risk apps should detect virtualization, analysis tools, or other indicators of security research.
Platform-Specific Security Testing Checklist
Windows
- Check registry keys for cleartext secrets
- Test for unquoted service paths
- Verify proper use of Windows Credential Manager
- Check for DLL hijacking opportunities
- Test UAC prompts and privilege escalation
macOS
- Verify proper Keychain usage
- Check application sandbox entitlements
- Test Gatekeeper and code signing
- Verify proper use of system permissions (camera, mic, etc.)
- Check for insecure helper tools
Linux
- Verify proper use of Secret Service
- Check file permissions (should never be 777)
- Test AppArmor or SELinux profiles
- Verify secure handling of setuid binaries
- Check for privilege escalation via sudo/polkit
What This Desktop Application Security Testing Checklist is Based On
This desktop application security testing checklist is based on the Desktop Application Security Verification Standard (DASVS).
DASVS has 12 security domains, 150+ specific requirements, and three risk levels. It’s what you need, when web app security standards don’t cover your attack surface.
The complete DASVS framework is here: https://github.com/afine-com/DASVS
Use this checklist as your starting point. Use DASVS when you need the complete picture.
Paweł Woyke




