Skip to content

Security

Akram El Assas edited this page Jun 5, 2026 · 70 revisions

Table of Contents

  1. Security Overview
  2. How We Protect Your Data
    1. Automatic Directory Hardening (ACLs)
    2. Machine-Unique Encryption (Dynamic Entropy)
    3. Cryptographic Key Derivation (HKDF)
    4. Authenticated Encryption (v6.5+)
    5. In-Memory Defense (Memory Zeroing)
    6. Sensitive Command-Line Arguments & Service Account Credentials
  3. Infiltration Guard: Local Import Enforcement
  4. Supply Chain & Trust
  5. The Servy Trust Boundary
  6. File Locations & Recovery
  7. Critical Warning: Machine Migration
  8. Best Practices
  9. Troubleshooting

Overview

Servy acts as a secure vault for your Windows service configurations. We encrypt sensitive data, including passwords, environment variables, and all execution arguments (Parameters, Password, EnvironmentVariables, FailureProgramParameters, PreLaunchParameters, PreLaunchEnvironmentVariables, PostLaunchParameters, PreStopParameters, and PostStopParameters), using industry-standard AES-256 encryption. If the database is compromised, your actual secrets remain unreadable text.

The Double-Lock System

Starting in version 7.9, we use a two-layer defense strategy to keep your secrets safe:

  • The Locked Room (ACLs): We automatically restrict who can even view the Servy folders on your hard drive.
  • The Machine-Unique Key (Dynamic Entropy): We tie your encryption key to the unique fingerprint of your specific computer. If the files are stolen and moved to another PC, they cannot be opened.

You can verify that the "Locked Room" is active by checking the Access Control List (ACL) of the data directory. Run the following command in an elevated PowerShell window:

(Get-Acl "$env:ProgramData\Servy").Access | Select-Object IdentityReference, IsInherited, AccessControlType

What to look for in the output:

  • IdentityReference: You should typically see three principals: NT AUTHORITY\SYSTEM, BUILTIN\Administrators, and the specific user account that installed Servy.
    • Note: The installer and the SecurityHelper class grant the current user Full Control as a "Manual Key" to ensure operational continuity. If the installation was performed strictly by a process already running as SYSTEM, only the first two will appear.
  • IsInherited: This must be False for all entries. Servy explicitly breaks inheritance from the C:\ProgramData root to prevent "sideways" access from other applications or standard users.
  • AccessControlType: This should be Allow. There should be no entries for broad identity groups such as Everyone, Users, or Authenticated Users, as these are surgically purged during the hardening phase.

Implementation Context for Auditors

To reconcile this with the source code, auditors can refer to the following logic gates:

  • Inno Setup (servy.iss): The ShouldAddCurrentUser check ensures the interactive installer's account is added to the folder ACL.
  • Runtime (SecurityHelper.cs): The ApplySecurityRules method checks if the current UserSid is the SystemSid. If they differ, it explicitly adds the FileSystemRights.FullControl rule to the directory.

Subdirectory Inheritance Note

While the root vault (%ProgramData%\Servy) has inheritance explicitly broken, all internal child folders such as recovery, db, and security are created with inheritance enabled relative to the vault root. This ensures the three-principal "Locked Room" security model is maintained consistently throughout the entire data structure without redundant ACL writes.

How We Protect Your Data

We have overhauled our security model to be proactive rather than reactive.

1. Automatic Directory Hardening (ACLs)

In previous versions, we relied on Windows defaults for the %ProgramData%\Servy folder. In v7.9+, Servy takes control. Upon installation or startup, the application automatically performs the following actions:

  • Breaks Inheritance: We disconnect the folder from the open permissions of the parent drive.
  • Explicit Purge: We surgically remove access for the Users, Authenticated Users, and Everyone groups.
  • Restricted Entry: Only SYSTEM and Administrators are allowed in. This prevents Local Privilege Escalation: the risk of a standard user tampering with a service to gain Admin rights.
  • Downward Inheritance: All subfolders and files within %ProgramData%\Servy automatically inherit these strict parent ACLs, ensuring new service directories, configurations, and logs remain locked down by default.
  • Custom Permissions Preserved (with caveat): Explicit Allow ACEs you have added for named identities are retained. Any Allow rule targeting the broad groups Users, Authenticated Users, or Everyone is surgically purged on every run. Deny rules for those broad groups are left in place (only Deny rules targeting Administrators, LocalSystem, or the installing user are removed, as an anti-squatting measure).

