Add Fortify scanner THREAT_MODEL.md to dot-net-framework-url-escaping repo

Bug: b/548453908
Change-Id: I95af7b986241d794c09404030d5fd639ae2ce259
Reviewed-on: https://gnocchi-internal-review.git.corp.google.com/c/third_party/dot-net-framework-uri-escaping/+/314964
Reviewed-by: Trevor Ryland <tryland@google.com>
diff --git a/THREAT_MODEL.md b/THREAT_MODEL.md
new file mode 100644
index 0000000..81e987b
--- /dev/null
+++ b/THREAT_MODEL.md
@@ -0,0 +1,134 @@
+# 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.