I have forked a project’s source code on GitHub. The program takes a private key as an input and that key must never leave the client. If I want to share a pre-built executable as a release it is essential that I can prove beyond reasonable doubt that it is built from the published source.

I have learned about how to publish the releases by using a Workflow in the GitHub actions such that GitHub itself will build the project and then repare a release draft with the built files as well as the file hashes…

However, I noticed that the release is first drafted, and at that point I have the option to manually swap the executable and the hashes. As far as I can tell, a user will not be able to tell if I swapped a file and its corresponding hashes. Or, is there a way to tell?

One potential solution that I have found is that I can pipe the output of the hashing both to a file that is stored and also to the publicly visible logs by using “tee”. This will make it such that someone can look through the logs of the build process and confirm that the hashes match the hashes published in the release.

Like this:

I would like to know whether:

  • There is already some built-in method to confirm that a file is the product of a GitHub workflow

  • The Github Action logs can easily be tampered by the repo owner, and the hashes in the logs can be swapped, such that my approach is still not good enough evidence

  • If there is another, perhaps more standard method, to prove that the executable is built from a specific source code.

  • pkulak@beehaw.org
    link
    fedilink
    arrow-up
    10
    ·
    2 years ago

    There’s a paper from like 30 years ago about how you can never verify an executable because you don’t know that your compiler isn’t doing something nefarious. And if you do know that somehow, you don’t know it about it’s compiler, and so on. Scary a stuff.

    • Max@nano.gardenOP
      link
      fedilink
      arrow-up
      2
      ·
      edit-2
      2 years ago

      Ooh, I think I found the paper!

      Oof:

      The actual bug I planted in the compiler would match code in the UNIX “login” command. The re- placement code would miscompile the login command so that it would accept either the intended encrypted password or a particular known password. Thus if this code were installed in binary and the binary were used to compile the login command, I could log into that system as any user

  • jet@hackertalks.com
    link
    fedilink
    English
    arrow-up
    7
    ·
    edit-2
    2 years ago

    Reproducible builds. And then multiple parties to confirm the build. So a reproducible build and then f Droid to build the product would allow people to have confidence that they have the right thing. But if people are truly concerned about security they should build it from the source directly and then verify that signature against your reproducible build

    • Max@nano.gardenOP
      link
      fedilink
      arrow-up
      2
      ·
      edit-2
      2 years ago

      Thanks! I am convinced now, I will learn how to create reproducible builds.

      My worry is that the build is run through npm, and I think that the dependencies rely on additional dependencies such as openssl libraries. I worry that it will be a lot of work to figure out what every npm dependency is, what libraries they depend on, and how to make sure that the correct versions can be installed and linked by someone trying to reproduce the build 10 years from now. So it looks like a difficult project, but I will read more about it and hopefully it is not as complicated as it looks!

      • jet@hackertalks.com
        link
        fedilink
        English
        arrow-up
        2
        ·
        2 years ago

        there are some excellent blogs/articles and books on it. Basically your entire build chain has to be tooled for reproducibility, so things like Rust are very good as a foundation.

  • JackbyDev@programming.dev
    link
    fedilink
    English
    arrow-up
    2
    ·
    2 years ago

    What’s your concern? If there was a lawsuit I believe I discovery they’d find you didn’t modify the release on GitHub, right?

    • Max@nano.gardenOP
      link
      fedilink
      arrow-up
      2
      ·
      2 years ago

      No, I’m not concerned about a lawsuit. It’s something that I want to do because I think that it is important. If I want to share tools with non-tech savvy people who are unable to build them from source, I want to be able to share these without anyone needing to “trust” me. The reproducible builds standards are a very nice idea, and I will learn how to implement them.

      But I still wonder whether my approach is valid or not - is printing the hash of the output executable during Github’s build process, such that it is visible in the workflow logs, very strong evidence that the executable in the release with the same hash was built by github through the transparent build process? Or is there a way a regular user would be able to fake these logs?

    • Max@nano.gardenOP
      link
      fedilink
      arrow-up
      0
      ·
      2 years ago

      If I understand this correctly, signify would allow someone to verify that the executable was built by me. But then they would still have to trust me, because I can also sign the malicious executable.

  • ReversalHatchery@beehaw.org
    link
    fedilink
    arrow-up
    0
    ·
    2 years ago

    I think you can even upload release files manually, independently of if you use actions or not, so it can never be guaranteed that it was built from the sources.

    The only way to verify this may be to build it again and see if the result matches the published bins, but if the project does not do reproducible builds, then it may not match even if it was genuine.

    • Max@nano.gardenOP
      link
      fedilink
      arrow-up
      0
      ·
      2 years ago

      I think you can even upload release files manually, independently of if you use actions or not, so it can never be guaranteed that it was built from the sources.

      True, but that’s why my current idea is the following:

      As part of the wortkflow, GitHub will build the executable, compute a few different hashes (sha256sum, md5, etc…), and those hashes will be printed out in the GitHub logs. In that same workflow, GitHub will upload the files directly to the release.

      So, if someone downloads the executable, they can compute the sha256sum and check that it matches the sha256 that was computed by github during the action.

      Is this enough to prove that executable they are downloading the same executable that GitHub built during that workflow? Since a workflow is associated a specific push, it is possible to check the source code that was used for that workflow.

      In this case, I think that the only one with the authority to fake the logs or mess with the source during the build process would be GitHub, and it would be really hard for them to do it because they would need to prepare in advance specifically for me. Once the workflow goes through, I can save the hashes too and after that both GitHub and I would need to conspire to trick the users.

      So, I am trying to understand whether my idea is flawed and there is a way to fake the hashes in the logs, or if I am over-complicating things and there is already a mechanism in place to guarantee a build.

      • ReversalHatchery@beehaw.org
        link
        fedilink
        arrow-up
        2
        ·
        2 years ago

        As long as maintainers can upload arbitrary files to a release, this is not enough, I think. There is no distinction between release files coming from the build process, and release files just uploaded by the maintainer.

        • Max@nano.gardenOP
          link
          fedilink
          arrow-up
          1
          ·
          2 years ago

          But, if during Github’s build process the sha156sum of the output binary is printed, and the hash matches what is in the release, isn’t this enough to demonstrate that the binary in the release is the binary built during the workflow?

  • noneabove1182@sh.itjust.works
    link
    fedilink
    arrow-up
    0
    arrow-down
    1
    ·
    2 years ago

    Besides the obvious of telling your users to build the exe, have you considered alternative distribution methods like docker?

    • Max@nano.gardenOP
      link
      fedilink
      arrow-up
      0
      ·
      2 years ago

      How does a docker distribution solve this problem? Is it because the build instructions are automated by the Dockerfile?

      • noneabove1182@sh.itjust.works
        link
        fedilink
        arrow-up
        0
        ·
        2 years ago

        When you make a docker image and push it to dockerhub all of the instructions it took appear there so it’s very transparent, also super easy for any person to build it themselves unlike executables, just download the Dockerfile and run a single command

        • Max@nano.gardenOP
          link
          fedilink
          arrow-up
          1
          ·
          2 years ago

          Ah. Cool. I was under the impression that docker images suffered from a similar issue - that one can’t verify that the image is built from the source. I’m happy to be mistaken about that.

          • noneabove1182@sh.itjust.works
            link
            fedilink
            arrow-up
            2
            ·
            2 years ago

            You could definitely do clever things to obfuscate what you’re doing, but it’s much easier to replicate building the image as there are no external dependencies, if you have docker installed then you can build any docker image