Inno Setup
Inno Setup is a free, open-source installation builder designed for creating software installers for Windows applications, utilizing a script-driven approach based on Pascal scripting to customize installation processes.[1] Developed by Jordan Russell and Martijn Laan, it was first introduced in 1997 and has become a widely trusted tool among developers for its reliability and flexibility in packaging and deploying software.[1]
Key features of Inno Setup include support for modern Windows versions such as Windows 11, 10, and 7 without requiring service packs, as well as compatibility with 64-bit architectures (x64 and Arm64) and multilingual installations, including right-to-left languages.[1] It enables the creation of single executable installer files with built-in uninstall capabilities, customizable setup types like Full or Minimal, and advanced functionalities such as file compression using algorithms like deflate, bzip2, and 7-Zip LZMA/LZMA2, alongside registry and INI file editing.[1] The tool maintains a minimal overhead of approximately 1.78 MB, making it efficient for distribution.[1]
While Inno Setup is provided under an open-source model, its developers request that commercial users—such as organizations distributing installers for profit—purchase a dedicated license to support project sustainability, though it remains free for personal and non-commercial use.[1] Notably, it has been adopted by prominent software projects, including Visual Studio Code, Git for Windows, and Embarcadero Delphi, highlighting its role in professional development workflows.[1]
History
Development Origins
Inno Setup was developed by Jordan Russell in 1997 as a script-driven installation system for Windows applications, utilizing Embarcadero Delphi as the primary programming language.[1][2] This choice of Delphi enabled the creation of a compact, efficient executable installer without dependencies on external runtime libraries, aligning with Russell's goal of producing a self-contained tool. The project originated from Russell's experience in software distribution, where he sought to address limitations in existing solutions by emphasizing ease of use and customization through scripting. Martijn Laan joined as a key contributor, with his "My Inno Setup Extensions" incorporated into version 2.0 in June 2003, enhancing the tool's capabilities.[3]
The first public release occurred in 1997.[1] By focusing on a lightweight design that generated single executable files with no ongoing fees, Inno Setup prioritized simplicity, scriptability, and accessibility for independent developers and small teams.
Early adoption of Inno Setup spread primarily through word-of-mouth within programming and shareware communities, where its reliability and lack of licensing restrictions made it a preferred choice for packaging applications.[4] Developers began incorporating it into their distributions, further amplifying its visibility without formal marketing efforts. This grassroots growth laid the foundation for its evolution into an open-source project, though detailed advancements in later versions are covered elsewhere.[1]
Major Releases and Milestones
Significant technical milestones followed in the mid-2000s. Version 5.1, released on May 31, 2005, introduced support for installing 64-bit applications on 64-bit Windows systems.[5] Later, version 5.3.0-beta, released on April 22, 2009, added Unicode support, enabling better handling of international languages and characters across different system code pages.[5]
In the 2010s, Inno Setup transitioned to full open-source availability, with its source code hosted on GitHub since October 2013, allowing community contributions alongside primary development by Jordan Russell and Martijn Laan.[4] Version 6.0, first released in beta on February 11, 2019, brought enhancements to the integrated Compiler IDE, including per-monitor DPI awareness, support for the Segoe UI font, and improved output views for better usability on modern displays.[6]
Recent updates have continued to expand capabilities. Version 6.5.0, released on August 12, 2025, increased the maximum size limit for a single Setup.exe file to 4 GB, aligning with Windows' upper limits and accommodating larger installations.[7] Version 6.6.0, released on November 11, 2025, introduced support for dark mode and dynamic theme adaptation in Setup and Uninstall interfaces, along with custom styles for enhanced visual consistency.[8] Ongoing development remains led by Russell and Laan, with community input facilitated through GitHub pull requests and issues.[4]
Core Features
Installation Capabilities
Inno Setup provides robust mechanisms for deploying applications across diverse Windows environments, enabling seamless installation processes that adapt to system configurations and user needs. Central to its installation capabilities is the ability to create a single executable installer that supports multiple processor architectures, including IA-32 (32-bit), x64 (64-bit), and ARM64, by detecting the host system's architecture at runtime and installing the appropriate files without requiring separate builds. This multi-architecture support is facilitated through directives in the [Files] section, such as ArchitecturesAllowed and ArchitecturesInstallIn64BitMode, which allow developers to specify architecture-specific installation rules within one unified setup package.[9]
A key aspect of Inno Setup's file handling during installation involves automatic version comparison to ensure updates are applied intelligently. By default, the installer compares the version information of existing files against those being installed, replacing them only if the new version is higher, which prevents unnecessary overwrites and maintains system stability. For files that are in use by running processes and cannot be replaced immediately, Inno Setup employs a retry mechanism—up to four attempts—and supports the "restartreplace" flag in the [Files] section to schedule replacements for the next system reboot via Windows' MoveFileEx API, prompting the user for a restart if necessary. This approach minimizes disruptions while ensuring complete file updates.[9][1][9]
The tool integrates comprehensive uninstaller creation as a standard feature, generating a dedicated executable (unins000.exe) that handles full cleanup of installed files, directories, registry entries, and shortcuts based on the original installation log. The Uninstallable directive in the [Setup] section controls this process, ensuring the uninstaller is included and registered in the Windows Add/Remove Programs control panel, where it performs reverse operations like deleting files listed in [UninstallDelete] and running specified programs in [UninstallRun] to restore the system state accurately. This built-in support for thorough uninstallation promotes reliable software management without residual artifacts.[10][11][12]
Inno Setup addresses prerequisite dependencies through integrated checks and execution capabilities, allowing installers to verify and install required runtimes such as the .NET Framework or Visual C++ redistributables before proceeding. Developers can use Pascal scripting functions like IsDotNetInstalled to detect the presence of specific .NET versions and service packs, and the [Run] section to execute external installers or setup programs if prerequisites are missing, ensuring the target application launches successfully post-installation. This proactive handling prevents common deployment failures on unprepared systems.[13][12]
Localization is a core strength, with multi-language support enabling installers to present user interfaces in the system's preferred language or via a selection dialog at launch. This is achieved through the [Languages] section, which references external .isl (Inno Setup Language) files containing translated strings, dialog captions, and messages; Inno Setup includes pre-built .isl files for over 40 languages, and custom ones can be created for additional support, including right-to-left scripts. The language selection occurs automatically based on system locale or user choice, making installations accessible globally without altering the core executable.[14][1]
To enhance security and user trust, Inno Setup incorporates digital signing integration directly into the compilation process, allowing executables and uninstallers to be signed with certificates using tools like SignTool. The SignTool directive in the [Setup] section specifies the signing command, which applies to the setup executable, embedded files, and the generated uninstaller when SignedUninstaller is enabled, thereby avoiding "unknown publisher" warnings in Windows SmartScreen and UAC prompts. This feature ensures compliance with modern Windows security standards and streamlines distribution.[15][16][1]
Compression and Packaging
Inno Setup provides built-in compression options to optimize the size of installation files while balancing compression ratio against processing time. The supported algorithms include deflate, bzip2, and 7-Zip's LZMA and LZMA2, with configurable compression levels that allow developers to trade off between file size reduction and compression/decompression speed. For instance, deflate and bzip2 support levels from 0 (no compression, fastest) to 9 (maximum compression, slowest), while LZMA/LZMA2 offer fast and ultra modes for similar adjustments, enabling smaller installers for faster downloads at the potential cost of longer build times.[17][1]
A key feature is the generation of a single executable (Setup.exe) file that bundles all installation components, facilitating straightforward online distribution without requiring multiple files or archives. This single-EXE format supports installations up to 4 GB in size starting from version 6.5.[7]
To further enhance efficiency when packaging multiple files, Inno Setup includes solid compression, which treats all files as a single continuous data stream during compression rather than compressing them individually. This approach can achieve significantly higher overall compression ratios than non-solid methods by exploiting redundancies across files, though it increases memory usage during extraction and may slow down access to individual files.[18]
For security in distribution, Inno Setup supports password protection, where a password is prompted at the start of the installation process, preventing unauthorized users from proceeding without it. This feature integrates with encryption to safeguard contents, ensuring that the installer cannot be run or files extracted without the correct password.[19]
Additionally, encryption of setup files is available to protect intellectual property and sensitive data during transit. When enabled via the Encryption directive, files compiled into the installation are secured using the XChaCha20 symmetric encryption algorithm, with the key derived from the provided password through functions like PBKDF2 for added strength against brute-force attacks. The encryption can apply to specific files or the entire installation, requiring the password via command-line parameter for full-encrypted setups.[20][21]
Scripting and Customization
Pascal Scripting Engine
The Pascal Scripting Engine in Inno Setup provides a powerful mechanism for runtime customization of installation and uninstallation processes through a subset of the Pascal programming language, resembling modern Delphi syntax. This engine allows developers to embed executable code directly within installer scripts (.iss files) via the optional [Code] section, enabling dynamic behaviors such as conditional logic, user input validation, and system interactions that go beyond static configuration. The scripting is event-driven, where predefined functions are invoked at specific points during the installation workflow, and it supports standard Pascal constructs like variables, procedures, loops, and conditionals to handle complex scenarios.[22][23]
Central to the engine is the [Code] section, which contains the Pascal script code executed by Inno Setup's integrated runtime. Scripts here can perform pre-installation checks, modify installation parameters based on runtime conditions, or execute post-install actions like launching applications. For instance, the engine supports declaring global and local variables with standard scoping rules: global variables are accessible throughout the script, while local ones are confined to their procedure or function, following Pascal's block-structured scoping to prevent unintended side effects. Procedures and functions can be defined to encapsulate reusable logic, and exception handling is available via try-except blocks, allowing graceful error recovery with functions like RaiseException to throw custom errors and GetExceptionMessage to retrieve details.[23][24][25]
Key event functions drive the customization, triggered automatically by the installer at predefined stages. The InitializeSetup event function, declared as function InitializeSetup(): Boolean;, runs early in the process for tasks like verifying prerequisites or reading command-line parameters; returning False aborts the installation, while True proceeds. CurStepChanged, prototyped as procedure CurStepChanged(CurStep: TSetupStep);, executes when the installation advances through steps (e.g., pre-install, install, post-install), ideal for step-specific actions such as logging progress or adjusting file permissions. ShouldSkipPage, as function ShouldSkipPage(PageID: Integer): Boolean;, enables conditional skipping of wizard pages based on user choices or system state, enhancing workflow flexibility without altering the core UI structure. These events, along with others like DeinitializeSetup for cleanup, form the backbone of runtime adaptability.[26]
The engine includes a rich set of built-in support functions for common operations, categorized by file handling, registry access, and external integrations. For file operations, CopyFile ([function](/page/Function) CopyFile(const ExistingFile, NewFile: [String](/page/String); FailIfExists: Boolean): Boolean;) allows scripted file copying with options to overwrite or fail on conflicts, useful for dynamic deployments. Registry manipulation is handled by functions like RegWriteStringValue ([function](/page/Function) RegWriteStringValue(RootKey: [Integer](/page/Integer); SubKey, ValueName, Value: [String](/page/String)): Boolean;), which writes string values to the Windows registry, enabling configuration persistence. External DLL calls are supported via LoadDLL to load libraries; to call functions dynamically, declare them with the 'external' keyword using the DLL handle, such as [function](/page/Function) SomeFunction(Param: [String](/page/String)): [Integer](/page/Integer); external 'dllhandle@SomeFunction;1';. This facilitates integration with Win32 APIs or custom modules extracted during installation. Example usage might look like:
var
DllHandle: LongInt;
begin
DllHandle := LoadDLL('example.dll');
if DllHandle <> 0 then
begin
try
SomeFunction('param');
finally
UnloadDLL(DllHandle);
end;
end;
end;
var
DllHandle: LongInt;
begin
DllHandle := LoadDLL('example.dll');
if DllHandle <> 0 then
begin
try
SomeFunction('param');
finally
UnloadDLL(DllHandle);
end;
end;
end;
This extends the script's capabilities to system-level interactions.[27][28][29][30]
Finally, the Pascal Scripting Engine integrates seamlessly with Inno Setup's Preprocessor (ISPP), allowing conditional compilation in .iss files using directives like #if, #elif, #else, and #endif. These evaluate expressions at compile time to include or exclude script sections based on defined constants (e.g., #define DEBUG), such as #if DEBUG then #include "debug_code.iss" #endif, which can conditionally embed debugging procedures or variant logic without runtime overhead. This combination supports both compile-time flexibility and runtime dynamism, making the engine versatile for diverse deployment needs.[31][32]
User Interface Customization
Inno Setup offers extensive options for tailoring the wizard interface, allowing developers to modify standard pages, integrate custom elements, and adapt the visual style to enhance user experience during installation. The wizard follows a sequential page-based structure, where each page handles specific user interactions, and customization is achieved primarily through the [Setup] section directives, Pascal scripting, and resource files. This flexibility enables branding, conditional page skipping, and dynamic content display without altering the core installer logic.[33]
Standard wizard pages include the Welcome page, which introduces the installation; the License Agreement page, displayed if a LicenseFile is specified in the script; the Password page, shown when encryption is enabled via the Password directive; and the Select Components page, which allows users to choose installation options defined in the [Components] section. These pages can be disabled or modified using directives such as DisableWelcomePage, DisableLicensePage, and DisablePasswordPage, or through Pascal scripting event functions like ShouldSkipPage to conditionally bypass them based on user input or system conditions. For instance, the Select Components page supports hierarchical component trees and descriptions for user-friendly selection. Additionally, pages like Select Destination Location and Select Start Menu Folder permit directory and folder customization, with options to set defaults via DefaultDirName and DefaultGroupName.[34][35][26]
Custom wizard pages can be added or fully designed using the Pascal scripting engine, extending the standard flow with tailored interactions. The CreateCustomPage function initializes an empty page, onto which developers add controls like labels, edit boxes, or radio buttons using methods such as CreateStaticText for labels and CreateComboBox for combo boxes; pre-built pages are available via functions like CreateInputQueryPage for simple queries, CreateDirTreePage for folder selection, or CreateInputSelectListPage for list-based inputs. Custom dialogs are supported through functions such as MsgBox, which displays modal message boxes with configurable icons, buttons, and text, and TaskDialogMsgBox for modern Windows task dialogs with instructions and expandable details. These elements allow for dynamic user interactions, such as validation or confirmation prompts, integrated seamlessly into the wizard flow. A brief reference to scripting events, like NextButtonClick, enables triggering UI changes or validations during page transitions.[36][37][38][39]
Theme support enhances visual customization, with the WizardStyle directive offering styles such as classic (gray background), modern (white background), and advanced modes including light, dark, dynamic (system-adaptive), polar (blue accents), slate (gray), windows11 (matching Windows 11 aesthetics), and zircon (cyan accents) as of version 6.6.0 (November 2025). Version 6.6.0 introduced full dark mode support for both Setup and Uninstall, along with new directives like WizardStyleFileDynamicDark for custom dark themes and direct support for built-in custom styles in WizardStyle. It also added automatic adaptation to Windows settings in dynamic mode, with high DPI scaling through per-monitor awareness and directives like WizardResizable, ensuring proper layout and font scaling on high-resolution displays without aspect ratio distortion. Custom styles are ignored in high-contrast themes to maintain accessibility.[40][7][41][42][43]
Icon and bitmap integration allows branding the installer UI with custom graphics. The SetupIconFile directive specifies a .ico file or executable for the main Setup and Uninstall window icon, replacing the default built-in icon. Side images are customized via WizardImageFile, which supports .bmp and .png formats (including transparency with WizardImageAlphaFormat) for the large left-panel bitmap, sized to 164x314 pixels by default; WizardSmallImageFile handles the smaller top-panel image (80x70 pixels), also supporting transparency and custom backgrounds via WizardImageBackColor or WizardSmallImageBackColor. These elements ensure a cohesive, professional appearance tailored to the application's branding.[44][45][46]
Progress bar and status messages during installation provide real-time feedback, customizable through scripting for advanced scenarios. The standard Installing page features a determinate progress bar that updates based on file sizes and operations, with status text reflecting current actions like file extraction or registry changes. For more control, the CreateOutputProgressPage function generates a custom wizard page with a progress bar and label, updated via SetText and SetProgress methods during scripted operations; alternatively, CreateOutputMarqueeProgressPage offers an indeterminate marquee-style bar for ongoing tasks without known duration. Event functions like CurInstallProgressChanged allow monitoring and adjusting progress in real-time, ensuring users receive clear, branded feedback throughout the process.[47][48][26]
Creating Installers
Inno Setup installers are authored using script files with the .iss extension, which are plain text files encoded in ASCII or Unicode (UTF-8) that resemble the structure of Windows .INI files. These scripts define the entire installation process through a series of named sections, each containing key-value pairs or entries that specify parameters, files, and actions.[49]
The [Setup] section is foundational, containing directives that configure global installation settings such as the application's name, version, publisher, and output directory for the compiled installer. For instance, directives like AppName, AppVersion, and DefaultDir determine basic metadata and the target installation path. Subsequent sections build on this: the [Files] section lists source files to copy to the destination, using parameters like Source for the input path (supporting wildcards) and DestDir for the output location; the [Icons] section creates shortcuts in locations like the Start Menu or desktop, with entries specifying the icon file, target executable, and working directory; and the [Registry] section manages Windows Registry modifications, defining keys and values to add, set, or delete during installation, with options to control uninstall behavior. Other common sections include [Components] for grouping optional features, [Tasks] for user-selectable actions, and [Run] for post-installation executions.[49][9][50][51]
To compile a .iss script into an executable installer, users employ the Inno Setup Compiler, available as a command-line tool (ISCC.exe) or through the graphical interface provided in the installation package. The command-line usage is straightforward: running ISCC.exe followed by the script filename, such as ISCC.exe MySetup.iss, processes the script and outputs a single Setup.exe file, with options for output directory (/O), or preprocessor controls. The compiler outputs progress messages to the console. Since version 6.0, the graphical compiler includes an integrated development environment (IDE) with syntax highlighting, error checking, and a built-in editor for authoring and compiling scripts directly, streamlining the development workflow.[52][52][43]
Components, tasks, and run lists enable modular and customizable installations. The [Components] section defines hierarchical optional elements displayed on the wizard's Select Components page, using parameters like Name, Description, and Flags (e.g., fixed or optional) to allow users to select features such as core application files versus add-ons. Similarly, the [Tasks] section specifies additional operations like creating desktop icons or associating file types, presented as check boxes with parameters including Name, Description, and GroupDescription for categorization. The [Run] section, meanwhile, outlines programs or commands to execute after file installation, such as launching the application or running maintenance tools, with parameters like Filename, Parameters, and WorkingDir; entries can be conditional based on components or tasks selected. These features support flexible setups without requiring extensive scripting.[35][53][12]
Handling dependencies, such as required runtimes or external software, is managed through directives in sections like [Files], where BeforeInstall parameters can invoke prerequisite installers before main files are copied, or via the InitializeSetup event function for custom logic. For example, an entry in [Files] might execute an external .msi or .exe for a framework like .NET, with options to wait for completion or run minimized. More complex prerequisite detection and installation often integrates with the Pascal scripting engine for custom logic.[12]
Testing installers involves compiling the script and running the resulting executable with command-line parameters for automated verification. The /SILENT parameter suppresses the wizard interface while showing a progress bar, allowing interactive but minimized testing, whereas /VERYSILENT runs the installation completely unattended without any UI, ideal for scripted deployments or batch validation; both modes log output to a file if /LOG is specified, facilitating error diagnosis.[54]
Third-Party Extensions
Third-party extensions for Inno Setup provide additional functionality beyond the core compiler, enabling developers to streamline script creation, automate dependency management, and integrate advanced features through external tools and scripts. These add-ons, often developed by the community and hosted on platforms like GitHub, enhance productivity by offering graphical interfaces, visual designers, and modular components that extend the installer’s capabilities without modifying the base software.[55]
ISTool serves as a graphical script editor designed specifically for Inno Setup, featuring syntax highlighting for easier code navigation and template support to import configurations from other installer formats like Visual Basic .lst or InstallShield .iwz files. It includes drag-and-drop functionality for adding files directly from Windows Explorer and preserves original script comments during editing, supporting all Inno Setup directives across multiple languages. Released in versions compatible with Inno Setup 5.3 and later, ISTool simplifies the creation of complex setup scripts for professional installations.[56]
Inno Script Studio functions as an IDE-like tool that allows visual design of installer pages and components, reducing the need for manual scripting by providing a structured graphical interface. Developers can define installation elements intuitively without deep knowledge of the Pascal-based scripting language, facilitating the generation and compilation of .iss files for Windows applications. This free tool, available via donation-supported downloads, integrates seamlessly with the Inno Setup compiler to produce customized installers.[57]
The Inno Setup Dependency Installer automates the detection, download, and installation of required runtimes such as .NET Framework, Visual C++ Redistributables, or SQL Server Express during the setup process, ensuring application compatibility without user intervention. This extension uses Inno Setup scripts and Pascal code to handle dependencies dynamically, supporting both 32-bit and 64-bit architectures. Hosted on GitHub, it is widely adopted for simplifying deployments of software with external prerequisites.[58]
Other notable extensions include community-driven collections like the Inno Setup Extensions (ISX) repository, which offers additional components for tasks such as enhanced file handling and UI modifications. Community scripts, often shared on GitHub and forums, address specific needs like web-based updates by checking for new versions online and prompting downloads during installation. For instance, scripts can integrate HTTP requests to verify application updates against a server.[55][59]
Modern integrations include the Inno Setup extension for Visual Studio Code, offering syntax highlighting, auto-completion, and compilation support within the editor.[60]
Integration examples demonstrate how these extensions pair with GitHub for version control of .iss files, allowing collaborative editing and automated builds via GitHub Actions to compile installers directly from repository changes. The official Inno Setup source code, maintained on GitHub, further encourages such workflows by providing pre-configured continuous integration setups.[4]
Licensing
License Terms
Inno Setup is governed by the Inno Setup License, a permissive open-source license that grants users the right to use, modify, and redistribute the software for any purpose, including commercial applications, without requiring royalties, runtime fees, or mandatory payments.[61] The license provides perpetual access to any downloaded versions of the software, ensuring long-term usability without expiration or recurring costs.[61]
Since its inception, Inno Setup has been open-source, with the full source code hosted on GitHub under the jrsoftware/issrc repository, facilitating community contributions, modifications, and redistribution while preserving the project's collaborative development model.[4] Redistributions in source code form must retain all existing copyright notices and license conditions without alteration, and binary distributions must include the original copyright notices and the jrsoftware.org website address.[61]
Attribution requirements under the license are minimal: users must not misrepresent the origin of the software or modified versions, which should be clearly marked as such, but formal acknowledgment in product documentation—such as crediting original author Jordan Russell—is appreciated though not obligatory.[61] The license operates on a voluntary donation model to support ongoing development, where contributions are encouraged for users seeking to aid the project but remain entirely optional for free use.[62] As of 2025, recent donors qualify for complimentary commercial licenses as a gesture of appreciation.[62]
Commercial Use
In version 6.5.0 of Inno Setup, released on August 12, 2025, the developers introduced an encouragement for commercial users to purchase a one-time perpetual license to support ongoing development and access professional support.[63][43]
This commercial license provides two years of major and minor updates following the purchase, after which users may continue using the version acquired at the time of purchase indefinitely.[62][7]
Pricing follows a single payment model, with options tailored for different scales: a single-user license at $150, a team license for 2-5 developers at $395, and an enterprise license for unlimited users at $1,095; exact costs and ordering details are available on the official order page, which also includes local taxes and a 30-day money-back guarantee.[62]
Inno Setup remains freely available for all uses, including commercial, with no enforcement of the commercial license requirement, though purchases and donations from any users help sustain the project.[1][63]
The initiative aims to ensure long-term sustainability for the project's maintainers, Jordan Russell and Martijn Laan, by funding improvements and maintenance efforts.[1][64]
Security Considerations
Known Vulnerabilities
Inno Setup, a widely used tool for creating Windows installers, has documented security weaknesses primarily related to its handling of dynamic link libraries (DLLs) and search paths, which can enable local privilege escalation or code execution if exploited. These vulnerabilities stem from the installer's reliance on Windows' DLL loading mechanisms without sufficient safeguards against untrusted paths. A key example is the uncontrolled search path vulnerability identified in all versions of Inno Setup, classified under CWE-427 (Uncontrolled Search Path Element), which allows attackers to manipulate the environment for DLL hijacking by placing malicious libraries in directories searched by the installer.[65]
In 2017, CVE-2017-20051 was assigned to a problematic functionality in the Inno Setup installer that exposes it to uncontrolled search path manipulation, potentially leading to the execution of arbitrary code during installation. This issue affects the core extraction and loading processes, where the installer fails to verify the integrity of libraries loaded from non-privileged directories, such as the current working directory or temporary folders. The vulnerability has a CVSS v3.1 base score of 7.8 (high severity) and is exploitable remotely if users run a crafted installer, though it requires local system access for full impact.[65][66]
Historical analyses have highlighted similar DLL hijacking risks in earlier versions, where Inno Setup extracts components like _ShFolder.dll and temporary subinstallers (e.g., is-*.tmp) to insecure locations such as %TEMP%\is-.tmp, allowing unprivileged users to overwrite these files with malicious DLLs like UXTheme.dll. This enables privilege escalation, as installers often request administrative rights via the "requireAdministrator" manifest, loading rogue libraries from the application's startup directory (e.g., Downloads). Affected versions include those up to Inno Setup 5.5.6 and extend to later releases like 6.x due to persistent search order flaws, as confirmed in security advisories from 2015.[67]
These inherent weaknesses, including risks from unsanitized inputs in file operations (aligning with CWE-73: External Control of File Name or Path) and insecure temporary file creation (CWE-378: Creation of Temporary File With Insecure Permissions), have facilitated directory traversal (CAPEC-13) and search order hijacking (CAPEC-471) in early versions. Additionally, untrusted search paths contribute to broader code execution risks (CWE-426: Untrusted Search Path).[68][69][70][71]
Beyond technical flaws, Inno Setup has been frequently abused in malware campaigns from 2023 to 2025, where attackers embed malicious Pascal scripts within legitimate-looking installers to deliver payloads. A notable instance occurred in July 2025, when cybercriminals used Inno Setup to distribute the RedLine stealer, leveraging obfuscated scripts for multi-stage attacks that retrieve and execute next-stage malware like HijackLoader, targeting browser credentials and cryptocurrency wallets. This exploitation underscores the risks of code injection via unsanitized scripting inputs (CWE-427), with multiple reported campaigns in 2025 alone disguising infostealers as benign software updates.[72][73]
Best Practices for Secure Installers
When building installers with Inno Setup, implementing robust input validation in Pascal scripts is essential to mitigate risks such as command injection. Developers should use parameterized paths for file operations and sanitize any user-provided inputs—such as directory selections or custom parameters—before incorporating them into script logic, ensuring they conform to expected formats and do not contain executable characters or sequences. This approach prevents malicious inputs from altering script behavior, particularly when combined with functions like Exec or ShellExec that invoke external processes.[74][75]
Digitally signing installers enhances trust and verifies integrity, reducing the likelihood of users encountering warnings about unknown publishers. Configure the SignTool directive in the [Setup] section to integrate with tools like SignTool.exe from the Windows SDK, applying certificates from trusted authorities such as DigiCert or Sectigo. Additionally, since version 6.5, Inno Setup supports signature verification for downloaded files and extractions, allowing scripts to check digital signatures of dependencies before proceeding with installation to prevent tampering. Always verify certificates against revocation lists during the signing process.[15][43]
Auditing Pascal scripts is a critical step to identify and eliminate potential vulnerabilities in the [Code] section. Avoid constructing commands dynamically from untrusted sources, as this can lead to unintended execution; instead, hardcode or validate parameters explicitly. Thoroughly review uses of high-risk functions like Exec and ShellExec, ensuring their arguments are static or properly escaped to block arbitrary code execution, and test scripts in isolated environments to detect anomalous behavior.[74][75]
For installers containing sensitive data, enable encryption via the Encryption directive in the [Setup] section, which protects compiled files using the XChaCha20 algorithm since version 6.4, derived with PBKDF2-HMAC-SHA256 for key strengthening. Set Encryption to "yes" for setup files only or "full" for the entire installation, requiring a strong password—at least 12 characters with mixed case, numbers, and symbols—passed via the /PASSWORD command-line parameter to avoid weak key derivation. This ensures data remains confidential even if the installer is intercepted.[20][21][76]
Maintaining security requires regular updates to the latest Inno Setup version, 6.6.0 as of November 2025, which includes enhancements for installer safety and reliability. Earlier versions addressed specific issues, such as DLL hijacking vulnerabilities fixed in 6.0.5, underscoring the importance of upgrading to patch known flaws. Additionally, before distribution, scan installers and dependencies with reputable antivirus tools to detect embedded malware signatures, and monitor for updates to third-party extensions used in the build process.[7][77][43]