2. Machine-Unique Encryption (Dynamic Entropy)

We use the Windows Data Protection API (DPAPI) with an added security layer. To prevent binary analysis (where someone reads our code to find a secret), we derive our encryption entropy from your computer's unique MachineGuid.

  • Why it is safe: The combination to the vault is not written in our code; it is hidden in your Windows Registry.
  • Non-Portable: Because every computer has a different ID, your aes_key.dat file is useless if copied to another machine.

3. Cryptographic Key Derivation (HKDF)

To adhere to strict cryptographic best practices, we use HKDF (RFC 5869) to derive independent sub-keys from your master key. By combining a cryptographic salt with distinct context strings (V2_AES_ENCRYPTION and V2_HMAC_AUTHENTICATION), we guarantee absolute key separation between our encryption operations and our authentication layers.

4. Authenticated Encryption (v6.5+)

We use AES-256-CBC with HMAC-SHA256. This does not just hide your data; it wraps it in a digital seal. If an attacker tries to modify even a single bit of the encrypted data, Servy will detect the tampering and refuse to decrypt it, preventing bit-flipping attacks.

5. In-Memory Defense (Memory Zeroing)

Security doesn't stop at the hard drive. To protect against advanced memory scraping attacks, Servy securely handles secrets in RAM. Our SecureData class implements IDisposable and utilizes CryptographicOperations.ZeroMemory() to wipe every sensitive buffer as soon as it is no longer needed:

  • Transient Data: Plaintext and ciphertext buffers are zeroed immediately after each encryption/decryption call.
  • Initialization Material: The master key clone passed during construction is wiped as soon as sub-keys are derived.
  • Key Material: All active sensitive buffers are securely zeroed upon the object's disposal. This includes the two HKDF-derived V2 sub-keys required for modern AES encryption and HMAC authentication. (Note: The two legacy V1 buffers, used for master key cloning and static IV retention, remain unallocated in shipped production builds as AllowLegacyV1Decryption is permanently disabled at compile-time).

Unlike standard array clearing methods, this approach ensures that the memory wipe is never elided by the JIT compiler's release optimizations, significantly reducing the window of opportunity for an attacker to extract keying material from a memory dump.

6. Sensitive Command-Line Arguments & Service Account Credentials

While Servy supports CLI flags for configuration convenience (e.g., --password, --envVars, --params), passing sensitive data via command-line arguments is insecure. Command-line arguments are visible to any user or process able to enumerate the process list (e.g., Get-Process, pslist, or Event Tracing for Windows) and are often recorded in shell history files and system audit logs.

The Preferred Methods

Starting in v8.5, Servy provides two secure alternatives to handle sensitive data:

  1. Environment Variables (Recommended for per-service secrets): For each sensitive field, Servy supports an associated environment variable. Servy reads these variables transparently at install time, ensuring the secret never touches the process argument string.
  2. Import Configuration (Recommended for complex deployments): Use the import command with an XML or JSON configuration file. This keeps sensitive values entirely out of the command line and allows for structured, version-controlled configuration management.

Sensitive Fields Reference

The following parameters are considered sensitive and should be provided via environment variables (v8.5+) or configuration files:

Parameter Environment Variable Description
--password SERVY_PASSWORD Windows service account password.
--params SERVY_PROCESS_PARAMETERS Command-line arguments for the service process.
--envVars SERVY_ENVIRONMENT_VARIABLES Environment variables for the service process.
--failureProgramParams SERVY_FAILURE_PROGRAM_PARAMETERS Arguments for the failure recovery program.
--preLaunchParams SERVY_PRE_LAUNCH_PARAMETERS Arguments for the pre-launch executable.
--preLaunchEnv SERVY_PRE_LAUNCH_ENVIRONMENT_VARIABLES Env vars for the pre-launch executable.
--postLaunchParams SERVY_POST_LAUNCH_PARAMETERS Arguments for the post-launch executable.
--preStopParams SERVY_PRE_STOP_PARAMETERS Arguments for the pre-stop executable.
--postStopParams SERVY_POST_STOP_PARAMETERS Arguments for the post-stop executable.
PowerShell Example:
# Set the secrets in the process-level environment
$env:SERVY_PASSWORD = 'p@ssw0rd_123!'
$env:SERVY_ENVIRONMENT_VARIABLES = 'API_KEY=secret_key_123;DB_URL=... '

