Perl-Dist-Strawberry
Perl-Dist-Strawberry copied to clipboard
Binary distribution is unsigned
Security is important.
Looks like a duplicate of https://github.com/StrawberryPerl/Perl-Dist-Strawberry/issues/164
I also got a warning on the download as well - forgot to screenshot that.
Security is important. Please don't just ignore it. We are all coders here, most of us professional. There are so many laws and rules about the prohibitions of unsigned software in most workplaces, so it really is not acceptable for all of use to just ignore all of those.
Ignoring stuff like security is what entire cities get built on - the people who care most about security, are the ones who break it - so we should at least take the most basic steps to make their job harder...
See here, for anyone who's not sure what this all means: https://www.keyfactor.com/education-center/what-is-code-signing/
@gitcnd There's an actual recurring financial cost associated with registering package signing keys with microsoft, so a stronger case than "but this blog post / tweet / vuln scanner report said so" is strongly encouraged.
I did look for a non-paid option for singing binaries, but obviously a self-signed key is going to pop the same security warnings and a quick bing! for "free binary signing key for foss"-type program didn't turn up anything. On top of that there's also the issue of keeping said keys both secret and accessible to the build tooling.
Perhaps if you further explain the problem you're trying to solve there might be a solution that doesn't involve paying the windows tax? Perhaps a list of sums along with the release would be enough for you to be sure you're running a "legit" strawberry perl, for example?
Hello there,
maybe using SignPath is the solution and they supports GH Actions. A lot of OpenSource project are still using freely this service as exposed here: https://signpath.org/projects
@g-bougard looks super promising! There are a couple of snags: https://signpath.org/terms
- Sign your own binaries only - The team must only sign software artifacts built from their own source code.
This project doesn't contain the source for the perl interpreter. With some upsetting git tricks it might be possible to slurp and commit a snapshot of a tagged perl version's source
- All team members must use multi-factor authentication for both SignPath and source code repository access (e.g. GitHub).
- Assign code signing roles - The OSS project team must self-organize to create a team structure with clear responsibilities: Author, Reviewer, Approvers
That's a lot of org structure, though I'm sure it's worth it for not having to try and maintain a CA.
It's possible that I'm reading their terms to mean the least convenient thing possible, but that's generally the best way to read policy documents
There is also the possibility of having the Perl Foundation pay for the certificates. I don't want to go against the terms or do some shenanigans to "work-around" clear terms.
Either way, having someone work with us to update our Wix configuration to include the certs and clean up some other things is still a pain point we need to overcome.
@genio The point of the requirement is that you can look at a single place to see where the binary came from, and use your squishy human meat eyes to look for anything suspicious in the commits leading up to the release. (I guess also that you can build it yourself for comparison).
I'd say committing the perl source into the repo would be complying with the requirement, rather than trying to evade it.
We would have to pull in more than just Perl. The point I'm making is that we would have a repository so outrageously large that it would be impossible to work with. We ship more than "Just Perl". We cannot adhere to those terms.
Are certs expensive? Within reason, I'll send you the money if you want to sort out the tech. (when I used to ship perl2exe binaries, I was using tucows, which I think was just $100)
Imho, "just" forking perl repo into StrawberryPerl orga and adapt build processes to use the fork could be sufficient to adhere the terms. The question could probably be discusses with SignPath and maybe they simply would accept the project as is and as StrawBerryPerl is referenced by perl.org donwload page. Indeed I discover that possible solution finding this ImageMagick #6826 issue. There, you have @stefan-wenig (sorry for the ping Stefan but maybe you have yourself some answers O:)) from SignPath who commented and tell it's possible to contact them on [email protected].
About actual cost for code-signing certificate, I think it's around ~300$/year.
@genio Having the Perl Foundation as sponsor would be of course the best solution.
Either way, having someone work with us to update our Wix configuration to include the certs and clean up some other things is still a pain point we need to overcome.
I implemented code-signing few years ago in glpi-agent project which uses Perl::Dist::Strawberry for the building process (code-signing is actually disabled as we wasn't able to renew our code-signing certificate). Anyway I didn't have to integrate code-signing in Wix, I just had to add dedicated step in the GH Actions workflow.
P.S.: After some more thinking, maybe I made a mistake by forgetting to sign binaries: I think only the MSI was signed and that was sufficient for our purpose at that time.
Since I was mentioned a bit of background here:
- SignPath signs qualifying OSS projecs for free - that includes a free SignPath Foundation certificate
- You can sign the entire package (portable ZIP, MSI _and _ the EXE/DLL files within) in a single step using our GitHub action
- In order to be able do this we have to enforce certain rules for every build. These verifications require that you use GitHub Actions in a reproducable manner, ideally from the repository that contains the original source code.
@guest20 is right to wonder what this would mean for a Perl distribution. We'd probably have to work something out.
This project doesn't contain the source for the perl interpreter. With some upsetting git tricks it might be possible to slurp and commit a snapshot of a tagged perl version's source
Well there's obviously a term that says "dont work around the terms" ;-)
That's a lot of org structure, though I'm sure it's worth it for not having to try and maintain a CA.
We're working on reducing them as we increase the level of automated verification.
It's possible that I'm reading their terms to mean the least convenient thing possible, but that's generally the best way to read policy documents
As you should. However, there is always a dregree of risk in upstream dependencies, and we're not a point where this can be fully avoided for any reasonably complex project. In your case that's a lot of upstream, but since Perl is not any upstream project I believe it's worth a closer look. /cc @paulsavoie
It's not just Perl. We also ship a compiler, several libraries, etc. I don't think we can adhere to their terms with a project build that's so complex.
I get that from the outside it seems fairly cut and dry, but it really is a complex build system. If we were just building native Perl alone and not having to ship all of the surrounding things, yes, it would be as easy as that. However, we are doing lots and lots and lots of other things that make shipping Strawberry possible. When we eventually move to a Microsoft native compiler build, we could probably revisit this as it would be muuuuuuch easier to adhere to their terms.
@genio is spbuild the best way for me to build a perl on my own personal windows computer?
Just to clarify: Representing SignPath, I believe we can work something out. The requirement is not 100% reproducable builds up to the last indirect dependency. Every project includes unchecked libraries, that's just a reality today.
Our mission is to make software safer to build and use, so we have to weigh vague upstream risks vs. the risk of a major Perl distribution having an uncontrolled build process and being fully unsigned and unverifiable on the client side. We're not above making sensible compromises. It might also be an upportunity to work up the chain and adress each dependency's security at the root, eventually.
If you have a good overview of your major upstream dependencies and what you know about their respective security postures, that would be a good place to start. If you don't, maybe that's something that should be done anyway, code signing or not. Any large enough project runs the risk of shipping next XzUtils-like breach at some point.
Hi @genio
Either way, having someone work with us to update our Wix configuration to include the certs and clean up some other things is still a pain point we need to overcome.
I was thinking again about that comment you wrote. Now I understand few points, the first is why I myself had the only choice to only sign the glpi-agent MSI few years ago: I'm using GH Actions workflow to build and the full perl+modules building process can only fit in one GH Actions step and this still provides the MSI + portable build as zip archive. Then I was able to only sign the MSI in a following workflow step. If we take the example of SignPath, they should provide a way to create a dedicated step in the workflow. So if we want to be able to sign binaries before building the MSI packaging itself, we should probably just have to stop the building process after the compilation and cleaning steps. This way we can insert a GH Actions workflow step to sign binaries. And then we would have to start the remaining steps to generate the MSI and other archives and finalize the workflow with a step to sign the MSI. It should be possible to add one or 2 options support to stop after a given step and then restart to the following. Even having a Perl::Dist::Strawberry plugin class to insert a workflow "pause" could handle that purpose, just needing to restart the same script after binaries have been signed.
Do you think it make sens ?
I can eventually work on it as I still played with Perl::Dist::Strawberry plugin class for glpi-agent and as I'll probably have to use that in a near future for glpi-agent project.
SignPath will sign the whole thing inside out in one step, you just specify how. Only problem is to decide what you want to sign, as there's lots of upstream stuff (exe, dll, scripts) that can technically be signed at that stage but should probably be signed upstream.
Here's a sample definition signing what seems to be your EXE files + the MSI. It's on the strict side, avoiding wildcards and instead using parameters and metadata constraints. A bit redundant if you have the same stuff in PDL and MSI but that's about it.
<zip-file path="strawberry-perl.zip">
<msi-file path="strawberry-perl-${full-version}-64bit.msi">
<directory path="Strawberry/perl/bin">
<pe-file-set product-name="strawberryperl.com" product-version="${full-version}">
<include path="perl.exe" />
<include path="perl${short-version}.exe" />
<include path="wperl.exe" />
<for-each>
<authenticode-sign />
</for-each>
</pe-file-set>
</directory>
<authenticode-sign />
</msi-file>
<zip-file path="strawberry-perl-${full-version}-64bit-PDL.zip">
<directory path="perl/bin">
<pe-file-set product-name="strawberryperl.com" product-version="${full-version}">
<include path="perl.exe" />
<include path="perl${short-version}.exe" />
<include path="wperl.exe" />
<for-each>
<authenticode-sign />
</for-each>
</pe-file-set>
</directory>
</zip-file>
</zip-file>
It would be worth sleuthing whatever is the difference between signed binaries - sometimes they download without fuss, but a lot of the time chrome blocks them:
if we are going to the effort of signing, we may as well pick the method that chrome is happy with.
I think the installer(s) are the main thing needing to be signed. If an .exe gets infected after install, the user has bigger problems than a mere sig of ours on that .exe would have prevented.
Here is one exe I found recently that downloaded without security warning blocks when I got it:
sourceforge.net /projects/crystalmarkretro/files/1.0.2/CrystalMarkRetro1_0_2.exe/download
hmm. maybe not the best example - it looks kinda sketchy - but the main thing is this works properly from the users point of view:
Responding to @g-bougard's comment in https://github.com/StrawberryPerl/Perl-Dist-Strawberry/issues/238#issuecomment-2675427198
We can add a new step to Perl::Dist::Strawberry to sign things, possibly skipping already signed files.
The main thing to address that I see is the timeouts on GH actions. The build process takes more than six hours so we'd need to subdivide pause the process at some step, save the state, and then restart in a new GH actions step. It's all possible as build checkpoints are already supported, but it will take a little effort to sort out.
There are also sometimes differences between running on a local machine and running under a docker instance (e.g. #60) but we can account for them when they are known.
It would be worth sleuthing whatever is the difference between signed binaries - sometimes they download without fuss, but a lot of the time chrome blocks them:
Depends on the browser. After the download it will still have the mark-of-the-web which triggers Windows SmartScreen. There's a lot of undocumented heuristics going on, but basically you don't get blocked if
- you're downloading a well-known binary (changes with every version)
- you're downloading a binary signed with a well-known certificate
- or you're signing with an Extended Validation (EV) certificate
We're currently looking into issuing EV certificates to OSS projects since certificates are now only issued for one year, and the time Windows needs to break in a new one is annoying for users.
@shawnlaffan
The main thing to address that I see is the timeouts on GH actions. The build process takes more than six hours so we'd need to subdivide pause the process at some step, save the state, and then restart in a new GH actions step
Or you just do the signing asynchronously after the build. If signing is the last step in your workflow, that's as simple as setting wait-for-completion to false https://about.signpath.io/documentation/trusted-build-systems/github#usage
Or you just do the signing asynchronously after the build. If signing is the last step in your workflow, that's as simple as setting
wait-for-completiontofalsehttps://about.signpath.io/documentation/trusted-build-systems/github#usage
Thanks @stefan-wenig
The issue here is more the time the overall build process takes, which is more than six hours. This means GH actions will time out before completion if we try to build the system in a single workflow. It's not a show-stopper, just something we need to work around. It's also not a new issue in general so we should be able to adapt processes from other projects.
Thanks @shawnlaffan for the point.
Yes, 6 hours is really an issue. Here maybe Perl::Dist::Strawberry module "Step" concept is not adapt to GH Actions processing. I think, but maybe I'm wrong, some steps can be run in parallel using GH Actions features for that. Or some steps could be run in a single GH Actions step. For that we may just need a way (I guess as launching options) to request processing until a given step and then being able to continue to next break point.
For glpi-agent, the process is approximately taking 30 minutes, but I only build a short perl modules subset. Also I'm using GH Actions caching so some parts don't need to be built on each run. But I guess this will be difficult to decide if we can cache or not. Maybe having an option to generate a checksum value for each step telling if we can use a previous build which used the same checksum value.
Anyway, I think we have to be able to pause the build to process binaries signing on the ones we generated, than continue and finally sign the MSI after all the steps has been processed.
@g-bougard - the build system supports restarting from a completed step so that's easy enough. We can either cache and restore the partial builds or use some other process to store and access build artefacts. The main sticking point is just finding the tuits.
That said, I ran a build yesterday and it took about 3-4 hours for a build that did not include the PDL step. That was on a decent machine but we might still be OK on GH runners. (It also skipped the perl tests but they'd already been checked with earlier debug runs).
Has anyone tried a github attest-build-provenance workflow?
https://github.com/actions/attest-build-provenance
Hi @shawnlaffan
as far I understand attest-build-provenance workflow only permits to use a command to verify the provenance of a binary. This seems not a way to sign a binary like signtool does. But I'm definitively not an expert for this GH action.
For you to know, we finally managed to purchase a USB token to sign binaries for our glpi-agent project. I modified our windows build process which is based on Perl-Dist-Strawberry to sign our built perl, modules DLLs and the MSI package. As I said before, I build all of them in GH Actions. Actually, the token is on a dedicated computer at home with a ssh server configured and secured to only sign binaries and MSI sent from our GH Actions. The dedicated computer is a linux and sign code using osslsigncode command. This is complex but this works.
This surely can be included in a local build process for really long building process. The main problem will still be to find a generous donator/contributor for the Code-Signing certificate. I still can help to include the required steps.