diff --git a/.jules/sentinel.md b/.jules/sentinel.md
index c7a67127..1e80d3de 100644
--- a/.jules/sentinel.md
+++ b/.jules/sentinel.md
@@ -2,3 +2,7 @@
**Vulnerability:** CSV formula injection mitigation was naive, missing leading whitespace, tabs, and newlines.
**Learning:** Checking `/^[=+\-@]/` is not sufficient, as OWASP states that spaces and tabs before the formula triggers will also execute the formula in applications like Excel.
**Prevention:** Use a regex that allows leading whitespace (e.g. `/^[\s\uFEFF\xA0]*[=+\-@\t\r\n]/`) and include standalone tabs or new lines which are also injection vectors.
+## 2026-06-25 - Frontend Input Length Limit (DoS Mitigation)
+**Vulnerability:** The YouTube URL `` component in the desktop app lacked a `maxLength` attribute, potentially allowing users to paste excessively long strings, leading to UI thread lockups or memory exhaustion (Denial of Service).
+**Learning:** Even client-side inputs communicating with a secure backend should enforce length constraints at the DOM level to prevent resource exhaustion vulnerabilities and performance degradation.
+**Prevention:** Enforce length limits (e.g., `maxLength={2048}`) on all user-facing text `` components.
diff --git a/apps/desktop/src/App.test.tsx b/apps/desktop/src/App.test.tsx
index c039dfba..37082b8c 100644
--- a/apps/desktop/src/App.test.tsx
+++ b/apps/desktop/src/App.test.tsx
@@ -1089,6 +1089,12 @@ describe("App", () => {
});
});
+ it("enforces a maximum length on the YouTube URL input", () => {
+ render();
+ const input = screen.getByPlaceholderText(/YouTube URL.../i);
+ expect(input).toHaveAttribute("maxLength", "2048");
+ });
+
it("rejects non-http YouTube URL", async () => {
render();
const input = screen.getByPlaceholderText(/YouTube URL.../i);
diff --git a/apps/desktop/src/App.tsx b/apps/desktop/src/App.tsx
index 24f5fb09..7aa7e57f 100644
--- a/apps/desktop/src/App.tsx
+++ b/apps/desktop/src/App.tsx
@@ -609,6 +609,7 @@ export function App() {
disabled={analysisInFlight || isStarting || isImporting}
className="h-10 flex-1 border-0 bg-transparent text-slate-100 placeholder:text-slate-500 focus-visible:ring-cyan-300"
aria-label="YouTube URL"
+ maxLength={2048}
/>