# Install the service (omit sensitive flags)
servy-cli install --name="MySecureService" --path="C:\App\app.exe" --user="DOMAIN\svc_account"

# Clear variables immediately after use
Remove-Item Env:SERVY_PASSWORD
Remove-Item Env:SERVY_ENVIRONMENT_VARIABLES

Infiltration Guard: Local Import Enforcement

Importing service configurations from Universal Naming Convention (UNC) paths or through redirected paths (such as symbolic links or junctions) poses severe security risks. These techniques are designed to bypass system trust boundaries and expose the application execution layer to malicious configuration injection.

To preserve system integrity, the import pipeline explicitly blocks non-local paths. The primary attack vectors mitigated by this enforcement include:

  • Attacker-Controlled Configuration Injection: UNC targets (e.g., \\attacker\share\evil.xml) allow a remote adversary to host a malicious configuration file on an infrastructure node under their direct control. If ingested, an attacker can inject arbitrary executable paths, unauthorized parameters, or unverified environment variables, effectively hijacking the service's runtime behavior.
  • Path Redirection Attacks: By leveraging filesystem symbolic links, directory junctions, or specialized Win32 reparse points, an attacker can manipulate the path resolution mechanics. This can trick the engine into reading from an entirely different backend target than intended, exposing sensitive files or pulling parameters from unexpected network locations.
  • Privilege Escalation and System Integrity: Because the engine performs administrative elevation validation checks to operate securely, it possesses high-privilege access to the local machine. If an import task is manipulated into processing files from protected operating system directories (such as the Windows or System32 namespaces), it can facilitate unintended system-level file access or manipulation.
  • Network-Based Mapping Bypasses: Virtual local paths - including mapped network drives (e.g., Z:\config.json) or local DOS device substitutions (subst) - frequently mask underlying remote storage volumes. These targets inherently lack the rigid security boundaries of localized storage hardware, introducing network-level interception vectors.

Mitigation: Defense-in-Depth Pipeline

To counter these vectors, the engine pipes all configuration paths through a strict, sequential validation chain before any file access occurs across the CLI or GUI interfaces:

  1. Explicit UNC Inspection: Rejects any raw path strings starting with standard network prefixes (\\) or parsing as a remote URI.
  2. Drive Interface Queries: Evaluates the target volume via DriveInfo to proactively block network-backed logical drive letters.
  3. Reparse Point Ancestor Walks: Recursively traces the full directory tree to verify that no parent or sibling paths utilize symbolic links or directory junctions.
  4. File-Level Symlink Evaluation: Directly inspects filesystem attributes to confirm the target file is a physical, non-symbolic entity.
  5. Reserved Device Blocks: Prevents spoofing attempts using legacy system device designations (e.g., CON, PRN, AUX).
  6. Protected System Directory Fencing: Prevents configuration loading out of primary administrative operating system paths.
  7. Win32 Kernel Handle Finalization: Opens a temporary restricted read handle to execute a low-level volume query via GetFinalPathNameByHandle. This extracts the ultimate canonical storage path, stripping away any complex virtual loop devices or custom environment mappings to expose and block hidden UNC targets.

Supply Chain and Trust

We believe security requires transparency. You should not have to guess if our software is safe.

  • Digitally Signed: All executables are signed by SignPath. This proves the code has not been altered since it left our build server.
  • SBOM (Software Bill of Materials): We publish a full list of every ingredient used to build Servy in the CycloneDX format.
  • Vulnerability Scanning: We use GitHub Dependabot to monitor for holes in our dependencies 24/7.
  • Verified Safe: Servy is regularly reviewed by Microsoft Security Intelligence and passes clean scans on VirusTotal.

The Servy Trust Boundary

Servy operates on a Single Trust Boundary model. All services managed by Servy live in the same secure room: %ProgramData%\Servy.

