diff --git a/.jules/sentinel.md b/.jules/sentinel.md index fbdd504..98a0444 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -22,3 +22,8 @@ **Vulnerability:** The `ImageLoader` and `VideoURLProvider` scripts validated and upgraded URLs to HTTPS in their string cache for comparisons, but failed to update the actual `VRCUrl` objects used for the download/playback requests. This meant the code *looked* secure (validating strings) but *acted* insecurely (requesting HTTP), creating a false sense of security and leaving users vulnerable to MITM attacks. **Learning:** Validating a shadow copy (cache) of data does not secure the source data. When using object wrappers (like `VRCUrl`), modifying the extracted value does not modify the object itself. Security upgrades must be applied to the actual objects used for operations. **Prevention:** Explicitly replace or upgrade the source objects (e.g., `predefinedUrls[i] = new VRCUrl(secureUrl)`) when sanitizing inputs, rather than just sanitizing the local variable used for logic checks. + +## 2025-05-22 - Prevent Content Spoofing via Fallback Logic +**Vulnerability:** `FindMatchingUrlIndex` contained a fallback mechanism that blindly mapped unknown URLs from external lists to existing, unrelated `VRCUrl` slots when `useGeneratedUrlData` was enabled. This allowed external configuration to apply arbitrary captions to pre-approved images, creating a spoofing vulnerability. +**Learning:** Convenience features (like "auto-mapping" or "cyclic assignment" for unmatched items) often undermine strict allowlist enforcement. "Fail Closed" means if an exact match isn't found, the operation must fail, not guess. +**Prevention:** Remove fallback logic that bypasses exact matching. Ensure that lookups against an allowlist return an error or empty result if the specific item is not found. diff --git a/Scripts/ImageLoader.cs b/Scripts/ImageLoader.cs index 092627a..e39dd83 100644 --- a/Scripts/ImageLoader.cs +++ b/Scripts/ImageLoader.cs @@ -457,19 +457,6 @@ private int FindMatchingUrlIndex(string urlToFind, int additionalCount = 0) } } - // If using generated data, we can use the cyclical assignment - if (useGeneratedUrlData) - { - // Use the next available predefined URL slot (cyclical) - int index = (_activeUrlIndices.Length + additionalCount) % urlCount; - - // Ensure the predefined URL at this index exists - if (index < _predefinedUrlStrings.Length && _predefinedUrlStrings[index] != null) - { - return index; - } - } - // Last resort: find any available predefined URL // REMOVED for security: preventing content spoofing. // If the URL is not found in the predefined list, we should NOT display a random image. diff --git a/Scripts/VideoURLProvider.cs b/Scripts/VideoURLProvider.cs index 376a9a4..6bd39c3 100644 --- a/Scripts/VideoURLProvider.cs +++ b/Scripts/VideoURLProvider.cs @@ -1040,35 +1040,6 @@ private int FindMatchingUrlIndex(string urlToFind, int additionalCount = 0) } } - // If using generated data, we can use the cyclical assignment - if (useGeneratedUrlData) - { - // Use the next available predefined URL slot (cyclical) - // Include additionalCount to account for items currently being batched - int index = (_activeUrlIndices.Length + additionalCount) % urlCount; - - // Ensure the predefined URL at this index exists - if (index < _predefinedUrlStrings.Length && _predefinedUrlStrings[index] != null) - { - // Check if this URL is already used - string newUrl = _predefinedUrlStrings[index]; - for (int j = 0; j < _activeUrlIndices.Length; j++) - { - int existingIndex = _activeUrlIndices[j]; - if (existingIndex < _predefinedUrlStrings.Length && _predefinedUrlStrings[existingIndex] != null) - { - if (_predefinedUrlStrings[existingIndex] == newUrl) - { - Debug.Log($"[VideoURLProvider] URL already exists in playlist, skipping duplicate: {newUrl}"); - return -1; // Skip adding duplicate - } - } - } - - return index; - } - } - // Last resort: find any available predefined URL // REMOVED for security: preventing content spoofing. // If the URL is not found in the predefined list, we should NOT display a random video.