Code Signing Best Practices
Want to keep your software and code safe?
Enter your contact information below below to receive your FREE Best Practices PDF:
PowerShell can be a very powerful tool for system administrators and developers alike. It helps you automate monotonous and time-consuming tasks and deliver better quality software faster. Last but not least, by code signing scripts, you can further integrate security into your organization’s development life cycle (i.e., DevSecOps).
But nothing is ever secure enough in cybersecurity. In fact, with 45% of attacks exploiting PowerShell scripts, code signing alone may just be not enough anymore. (Although it’s still better than not signing it at all!) This is where implementing PowerShell code signing best practices can really help.
So far, in our series of three articles dedicated to PowerShell you’ve learned:
Now, in this last article of the series, we’ll show you how to take the security of your scripts to the next level. Do you want to know how? Discover nine PowerShell script signing best practices that’ll provide your scripts with ultimate security in these turbulent times.
Did you know that the number of data breaches recorded by the Identity Theft Resource Center (ITRC) saw a 68% increase in 2021 compared to the previous year? Nowadays, any organization can fall victim to a cyber attack. It doesn’t matter whether you’re big or small, or if you have a full-fledged cyber security team — any organization can be a target for sensitive data-hungry hackers.
Don’t be discouraged, though. Implementing the following PowerShell script signing best practices will help you make a difference. Get ready to transform your day! Move from a major security breach that could cost your business money and reputation to “just another day at the office.” Now, enough with the theory and numbers. Let’s get down to business!
|1. Ensure You Have Installed the Latest PowerShell Version||Your version of PowerShell isn’t the latest? Take a few minutes to update it.|
|2. Timestamp Your Scripts||Add the following at the end of your Set-AuthenticodeSignature command:|
|3. Use a Trusted Code Signing Certificate||You can choose between:|
|4. Check Your Script Before Signing It|
|5. Use a Hardware Security Module (HSM)|
|6. Implement Signing Keys Policies|
|7. Don’t Sign All Your Scripts With the Same Key|
|8. Make Your Script Signing System Flexible|
|9. Log Your Script Signing Actions|
Ensuring that your software is up to date may seem obvious, but apparently, this isn’t always the case. The latest Ivanti report shows a 29% growth of unpatched vulnerabilities that caused a ransomware attack in 2021. Considering that Ivanti also reports that 91% of ransomware vulnerabilities remain unpatched, leaving a large attack surface for cybercriminals to target, this shows why bad guys love exploiting old vulnerabilities as much as the new ones.
Do you have the latest version of PowerShell installed on your machine? If you don’t, you should download it as soon as possible. You don’t want to miss the two PowerShell security updates released by Microsoft in the first eight months of 2022.
Not sure how to check the version of PowerShell installed on your device? It’s easy:
Your version of PowerShell isn’t the latest? Take a few minutes to update it.
Code signing certificates are a bit like dark chocolate: they expire after a set amount of time (in this case, a maximum of three years). However, just like how you can still eat dark chocolate after it’s expired, there’s also a way to extend the life of your certificate in one regard. How? By adding a timestamp when you first sign your script.
Timestamping your digital signature ensures that your users can still run it without getting a warning. This is because a timestamp adds the exact date and time when a digital signature was applied using a CA-issued (and, therefore, verifiable) code signing certificate.
Do you want to give it a try? Next time you sign your script with PowerShell, add the following at the end of your Set-AuthenticodeSignature command:
This is what it’ll look like with an example where the stand-in example text is replaced with real information:
Set-AuthenticodeSignature -FilePath C:\PS\powershell_script.ps1 -Certificate $cert -TimeStampServer https://timestamp.digicert.com
Make sure you replace:
Check to see whether your signing and timestamping were successful:
If it worked, the date and time of your signature should be visible under the Timestamp column, as shown in the graphic on the right.
Cool, huh? Don’t forget, though, that while timestamping will preserve the integrity of your signature after your certificate expires, you’ll still lose something. Yup! Like expired dark chocolate loses flavor, an expired code signing certificate loses the possibility to sign new scripts, even with timestamping.
In addition to costs, there’s another fundamental difference between self-signed code signing certificates and those issued by a trusted certificate authority (CA): the level of security and identity they offer.
Let’s check out the difference between a self-signed code signing certificate and a code signing certificate issued by a publicly trusted certificate authority (CA). First up is an example of a publicly trusted code signing certificate:
Now, let’s compare this to the usage information and subject details of a self-signed code signing certificate:
Which one would you trust more? I guess we both know the answer.
Self-signed can be an acceptable solution for internal testing environments as they don’t require high-security standards. However, they’re absolutely a no-go for scripts that’ll be available to the public. Why? Because, unlike a self-signed certificate, a CA-issued certificate:
Bottom line, do you want to secure your scripts? Do yourself and your organization a favor: get an OV or EV code signing certificate. Yes, it’ll cost you some money up front, but this investment in security will be money well spent as it may save you from a costly supply chain attack or data breach later on.
Prove Your Software Is Trustworthy
Signing your code shows users that your software and updates can be trusted.
Download our free code signing best practices eBook to learn how to help keep your supply chain secure and your company, customers & end-users safe.
Errors, unauthorized changes — anything could happen to your script before it’s ready to be released. How can you avoid all this?
Making mistakes when writing a script, no matter what language you’re using, it’s easy. Forget a comma there, type a word wrong here or simply name the variable you called $a as $A and you’re done. Instead of spending hours looking for the error or just signing your script without thoroughly checking it, make sure you scan it with PowerShell Script Analyzer (PSScriptAnalyzer). It’s a static code checker included in the Windows Management Framework. Once installed, you can:
Go through the common names of the available rules using the command
Get-ScriptAnalyzerRule | Sort-Object RuleName | Select-Object CommonName
Don’t forget to replace SCRIPT_PATH with the path to your script.
Did you receive no output after running the command?? That’s great! It means that your script syntax is perfect!
Do you want to sign a script you wrote a while ago or have you just finished writing it after spending weeks working on it? After checking it for syntax mistakes, ensure you also scan it for obfuscated scripts (i.e., malicious scripts that are very difficult to understand) or other modifications that could harm any device that runs it. How?
Use Windows Defender:
Or, if you have Windows 10, use Windows Antimalware Scan Interface (AMSI):
Remember! Your reputation and the security of your organization are on the line. You don’t want to be the one that brought your organization (or any customers’ organizations) down by signing a script that was modified without your knowledge.
Do you want to know more about obfuscation detection? Black Hat made a great video about it:
Four eyes (or more) can always see better than two. Before you release your script, ask at least one colleague to review and validate it. Do you have a PowerShell expert on your team? Ask him or her to go through your script and confirm that it’s ready to go. Make sure you include comments in your script so that every reviewer will be able to understand what it’s supposed to do.
Starting Nov.15, 2022, implementing this best practice will be even easier as OV code signing certificates will also be delivered via a secure hardware token, or you’ll have to store your keys on an approved HSM. The idea here is that using these devices will keep your cryptographic keys more away from prying eyes.
If you own an EV certificate, you should already be familiar with secure cryptographic hardware devices as one (usually in the form of a USB hardware security token) has been sent to you by the CA when you purchased the certificate. But these aren’t the only devices you can use to protect your keys. While hardware security tokens are intended for individual use, other crypto hardware, such as HSMs, are intended for use by authorized employees across your organization.
For example, an HSM as described by the National Institute of Standards and Technology (NIST), is a tamper-resistant and FIPS-validated device specifically designed to protect, process, and manage cryptographic keys. It allows the usage of keys without requiring employees to have direct access to them. Individual developers can also store their keys on hardware security tokens or trusted security modules on their individual devices.
Are some of your existing code signing certificate private keys stored elsewhere (e.g., on a computer)? Ensure you save them on an HSM. Once done, don’t forget to delete them from the computer they were originally stored on.
Now that your private keys are safe and sound, it’s time to double up on security and implement some strict signing keys policies. Which ones? Let’s find it out.
Think about it: does everyone in your organization really need to have access to all code signing keys at all times? Most definitely not. Therefore, make sure that you have access permissions and a policy that clearly explains:
This will minimize the risks of unauthorized access and script manipulation.
Every person who needs to digitally sign a script should use a strong authentication method (e.g., multi-factor authentication). But that’s not enough. To ensure that your scripts will be signed only using a device approved by your organization (e.g., a company laptop), you should add a policy requiring authentication of each device used to sign the code.
Why? This will make the life of an attacker more complicated as he’ll also have to hack one of your organization’s devices before being able to do anything with your script. Are you thinking of authenticating your machines via IP addresses? That isn’t sufficiently secure, either. Use a trusted platform module (.e.g., a microcontroller used to authenticate devices) instead.
A checksum is a unique value (i.e., a short string of alphanumeric characters) that can be used to check whether the original script has been altered. Adding a policy that requires your developers to publish your script’s checksums will give you the possibility for your users to verify the hashes and see whether they match.
Do you want an example? Check out any VMware’s product download page. You’ll see that it always includes the product’s checksum.
By adding a checksum, your users or customers will have a way to verify whether the file they downloaded is authentic and unaltered or has been tampered with. How? By comparing the two checksums using:
Do you want to know, for example, how a user can check an MD5 checksum using PowerShell? Discover how easy it is in our article “How to Check an MD5 Checksum.”
Do you have more than one signing key? Not all signing keys should be used for the same scripts and by the same people (more on this in a moment). Adding a specific policy to each different key, dictating how it should be used, will help you minimize errors and vulnerabilities. This will help minimize the risk of software supply chain attacks (wherein a hacker gets access to the code signing infrastructure and sign malware without needing to steal or directly access your keys).
Each policy should include guidance, such as:
Does your organization have employees living in other countries? You may also add the list of countries approved to use the key. These are just a few examples of policy specifications, of course. Make sure you pick or add regulations depending on your situation and needs.
Do you want more examples of key signing policies? Don’t miss NIST’s cybersecurity white paper on Security Considerations for Code Signing.
While using just one key for all your needs is cheaper and easier to manage, above all when time is tight and you can’t afford to waste even one minute looking for the right key, it’s often not a good idea. You’ll likely end up paying a much higher price than spending only a few extra minutes (and bucks) to get the right key.
So, how do you avoid key compromise-related issues?
It’s much safer to use the same key to sign one piece of software and its subsequent updates/patches, and another key to sign a different application and its subsequent updates and/or patches. Why?
Defining for your keys what the National Institute of Standard and Technology (NIST) calls a “cryptoperiod” will help you limit the time an attacker has to compromise your key. The longer each key is active, the more time will have an attacker to try to breach it. Even if there seems to be some kind of disagreement within the industry about rotation (e.g., whether to do it, and how frequently) NIST has issued some useful recommendations about it.
The maximum cryptoperiod of a certificate’s private signature key should:
“Things get damaged, things get broken,” says Depeche Mode’s song “Precious.” Algorithms are a bit like that, too. And once they’re broken by cybercriminals or deprecated, they have to be replaced with stronger ones. (Think of what happened to the SHA-1 algorithm a few years back.) This requires some flexibility and quick response capabilities.
Therefore, to make your code signing system as flexible (and secure) as possible, make sure:
If you have worked in cybersecurity long enough, you’ll know that logs and monitoring tools are your best friends. They’re incredible resources for efficiently addressing or preventing (e.g., nearly real-time event log monitoring) security incidents. So, what PowerShell code signing best practices can you implement to do that?
This is our list of the best nine PowerShell code signing best practices that we believe every IT administrator should know and use. Does implementing all of them sound, though? Maybe, but it’ll be well worth it when you consider all the time and headaches you’ll save yourself in the future.
Are you still not sure about it? Okay, let’s see if we can find a reason good enough to prove to you how important PowerShell script signing best practices can be for an organization…
I know what you’re thinking: Code signing may already be viewed as a burden on IT administrators and development teams. And you’re afraid that adding best practices and policies to it may just irritate them more and slow down the development and signing processes.
However, if implemented correctly, the best practices we’ve explored in this article will enable you to:
At the end of the day, it’ll be up to you if you want to put into practice what you’ve learned in this article. But remember, no pain no gain. With fileless malware attacks (attacks using legitimate system tools like PowerShell to execute a cyber attack) becoming more frequent, monitoring and protecting your script signings can be your only safety net.
These PowerShell code signing best practices should give you a foundation on how to further secure your scripts. It’ll help you extend your security radar beyond your code signing certificate by enabling you to cover other aspects of your entire script signing process.
A few of the PowerShell script signing best practices we’ve explored in our article include:
Use them all or pick the ones you prefer, it’s up to you. You got the power now. Design a super secure PowerShell code signing system that can handle all use cases and integrate with your organization’s tools and platforms by following our PowerShell code signing best practices. Ensure you secure your scripts against all the odds now!