What this means for you

  • Shared Influence: If you give a specific service account Write access to the Servy folder, it can technically see the configuration of other services in that same folder.
  • Intended Use: Servy is designed for dedicated app servers, CI/CD agents, and workstations.
  • Isolation Tip: If you need absolute Zero Trust isolation between two services, they should be run on separate Virtual Machines or in Windows Containers.

Automatic Permissions Table (v7.9+)

Identity Access Level Managed By
SYSTEM Full Control Servy (Automatic)
Administrators Full Control Servy (Automatic)
Installing User (when not SYSTEM) Full Control Servy (Automatic)
Custom Service Accounts Modify User (Manual)
Standard Users None Servy (Automatic)

The installing user ACE is added by SecurityHelper.ApplySecurityRules only when the current process identity is not SYSTEM. If Servy was installed/run strictly under SYSTEM (e.g. unattended deployment), this row does not appear in the ACL.

Note

If you run a service under a custom Service Account, you must manually grant that account Modify rights to %ProgramData%\Servy. Standard users are blocked by default for your protection.

File Locations and Recovery

Your master encryption keys are stored here:

  • Database: %ProgramData%\Servy\db\Servy.db
  • Key: %ProgramData%\Servy\security\aes_key.dat
  • IV: %ProgramData%\Servy\security\aes_iv.dat

The aes_iv.dat file holds the static IV used by the legacy v1 cipher format (Servy < 6.5). Servy 6.5+ uses a per-message random IV embedded in the ciphertext, so the static IV is no longer used to encrypt or decrypt anything in current builds - v1 decryption is permanently disabled (AllowLegacyV1Decryption = false) to mitigate downgrade attacks. While disabled, the file is not read on service start and is not loaded into memory; the entire load path is compiled out via the AllowLegacyV1Decryption constant. The file is still created on fresh installs and retained on disk so that legacy material remains available if AllowLegacyV1Decryption is ever re-enabled in a custom build - do not delete it. To migrate records written by a pre-6.5 build, export them with a v1-compatible Servy version and import the resulting file into the current version; they will be re-encrypted as v2.

Critical Warning: Machine Migration

Because our encryption is tied to your specific Windows installation, you cannot simply copy the .dat files to a new server.

To move Servy to a new PC:

  1. Export your services on the old machine (the export is unencrypted; treat it like a physical key - Parameters, EnvironmentVariables, etc. are written in plaintext).
  2. Move the Export file to the new machine.
  3. Import the services. Because Servy never persists the LogOn account/password into the export, the imported services will run as LocalSystem by default.
  4. Re-enter the service account credentials manually in Servy Manager (or via servy-cli install) for any service that should not run as LocalSystem.

Step 4 is mandatory if your services run under a domain account, MSA, or local account.

Best Practices

  • Backup the Whole Servy Data Folder: Before doing a Windows Reset or Refresh, back up the entire %ProgramData%\Servy\ tree. The keys (security\*.dat) and the encrypted configuration database (db\Servy.db) must be restored together - keys alone cannot decrypt anything, and the database alone cannot be decrypted without the matching keys.
  • Use Managed Accounts: When possible, run services under Managed Service Accounts (MSA) for the best balance of security and ease of use.
  • Audit Access: Periodically check the Security tab of the %ProgramData%\Servy folder to ensure no unauthorized users have been added manually.

Troubleshooting

  • Access Denied on Startup: This usually means the account running the service does not have permissions to the %ProgramData%\Servy folder. Refer to the Permissions Table above.
  • Decryption Error: This happens if the .dat files were moved from another computer or if the Windows MachineGuid was altered. You will need to re-enter every encrypted field - Password, Parameters, EnvironmentVariables, PreLaunchEnvironmentVariables, and the corresponding hook Parameters (PreLaunchParameters, PostLaunchParameters, PreStopParameters, PostStopParameters, FailureProgramParameters) - because all of them are stored under the same machine-bound AES key. If you have an Export from the original machine, import it now (per Critical Warning: Machine Migration) instead of reconfiguring each service by hand.

Servy v7.9+ is designed to be invisible but invincible. By automating the routine parts of Windows security, including Access Control Lists and Registry GUIDs, we ensure your infrastructure stays locked down without needing a degree in cryptography.

Questions? Check our full Troubleshooting Guide or join the community discussion.

Clone this wiki locally