Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
1 line
5.0 KiB
JSON
1 line
5.0 KiB
JSON
{"repo": "amirwopi/vpet-ultra", "files": {"VPet.Cognition.Security/SecurityInfrastructure.cs": {"e85df1c83e64b79b64b46f058aa19c419a2e6ab7": {"t": 1786068387.8670564, "n": 4720, "h": "a68fc498eeb21495", "c": "using System.Text.Json;\nusing Microsoft.Extensions.Logging;\n\nnamespace VPet.Cognition.Security;\n\n/// <summary>\n/// HTTP delegating handler that filters outbound requests to only allowlisted domains.\n/// Prevents SSRF and data exfiltration to unauthorized endpoints.\n/// </summary>\npublic sealed class EgressFilterHandler : DelegatingHandler\n{\n private readonly HashSet<string> _allowlist;\n private readonly ILogger<EgressFilterHandler> _logger;\n\n // Default allowlist for known AI providers\n private static readonly string[] DefaultAllowlist =\n {\n \"localhost\", \"127.0.0.1\", \"0.0.0.0\",\n \"api.openai.com\", \"api.deepseek.com\",\n \"dashscope.aliyuncs.com\", \"open.bigmodel.cn\",\n \"huggingface.co\", \"cdn-lfs.huggingface.co\",\n \"cdn-lfs-us-1.huggingface.co\", \"cdn-lfs-eu-1.huggingface.co\",\n };\n\n public EgressFilterHandler(ILogger<EgressFilterHandler> logger, IEnumerable<string>? additionalAllowlist = null)\n {\n _logger = logger;\n _allowlist = new HashSet<string>(DefaultAllowlist, StringComparer.OrdinalIgnoreCase);\n if (additionalAllowlist is not null)\n {\n foreach (var domain in additionalAllowlist)\n _allowlist.Add(domain);\n }\n }\n\n protected override Task<HttpResponseMessage> SendAsync(\n HttpRequestMessage request, CancellationToken cancellationToken)\n {\n if (request.RequestUri is not null)\n {\n var host = request.RequestUri.Host;\n\n if (!_allowlist.Contains(host))\n {\n _logger.LogWarning(\"Egress blocked: {Host} not in allowlist. URL: {Url}\", host, request.RequestUri);\n return Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)\n {\n Content = new StringContent($\"Egress blocked: {host} not in allowlist\"),\n });\n }\n\n _logger.LogDebug(\"Egress allowed: {Host}\", host);\n }\n\n return base.SendAsync(request, cancellationToken);\n }\n}\n\n/// <summary>\n/// Resolves secrets from environment variables, with optional Windows DPAPI encryption.\n/// On Windows, secrets can be stored encrypted via ProtectedData (DPAPI).\n/// On Linux, secrets are read from environment variables only.\n/// </summary>\npublic sealed class SecretResolver\n{\n private readonly ILogger<SecretResolver> _logger;\n\n public SecretResolver(ILogger<SecretResolver> logger) => _logger = logger;\n\n /// <summary>\n /// Resolve a secret value. Supports ${ENV_VAR} syntax for environment variable expansion.\n /// </summary>\n public string Resolve(string value)\n {\n if (string.IsNullOrEmpty(value)) return value;\n\n // Expand ${ENV_VAR} syntax\n if (value.StartsWith(\"${\") && value.EndsWith(\"}\"))\n {\n var envVar = value[2..^1];\n var resolved = Environment.GetEnvironmentVariable(envVar);\n if (string.IsNullOrEmpty(resolved))\n {\n _logger.LogWarning(\"Environment variable '{Var}' not set; using empty string.\", envVar);\n return string.Empty;\n }\n _logger.LogDebug(\"Resolved secret from env var '{Var}'\", envVar);\n return resolved;\n }\n\n // Check if value looks like a base64-encoded DPAPI blob (Windows only)\n if (OperatingSystem.IsWindows() && value.StartsWith(\"dpapi:\"))\n {\n try\n {\n var base64 = value[5..];\n var encrypted = Convert.FromBase64String(base64);\n var decrypted = System.Security.Cryptography.ProtectedData.Unprotect(\n encrypted, null, System.Security.Cryptography.DataProtectionScope.CurrentUser);\n return System.Text.Encoding.UTF8.GetString(decrypted);\n }\n catch (Exception ex)\n {\n _logger.LogError(ex, \"Failed to decrypt DPAPI secret.\");\n return value;\n }\n }\n\n return value;\n }\n\n /// <summary>\n /// Encrypt a secret using Windows DPAPI (CurrentUser scope).\n /// Returns \"dpapi:base64data\" string.\n /// </summary>\n public string Encrypt(string plainValue)\n {\n if (!OperatingSystem.IsWindows())\n {\n _logger.LogWarning(\"DPAPI encryption not available on non-Windows; returning plain value.\");\n return plainValue;\n }\n\n var encrypted = System.Security.Cryptography.ProtectedData.Protect(\n System.Text.Encoding.UTF8.GetBytes(plainValue),\n null, System.Security.Cryptography.DataProtectionScope.CurrentUser);\n return \"dpapi:\" + Convert.ToBase64String(encrypted);\n }\n}"}}}} |