Add opt-in --fetch path for mwebd.exe Windows build
What changed, and why it matters
This commit adds an optional shortcut for Windows builds that downloads a pre-built 'mwebd.exe' program from the internet instead of compiling it from source. It checks the downloaded file against a published SHA-256 hash, but the download itself uses plain HTTPs and the source URL can be overridden by an environment variable. There is no claim in the commit that this fixes a security issue; it appears to be a build-convenience change.
Treat this as a build-hygiene change rather than a security patch. If using `--fetch`, ensure the release artifacts and checksums are served from a trusted, immutable source; consider pinning to a specific, signed release; and verify that the CI pipeline cannot be redirected by untrusted environment variables. Review whether the SHA-256 file should be fetched from a separate, trusted channel rather than the same URL as the binary.
Security signals we found
Downloads a pre-built executable from a configurable remote URL
SHA-256 checksum verification is performed against a checksum downloaded from the same remote origin
Environment variable `MWEBD_FETCH_BASE_URL` can redirect the download source
No code signing or signature verification is performed
No vendor statement of security relevance in commit or supplied references
Evidence from the diff
The patch introduces a --fetch path in build_standalone_mwebd_windows.dart. When MWEBD_FETCH=1 is set, the script downloads mwebd.exe and its .sha256 file from a GitHub releases URL (defaulting to the project’s own releases, but overridable via MWEBD_FETCH_BASE_URL). It then verifies the executable’s SHA-256 against the downloaded checksum. The default build path still compiles from the ltcmweb/mwebd repository at tag v0.1.8. The change centralizes the version string and reformats some process invocations.
Changed components
scripts/app_config/configure_stack_wallet.shtool/build_standalone_mwebd_windows.dartassets/windows/mwebd.exe (build output)Inspect captured patch +103 / −17
diff --git a/scripts/app_config/configure_stack_wallet.sh b/scripts/app_config/configure_stack_wallet.sh
index 3de44a6..c68de3f 100755
--- a/scripts/app_config/configure_stack_wallet.sh
+++ b/scripts/app_config/configure_stack_wallet.sh
@@ -53,7 +53,11 @@ dart "${APP_PROJECT_ROOT_DIR}/tool/gen_interfaces.dart" \
MWEBD_EXE_SHA256=""
if [[ "$1" == "windows" ]]; then
- dart "${APP_PROJECT_ROOT_DIR}/tool/build_standalone_mwebd_windows.dart"
+ if [[ "${MWEBD_FETCH:-0}" == "1" ]]; then
+ dart "${APP_PROJECT_ROOT_DIR}/tool/build_standalone_mwebd_windows.dart" --fetch
+ else
+ dart "${APP_PROJECT_ROOT_DIR}/tool/build_standalone_mwebd_windows.dart"
+ fi
MWEBD_EXE_SHA256="$(sha256sum "${APP_PROJECT_ROOT_DIR}/assets/windows/mwebd.exe" | awk '{print $1}')"
dart "${APP_PROJECT_ROOT_DIR}/tool/process_pubspec_deps.dart" \
"${PUBSPEC_FILE}" MWEBDEXE
diff --git a/tool/build_standalone_mwebd_windows.dart b/tool/build_standalone_mwebd_windows.dart
index 012c82f..3f8c178 100644
--- a/tool/build_standalone_mwebd_windows.dart
+++ b/tool/build_standalone_mwebd_windows.dart
@@ -1,8 +1,68 @@
import 'dart:io';
-Future<void> main() async {
+const _mwebdVersion = "v0.1.8";
+const _defaultFetchBaseUrl =
+ "https://github.com/cypherstack/stack_wallet/releases/download";
+
+Future<void> main(List<String> args) async {
final projectToolDir = File(Platform.script.toFilePath()).parent;
+ if (args.contains("--fetch")) {
+ await _fetchPrebuilt(projectToolDir);
+ } else {
+ await _buildFromSource(projectToolDir);
+ }
+}
+
+Future<void> _fetchPrebuilt(Directory projectToolDir) async {
+ final baseUrl =
+ Platform.environment["MWEBD_FETCH_BASE_URL"] ?? _defaultFetchBaseUrl;
+ final tag = "mwebd-$_mwebdVersion";
+
+ final winAssetsDir = Directory(
+ "${projectToolDir.parent.path}"
+ "${Platform.pathSeparator}assets"
+ "${Platform.pathSeparator}windows",
+ );
+ if (!(await winAssetsDir.exists())) {
+ await winAssetsDir.create(recursive: true);
+ }
+ final exePath = "${winAssetsDir.path}${Platform.pathSeparator}mwebd.exe";
+ final shaPath = "$exePath.sha256";
+
+ await _waitForProcess(
+ await Process.start(
+ "curl",
+ ["-fL", "-o", exePath, "$baseUrl/$tag/mwebd.exe"],
+ runInShell: true,
+ mode: ProcessStartMode.inheritStdio,
+ ),
+ );
+ await _waitForProcess(
+ await Process.start(
+ "curl",
+ ["-fL", "-o", shaPath, "$baseUrl/$tag/mwebd.exe.sha256"],
+ runInShell: true,
+ mode: ProcessStartMode.inheritStdio,
+ ),
+ );
+
+ final expected = (await File(
+ shaPath,
+ ).readAsString()).trim().split(RegExp(r"\s+")).first;
+ final actual = (await Process.run("sha256sum", [
+ exePath,
+ ], runInShell: true)).stdout.toString().trim().split(RegExp(r"\s+")).first;
+ if (expected.toLowerCase() != actual.toLowerCase()) {
+ stderr.writeln(
+ "mwebd.exe sha256 mismatch: expected $expected, got $actual",
+ );
+ exit(1);
+ }
+ await File(shaPath).delete();
+}
+
+Future<void> _buildFromSource(Directory projectToolDir) async {
// setup temp build dir
final tempBuildDir = Directory(
"${projectToolDir.path}"
@@ -15,12 +75,17 @@ Future<void> main() async {
// change working dir and clone mwebd
Directory.current = tempBuildDir;
- final clone = await Process.start("git", [
- "clone",
- "https://www.github.com/ltcmweb/mwebd.git",
- "--branch",
- "v0.1.8",
- ], runInShell: true, mode: ProcessStartMode.inheritStdio);
+ final clone = await Process.start(
+ "git",
+ [
+ "clone",
+ "https://www.github.com/ltcmweb/mwebd.git",
+ "--branch",
+ _mwebdVersion,
+ ],
+ runInShell: true,
+ mode: ProcessStartMode.inheritStdio,
+ );
await _waitForProcess(clone);
// change working dir and build mwebd.exe
@@ -33,23 +98,40 @@ Future<void> main() async {
if (Platform.isWindows && isCI) {
build = await Process.start(
"go",
- ["build", "-v", "-o", "../mwebd.exe", "github.com/ltcmweb/mwebd/cmd/mwebd"],
+ [
+ "build",
+ "-v",
+ "-o",
+ "../mwebd.exe",
+ "github.com/ltcmweb/mwebd/cmd/mwebd",
+ ],
environment: {"CGO_ENABLED": "1"},
runInShell: true,
mode: ProcessStartMode.inheritStdio,
);
} else if (Platform.isWindows) {
- build = await Process.start("wsl", [
- "bash",
- "-l",
- "-c",
- "GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc "
- "go build -v -o ../mwebd.exe github.com/ltcmweb/mwebd/cmd/mwebd",
- ], runInShell: true, mode: ProcessStartMode.inheritStdio);
+ build = await Process.start(
+ "wsl",
+ [
+ "bash",
+ "-l",
+ "-c",
+ "GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc "
+ "go build -v -o ../mwebd.exe github.com/ltcmweb/mwebd/cmd/mwebd",
+ ],
+ runInShell: true,
+ mode: ProcessStartMode.inheritStdio,
+ );
} else {
build = await Process.start(
"go",
- ["build", "-v", "-o", "../mwebd.exe", "github.com/ltcmweb/mwebd/cmd/mwebd"],
+ [
+ "build",
+ "-v",
+ "-o",
+ "../mwebd.exe",
+ "github.com/ltcmweb/mwebd/cmd/mwebd",
+ ],
environment: {
"GOOS": "windows",
"GOARCH": "amd64",
Why this scored 39/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.