#define UNICODE #define _UNICODE #include #include #include #include #include #include #include #include #include #pragma comment(lib, "userenv.lib") #pragma comment(lib, "ole32.lib") static bool GrantContainerFolderAccess(const std::wstring& path, PSID sid) { PACL oldDacl = nullptr; PSECURITY_DESCRIPTOR descriptor = nullptr; DWORD error = GetNamedSecurityInfoW( const_cast(path.c_str()), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nullptr, nullptr, &oldDacl, nullptr, &descriptor); if (error != ERROR_SUCCESS) return false; EXPLICIT_ACCESSW access{}; access.grfAccessPermissions = GENERIC_ALL; access.grfAccessMode = GRANT_ACCESS; access.grfInheritance = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; BuildTrusteeWithSidW(&access.Trustee, sid); PACL updatedDacl = nullptr; error = SetEntriesInAclW(1, &access, oldDacl, &updatedDacl); if (error == ERROR_SUCCESS) { error = SetNamedSecurityInfoW( const_cast(path.c_str()), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nullptr, nullptr, updatedDacl, nullptr); } if (updatedDacl) LocalFree(updatedDacl); if (descriptor) LocalFree(descriptor); return error == ERROR_SUCCESS; } static std::wstring QuoteArg(const std::wstring& value) { std::wstring out = L"\""; size_t slashes = 0; for (wchar_t ch : value) { if (ch == L'\\') { ++slashes; } else if (ch == L'\"') { out.append(slashes * 2 + 1, L'\\'); out += ch; slashes = 0; } else { out.append(slashes, L'\\'); slashes = 0; out += ch; } } out.append(slashes * 2, L'\\'); out += L'\"'; return out; } static std::vector SafeEnvironmentBlock() { static const wchar_t* const allowed[] = { L"ALLUSERSPROFILE", L"APPDATA", L"COMSPEC", L"HOMEDRIVE", L"HOMEPATH", L"LOCALAPPDATA", L"NUMBER_OF_PROCESSORS", L"OS", L"PATH", L"PATHEXT", L"PROCESSOR_ARCHITECTURE", L"PROCESSOR_IDENTIFIER", L"PROGRAMDATA", L"PROGRAMFILES", L"PROGRAMFILES(X86)", L"PUBLIC", L"SYSTEMDRIVE", L"SYSTEMROOT", L"TEMP", L"TMP", L"USERDOMAIN", L"USERNAME", L"USERPROFILE", L"WINDIR" }; std::vector entries; LPWCH inherited = GetEnvironmentStringsW(); if (!inherited) return {}; for (const wchar_t* item = inherited; *item;) { std::wstring entry(item); item += entry.size() + 1; size_t separator = entry.find(L'='); if (separator == std::wstring::npos || separator == 0) continue; std::wstring key = entry.substr(0, separator); bool keep = false; for (const wchar_t* candidate : allowed) { if (_wcsicmp(key.c_str(), candidate) == 0) { keep = true; break; } } if (keep) entries.push_back(std::move(entry)); } FreeEnvironmentStringsW(inherited); std::sort(entries.begin(), entries.end(), [](const std::wstring& left, const std::wstring& right) { return _wcsicmp(left.c_str(), right.c_str()) < 0; }); std::vector block; for (const auto& entry : entries) { block.insert(block.end(), entry.begin(), entry.end()); block.push_back(L'\0'); } block.push_back(L'\0'); if (entries.empty()) block.push_back(L'\0'); return block; } static void SetEnvironmentValue( std::vector& block, const std::wstring& key, const std::wstring& value) { std::vector entries; for (const wchar_t* item = block.data(); item && *item;) { std::wstring entry(item); item += entry.size() + 1; size_t separator = entry.find(L'='); if (separator == std::wstring::npos || _wcsicmp(entry.substr(0, separator).c_str(), key.c_str()) != 0) { entries.push_back(std::move(entry)); } } entries.push_back(key + L"=" + value); std::sort(entries.begin(), entries.end(), [](const std::wstring& left, const std::wstring& right) { return _wcsicmp(left.c_str(), right.c_str()) < 0; }); block.clear(); for (const auto& entry : entries) { block.insert(block.end(), entry.begin(), entry.end()); block.push_back(L'\0'); } block.push_back(L'\0'); } static bool FilesMatch(const std::wstring& leftPath, const std::wstring& rightPath) { HANDLE left = CreateFileW(leftPath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); HANDLE right = CreateFileW(rightPath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (left == INVALID_HANDLE_VALUE || right == INVALID_HANDLE_VALUE) { if (left != INVALID_HANDLE_VALUE) CloseHandle(left); if (right != INVALID_HANDLE_VALUE) CloseHandle(right); return false; } LARGE_INTEGER leftSize{}, rightSize{}; bool matches = GetFileSizeEx(left, &leftSize) && GetFileSizeEx(right, &rightSize) && leftSize.QuadPart == rightSize.QuadPart && leftSize.QuadPart >= 0 && leftSize.QuadPart <= 1024 * 1024; std::vector leftBytes(matches ? static_cast(leftSize.QuadPart) : 0); std::vector rightBytes(matches ? static_cast(rightSize.QuadPart) : 0); DWORD leftRead = 0, rightRead = 0; if (matches && !leftBytes.empty()) { matches = ReadFile(left, leftBytes.data(), static_cast(leftBytes.size()), &leftRead, nullptr) && ReadFile(right, rightBytes.data(), static_cast(rightBytes.size()), &rightRead, nullptr) && leftRead == static_cast(leftBytes.size()) && rightRead == static_cast(rightBytes.size()) && leftBytes == rightBytes; } CloseHandle(left); CloseHandle(right); return matches; } static DWORD RunContained( PSID appContainerSid, const std::wstring& command, const wchar_t* environment, const std::wstring& cwd, HANDLE job ) { SIZE_T attributeBytes = 0; InitializeProcThreadAttributeList(nullptr, 1, 0, &attributeBytes); if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return GetLastError(); auto* attributes = static_cast( HeapAlloc(GetProcessHeap(), 0, attributeBytes) ); if (!attributes) return ERROR_OUTOFMEMORY; if (!InitializeProcThreadAttributeList(attributes, 1, 0, &attributeBytes)) { DWORD error = GetLastError(); HeapFree(GetProcessHeap(), 0, attributes); return error; } SECURITY_CAPABILITIES security{}; security.AppContainerSid = appContainerSid; security.Capabilities = nullptr; security.CapabilityCount = 0; if (!UpdateProcThreadAttribute( attributes, 0, PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES, &security, sizeof(security), nullptr, nullptr)) { DWORD error = GetLastError(); DeleteProcThreadAttributeList(attributes); HeapFree(GetProcessHeap(), 0, attributes); return error; } STARTUPINFOEXW startup{}; startup.StartupInfo.cb = sizeof(startup); startup.StartupInfo.dwFlags = STARTF_USESHOWWINDOW; startup.StartupInfo.wShowWindow = SW_HIDE; startup.lpAttributeList = attributes; PROCESS_INFORMATION process{}; std::wstring commandLine = QuoteArg(L"C:\\Windows\\System32\\cmd.exe") + L" /d /s /c \"" + command + L"\""; std::wstring mutableLine = commandLine; constexpr DWORD flags = EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW | CREATE_SUSPENDED; BOOL created = CreateProcessW( L"C:\\Windows\\System32\\cmd.exe", mutableLine.empty() ? nullptr : &mutableLine[0], nullptr, nullptr, FALSE, flags, const_cast(environment), cwd.c_str(), &startup.StartupInfo, &process ); DWORD error = created ? ERROR_SUCCESS : GetLastError(); DeleteProcThreadAttributeList(attributes); HeapFree(GetProcessHeap(), 0, attributes); if (!created) return error; if (!AssignProcessToJobObject(job, process.hProcess)) { error = GetLastError(); TerminateProcess(process.hProcess, error); CloseHandle(process.hThread); CloseHandle(process.hProcess); return error; } ResumeThread(process.hThread); DWORD waitResult = WaitForSingleObject(process.hProcess, 30000); DWORD exitCode = ERROR_TIMEOUT; if (waitResult == WAIT_OBJECT_0) { GetExitCodeProcess(process.hProcess, &exitCode); } else { TerminateJobObject(job, ERROR_TIMEOUT); } CloseHandle(process.hThread); CloseHandle(process.hProcess); return exitCode; } int wmain() { wchar_t tempPath[MAX_PATH]{}; if (!GetTempPathW(MAX_PATH, tempPath)) return 10; GUID id{}; if (FAILED(CoCreateGuid(&id))) return 11; wchar_t idText[40]{}; if (StringFromGUID2(id, idText, 40) == 0) return 12; std::wstring nonce = idText; if (!nonce.empty() && nonce.front() == L'{') nonce.erase(nonce.begin()); if (!nonce.empty() && nonce.back() == L'}') nonce.pop_back(); std::wstring profileName = L"SovereignAIProbe" + nonce; std::wstring secretPath = std::wstring(tempPath) + L"SovereignAIProbe" + nonce + L".txt"; std::wstring writePath = std::wstring(tempPath) + L"SovereignAIProbe" + nonce + L"-write.txt"; const char marker[] = "host-secret-must-stay-private"; HANDLE secret = CreateFileW(secretPath.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, nullptr); if (secret == INVALID_HANDLE_VALUE) return 13; DWORD bytesWritten = 0; if (!WriteFile(secret, marker, sizeof(marker) - 1, &bytesWritten, nullptr) || bytesWritten != sizeof(marker) - 1) { CloseHandle(secret); return 14; } CloseHandle(secret); PSID appContainerSid = nullptr; HRESULT profileResult = CreateAppContainerProfile( profileName.c_str(), L"SovereignAI isolated command probe", L"Temporary test profile for command isolation", nullptr, 0, &appContainerSid); if (FAILED(profileResult)) { fwprintf(stderr, L"CreateAppContainerProfile failed: 0x%08lx (Win32 %lu)\n", static_cast(profileResult), static_cast(HRESULT_CODE(profileResult))); DeleteFileW(secretPath.c_str()); return static_cast(HRESULT_CODE(profileResult)); } LPWSTR sidText = nullptr; PWSTR appContainerFolder = nullptr; bool appContainerPathReady = ConvertSidToStringSidW(appContainerSid, &sidText) && SUCCEEDED(GetAppContainerFolderPath(sidText, &appContainerFolder)); if (!appContainerPathReady) { FreeSid(appContainerSid); DeleteAppContainerProfile(profileName.c_str()); DeleteFileW(secretPath.c_str()); return 16; } if (sidText) LocalFree(sidText); HANDLE job = CreateJobObjectW(nullptr, nullptr); JOBOBJECT_EXTENDED_LIMIT_INFORMATION limits{}; limits.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_ACTIVE_PROCESS | JOB_OBJECT_LIMIT_JOB_MEMORY; limits.BasicLimitInformation.ActiveProcessLimit = 8; limits.JobMemoryLimit = 512ull * 1024 * 1024; bool jobReady = job && SetInformationJobObject( job, JobObjectExtendedLimitInformation, &limits, sizeof(limits)); auto environment = SafeEnvironmentBlock(); if (environment.empty()) return 15; std::wstring appDataPath(appContainerFolder); std::wstring appTempPath = appDataPath + L"\\Temp"; std::wstring sandboxWorkspacePath = appDataPath + L"\\agent-workspace"; std::wstring stagedInputPath = sandboxWorkspacePath + L"\\README.md"; std::wstring stagedCopyPath = sandboxWorkspacePath + L"\\staged-copy.md"; CreateDirectoryW(appTempPath.c_str(), nullptr); bool workspaceFolderReady = CreateDirectoryW(sandboxWorkspacePath.c_str(), nullptr) != FALSE || GetLastError() == ERROR_ALREADY_EXISTS; workspaceFolderReady = workspaceFolderReady && GrantContainerFolderAccess(sandboxWorkspacePath, appContainerSid); bool stagedInputCopied = workspaceFolderReady && CopyFileW(L"README.md", stagedInputPath.c_str(), FALSE); std::wstring curlPath = sandboxWorkspacePath + L"\\curl.exe"; bool curlCopied = workspaceFolderReady && CopyFileW(L"C:\\Windows\\System32\\curl.exe", curlPath.c_str(), FALSE); SetEnvironmentValue(environment, L"PATH", L"C:\\Windows\\System32"); SetEnvironmentValue(environment, L"APPDATA", appDataPath); SetEnvironmentValue(environment, L"LOCALAPPDATA", appDataPath); SetEnvironmentValue(environment, L"TEMP", appTempPath); SetEnvironmentValue(environment, L"TMP", appTempPath); std::wstring cwd = L"C:\\Windows\\System32"; DWORD shellResult = jobReady ? RunContained(appContainerSid, L"exit 0", environment.data(), cwd, job) : GetLastError(); std::wstring readAttempt = L"type " + secretPath + L" >nul 2>nul"; DWORD readResult = jobReady ? RunContained(appContainerSid, readAttempt, environment.data(), cwd, job) : ERROR_INVALID_HANDLE; std::wstring writeAttempt = L"echo modified>" + writePath + L" 2>nul"; DWORD writeResult = jobReady ? RunContained(appContainerSid, writeAttempt, environment.data(), cwd, job) : ERROR_INVALID_HANDLE; std::wstring allowedWritePath = sandboxWorkspacePath + L"\\probe-output.txt"; DWORD allowedWriteResult = jobReady && workspaceFolderReady ? RunContained(appContainerSid, L"echo contained>" + allowedWritePath, environment.data(), cwd, job) : ERROR_INVALID_HANDLE; std::wstring stagedFileUrl = L"file:///"; for (wchar_t ch : stagedInputPath) { stagedFileUrl += ch == L'\\' ? L'/' : ch; } DWORD stagedReadResult = jobReady && stagedInputCopied && curlCopied ? RunContained(appContainerSid, QuoteArg(curlPath) + L" --fail --silent " + stagedFileUrl + L" -o " + stagedCopyPath, environment.data(), cwd, job) : ERROR_INVALID_HANDLE; DWORD curlVersionResult = jobReady && curlCopied ? RunContained(appContainerSid, QuoteArg(curlPath) + L" --version", environment.data(), cwd, job) : ERROR_INVALID_HANDLE; DWORD curlNetworkResult = jobReady && curlCopied ? RunContained(appContainerSid, QuoteArg(curlPath) + L" --noproxy \"*\" --max-time 4 http://127.0.0.1:8100/health -o NUL", environment.data(), cwd, job) : ERROR_INVALID_HANDLE; DWORD attrs = GetFileAttributesW(writePath.c_str()); DWORD attrsError = attrs == INVALID_FILE_ATTRIBUTES ? GetLastError() : ERROR_SUCCESS; bool hostSecretPreserved = false; secret = CreateFileW(secretPath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (secret != INVALID_HANDLE_VALUE) { char check[sizeof(marker)]{}; DWORD bytesRead = 0; hostSecretPreserved = ReadFile(secret, check, sizeof(marker) - 1, &bytesRead, nullptr) && bytesRead == sizeof(marker) - 1 && memcmp(check, marker, sizeof(marker) - 1) == 0; CloseHandle(secret); } bool allowedWorkspaceWriteVisible = false; HANDLE allowedOutput = CreateFileW(allowedWritePath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (allowedOutput != INVALID_HANDLE_VALUE) { char contents[32]{}; DWORD count = 0; allowedWorkspaceWriteVisible = ReadFile(allowedOutput, contents, sizeof(contents) - 1, &count, nullptr) && count >= 9 && memcmp(contents, "contained", 9) == 0; CloseHandle(allowedOutput); } bool stagedInputRoundTripMatches = stagedInputCopied && FilesMatch( L"README.md", stagedCopyPath); if (job) CloseHandle(job); if (appContainerFolder) CoTaskMemFree(appContainerFolder); FreeSid(appContainerSid); DeleteFileW(curlPath.c_str()); DeleteFileW(stagedInputPath.c_str()); DeleteFileW(stagedCopyPath.c_str()); DeleteAppContainerProfile(profileName.c_str()); DeleteFileW(secretPath.c_str()); DeleteFileW(writePath.c_str()); DeleteFileW(allowedWritePath.c_str()); bool writeWasBlocked = attrs == INVALID_FILE_ATTRIBUTES && (attrsError == ERROR_FILE_NOT_FOUND || attrsError == ERROR_ACCESS_DENIED); wprintf(L"shell_exit=%lu\nread_host_file_exit=%lu\nwrite_host_file_exit=%lu\nhost_secret_preserved=%s\nwrite_artifact_absent=%s\n", shellResult, readResult, writeResult, hostSecretPreserved ? L"true" : L"false", writeWasBlocked ? L"true" : L"false"); wprintf(L"profile_write_exit=%lu\nprofile_write_visible=%s\n", allowedWriteResult, allowedWorkspaceWriteVisible ? L"true" : L"false"); wprintf(L"staged_copy_exit=%lu\nstaged_input_copied=%s\nstaged_roundtrip_matches=%s\n", stagedReadResult, stagedInputCopied ? L"true" : L"false", stagedInputRoundTripMatches ? L"true" : L"false"); wprintf(L"curl_version_exit=%lu\ncurl_local_health_exit=%lu\n", curlVersionResult, curlNetworkResult); if (!jobReady || shellResult != 0 || readResult == 0 || writeResult == 0 || !hostSecretPreserved || !writeWasBlocked || !workspaceFolderReady || allowedWriteResult != 0 || !allowedWorkspaceWriteVisible || !stagedInputCopied || stagedReadResult != 0 || !stagedInputRoundTripMatches || !curlCopied || curlVersionResult != 0 || curlNetworkResult == 0) return 20; return 0; }