|
4 | 4 |
|
5 | 5 | import { SAMLValidateRequest, CASValidateResult } from "./types"; |
6 | 6 |
|
| 7 | +/** |
| 8 | + * Maximum XML input size to prevent ReDoS attacks |
| 9 | + * 1MB should be more than enough for any valid CAS/SAML response |
| 10 | + */ |
| 11 | +const MAX_XML_SIZE = 1024 * 1024; |
| 12 | + |
7 | 13 | /** |
8 | 14 | * Simple XML tag extraction (without full XML parser dependency) |
9 | 15 | */ |
@@ -60,7 +66,7 @@ function extractAttribute( |
60 | 66 | export function parseSamlValidateRequest( |
61 | 67 | xml: string, |
62 | 68 | ): SAMLValidateRequest | null { |
63 | | - if (!xml) return null; |
| 69 | + if (!xml || xml.length > MAX_XML_SIZE) return null; |
64 | 70 |
|
65 | 71 | // Extract ticket from AssertionArtifact |
66 | 72 | const ticket = extractTagContent(xml, "AssertionArtifact"); |
@@ -95,11 +101,11 @@ function unescapeXml(str: string): string { |
95 | 101 | * Parse CAS serviceValidate response |
96 | 102 | */ |
97 | 103 | export function parseServiceValidateResponse(xml: string): CASValidateResult { |
98 | | - if (!xml) { |
| 104 | + if (!xml || xml.length > MAX_XML_SIZE) { |
99 | 105 | return { |
100 | 106 | success: false, |
101 | 107 | code: "INVALID_RESPONSE", |
102 | | - message: "Empty response", |
| 108 | + message: !xml ? "Empty response" : "Response too large", |
103 | 109 | }; |
104 | 110 | } |
105 | 111 |
|
@@ -199,11 +205,11 @@ export function parseValidateResponse(response: string): CASValidateResult { |
199 | 205 | * Parse SAML validate response (for CAS SP) |
200 | 206 | */ |
201 | 207 | export function parseSamlValidateResponse(xml: string): CASValidateResult { |
202 | | - if (!xml) { |
| 208 | + if (!xml || xml.length > MAX_XML_SIZE) { |
203 | 209 | return { |
204 | 210 | success: false, |
205 | 211 | code: "INVALID_RESPONSE", |
206 | | - message: "Empty response", |
| 212 | + message: !xml ? "Empty response" : "Response too large", |
207 | 213 | }; |
208 | 214 | } |
209 | 215 |
|
@@ -273,11 +279,11 @@ export function parseProxyResponse( |
273 | 279 | ): |
274 | 280 | | { success: true; proxyTicket: string } |
275 | 281 | | { success: false; code: string; message: string } { |
276 | | - if (!xml) { |
| 282 | + if (!xml || xml.length > MAX_XML_SIZE) { |
277 | 283 | return { |
278 | 284 | success: false, |
279 | 285 | code: "INVALID_RESPONSE", |
280 | | - message: "Empty response", |
| 286 | + message: !xml ? "Empty response" : "Response too large", |
281 | 287 | }; |
282 | 288 | } |
283 | 289 |
|
|
0 commit comments