| # Security Threat Model |
| |
| ## Asset Definition & Scope |
| |
| This threat model covers the **`Appsheet.DotNetFrameworkUriEscaping`** |
| repository |
| (`sso://gnocchi-internal/third_party/dot-net-framework-uri-escaping`), a C# |
| shared library targeting `.NET Standard 2.0`. The repository contains a custom |
| fork of Microsoft .NET Framework 4.6.2 Reference Source (`NetFrameworkUri.cs`) |
| configured to execute in legacy V2 quirks mode (RFC 2396). It provides |
| `NetFrameworkUri.EscapeDataString()` to escape query parameters identically to |
| legacy .NET Framework (notably preserving unreserved characters such as `(` and |
| `)`), which is utilized by AppSheet to verify cryptographic signatures on legacy |
| image URLs generated prior to AppSheet's migration to .NET Core. |
| |
| ## Prioritization Signals |
| |
| - **1P OSS:** No |
| - **1P Proprietary Shipped Software:** No (Server-side library powering |
| AppSheet cloud services) |
| - **High-Risk Code Surface:** Yes. Utilizes C# `unsafe` pointer operations, |
| stack allocations (`stackalloc`), raw buffer copying (`Buffer.BlockCopy`), |
| and custom Unicode surrogate/UTF-8 byte processing on untrusted external URL |
| strings. |
| - **Perimeter Exposure:** Yes (Exposed via AppSheet public-facing internet |
| service and customer endpoints). |
| - **Data Sensitivity:** Medium/High (Processes customer image URLs, query |
| parameters, HMAC/signature tokens, and customer data identifiers). |
| - **Untrusted Input Handling:** Yes (Consumes raw, untrusted URI strings and |
| query parameters from external HTTP requests). |
| - **Business Value:** Critical for preserving backwards compatibility and |
| security of AppSheet's legacy image URL signature verification pipeline, |
| preventing unauthorized access to customer image assets. |
| |
| ## Scanning Harness Prompts |
| |
| - Focus on pointer arithmetic, buffer boundary calculations, and array |
| allocations in `NetFrameworkUri.EscapeString` and |
| `NetFrameworkUri.EnsureDestinationSize`. Check for potential off-by-one or |
| integer overflow vulnerabilities when indexing characters, calculating |
| surrogate pair offsets (`pStr[i + count - 1]`), or converting UTF-8 bytes |
| (`Encoding.UTF8.GetBytes`). |
| - Inspect unsafe stack allocation `stackalloc byte[160]` |
| (`c_MaxUnicodeCharsReallocate * c_MaxUTF_8BytesPerUnicodeChar`) and verify |
| whether input strings with surrogate pairs or long sequences of non-ASCII |
| characters can cause buffer overruns in `Encoding.UTF8.GetBytes(pStr + i, |
| count, bytes, 160)`. |
| - Analyze surrogate pair handling (`0xD800` to `0xDBFF`) for malformed Unicode |
| inputs (e.g., truncated high surrogates, unpaired surrogates, non-shortest |
| form UTF-8) to ensure `UriFormatException` is reliably thrown without memory |
| corruption or infinite loops (`for (; count < maxSize && pStr[i + count] > |
| '\x7f'; ++count)`). |
| - Evaluate differential URI escaping/unescaping behavior between RFC 2396 (V2 |
| quirks mode) and modern RFC 3986 / .NET Core parsers to ensure that |
| canonicalization differences cannot be exploited for signature validation |
| bypass or request spoofing in downstream AppSheet components. |
| |
| ## Entry Points and Untrusted Inputs |
| |
| | Entry Point | Type | Trusted? | Validation | |
| | ---------------------------------------- | -------- | ---------- | -------------------- | |
| | `NetFrameworkUri.EscapeDataString(string | Public | No | Validates null, | |
| : stringToEscape)` : C# : (Untrusted : empty string, : |
| : : Static : query : surrogate pairs, : |
| : : Method : parameters : UTF-8 encodability, : |
| : : : and URLs : and enforces : |
| : : : from : `c_MaxUriBufferSize` : |
| : : : external : (65,520 chars) : |
| : : : users) : : |
| | `NetFrameworkUri.EscapeString(...)` | Internal | No (Raw | Enforces `end - | |
| : : Unsafe : string and : start < : |
| : : Static : substring : c_MaxUriBufferSize`; : |
| : : Method : bounds) : validates high/low : |
| : : : : surrogates and UTF-8 : |
| : : : : byte conversion : |
| |
| ## Trust Boundaries and Auth Assumptions |
| |
| - **Authentication**: None within this library (assumed to be invoked by |
| AppSheet backend during authentication and signature verification |
| pipelines). |
| - **Authorization**: None within this library. |
| - **Implicit trust**: The library assumes callers pass .NET string objects |
| within valid memory; however, the string content itself is treated as |
| completely untrusted. |
| - **Boundary crossings**: External user/client request → AppSheet HTTP edge / |
| API handler → `NetFrameworkUri.EscapeDataString` → Signature validator / |
| image storage fetcher. |
| |
| ## Sensitive Data Paths |
| |
| | Data Type | Source | Destination | Protection | |
| | ---------- | -------- | ---------------------------------- | -------------------- | |
| | Customer | External | `NetFrameworkUri.EscapeDataString` | In-memory | |
| : image URLs : client : -> Signature verification hash / : processing; input : |
| : & query : requests : HMAC engine : size limited by : |
| : parameters : : : `c_MaxUriBufferSize` : |
| | Image URL | External | Signature verification comparison | Processed in string | |
| : signatures : client : logic : / character buffers : |
| : & HMAC : requests : : : |
| : tokens : : : : |
| |
| ## Privileged Actions |
| |
| | Action | Location | Guard | |
| | -------------------- | --------------------------------------- | ------------------------------- | |
| | Unsafe stack | `NetFrameworkUri.EscapeString` | Fixed allocation size | |
| : allocation : : (`c_MaxUnicodeCharsReallocate * : |
| : (`stackalloc`) : : c_MaxUTF_8BytesPerUnicodeChar` : |
| : : : = 160 bytes); bounded by : |
| : : : `maxSize` calculation : |
| | Direct pointer | `NetFrameworkUri.EscapeString`, | Fixed pointer pins (`fixed | |
| : dereferencing & : `NetFrameworkUri.EnsureDestinationSize` : (char* pStr = input)`); bounded : |
| : traversal (`char*`, : : loop index and `prevInputPos` : |
| : `byte*`) : : tracking : |
| | Raw buffer copy | `NetFrameworkUri.EnsureDestinationSize` | Reallocation logic with | |
| : (`Buffer.BlockCopy`) : : `destPos << 1` byte count : |
| |
| ## Priority Review Areas |
| |
| 1. **Unsafe Pointer Manipulation and Buffer Resizing:** Verify bounds checks in |
| `NetFrameworkUri.EscapeString` and `NetFrameworkUri.EnsureDestinationSize` |
| under edge cases (e.g. repeated resizing, maximum buffer size, mixed ASCII |
| and non-ASCII sequences). |
| 2. **Malformed Unicode & Surrogate Pair Handling:** Review behavior when |
| processing lone high surrogates, lone low surrogates, or invalid UTF-8 byte |
| sequences at string boundaries (`count == 1 || count == end - i`). |
| 3. **V2 Quirks Differential & RFC 2396 Compliance:** Review the character sets |
| in `RFC2396UnreservedMarks` (`-_.~*'()!`) vs `RFC3986UnreservedMarks` |
| (`-_.~`) and ensure signature calculations in AppSheet cannot be |
| desynchronized between .NET Framework and .NET Core. |
| 4. **Denial of Service (DoS) via Exception Flooding or Buffer Limits:** Check |
| if large or invalid URI payloads (approaching `c_MaxUriBufferSize = 0xFFF0`) |
| can cause high CPU usage or excessive garbage collection. |