diff --git a/app/components/file-details/vulnerability-analysis-details/findings/vulnerable-api/index.hbs b/app/components/file-details/vulnerability-analysis-details/findings/vulnerable-api/index.hbs index 9fb1861394..085d9c8f8e 100644 --- a/app/components/file-details/vulnerability-analysis-details/findings/vulnerable-api/index.hbs +++ b/app/components/file-details/vulnerability-analysis-details/findings/vulnerable-api/index.hbs @@ -24,24 +24,14 @@ {{/if}} {{/each}} - {{#if @currentVulnerability.request.body}} - {{#unless this.isRequestBodyEmpty}} - - {{t 'requestBody'}}: - - -
-
-            {{@currentVulnerability.request.body}}
-          
-
- {{/unless}} - {{/if}} + {{#unless this.isRequestBodyEmpty}} + {{@currentVulnerability.request.body}} + + {{/unless}} {{#unless this.isRequestHeadersEmpty}} {{/unless}} + {{#unless this.isRequestCookiesEmpty}} + {{#each-in @currentVulnerability.response.cookies as |key value|}}{{key}}: {{value}} + {{/each-in}} + + {{/unless}} + {{#if @currentVulnerability.response.status_code}} {{/unless}} + {{#unless this.isResponseCookiesEmpty}} + {{#each-in @currentVulnerability.response.cookies as |key value|}}{{key}}: {{value}} + {{/each-in}} + + {{/unless}} + {{#unless this.isResponseBodyEmpty}} ; } /** @@ -21,16 +24,9 @@ export interface VulnerableApiResponse { status_code: number; text: string; url: string; + cookies: Record; } -type VulnerableApiFindingSection = - | 'request' - | 'response' - | 'request-headers' - | 'response-headers' - | 'params' - | 'other'; - /** * Represents a finding of a vulnerability in an API. */ @@ -54,6 +50,7 @@ function initializeVulnerableApiFinding(): VulnerableApiFinding { method: '', params: { key: '', token: '' }, url: '', + cookies: {}, }, response: { headers: {}, @@ -61,6 +58,7 @@ function initializeVulnerableApiFinding(): VulnerableApiFinding { status_code: 0, text: '', url: '', + cookies: {}, }, severity: '', confidence: '', @@ -68,6 +66,35 @@ function initializeVulnerableApiFinding(): VulnerableApiFinding { }; } +function updateSection( + key: string, + currentSection: NestedKeyOf +): NestedKeyOf { + const sectionMap: Record> = { + request: 'request', + response: 'response', + headers: currentSection.startsWith('response') + ? 'response.headers' + : 'request.headers', + params: 'request.params', + severity: 'severity', + confidence: 'confidence', + url: currentSection.startsWith('response') ? 'response.url' : 'request.url', + method: 'request.method', + body: 'request.body', + text: 'response.text', + status_code: 'response.status_code', + reason: 'response.reason', + cookies: currentSection.startsWith('response') + ? 'response.cookies' + : 'request.cookies', + key: 'request.params.key', + token: 'request.params.token', + }; + + return sectionMap[key] || currentSection; +} + /** * Determines if a given content string contains information indicative of a vulnerable API finding. * @param content - The content string to check. @@ -142,9 +169,13 @@ function parseVulnerableApiFindingBlock(block: string): VulnerableApiFinding { const lines = block.split('\n'); const finding = initializeVulnerableApiFinding(); - let currentSection: VulnerableApiFindingSection = 'other'; + let currentSection: NestedKeyOf = 'confidence'; let currentHeaders: Record | null = null; + let currentCookies: Record | null = null; + let currentBuffer: string | null = null; + let currentKey: string | null = null; + // Process the first line separately to handle initial URL or description processFirstLine(lines, finding); lines.forEach((line) => { @@ -153,20 +184,51 @@ function parseVulnerableApiFindingBlock(block: string): VulnerableApiFinding { if (parsedLine) { const [key, value] = parsedLine; - const { updatedSection, updatedHeaders } = updateVulnerableApiFinding( - finding, - key, - value, - currentSection, - currentHeaders - ); - - // update the current section and headers - currentSection = updatedSection; - currentHeaders = updatedHeaders; + if (currentKey && currentBuffer) { + // If a previous key exists, update it with the accumulated buffer + updateFindingField(finding, currentKey, currentBuffer, currentSection); + currentBuffer = null; // Reset buffer after updating + currentKey = null; // Reset key after updating + } + + if (key) { + if (currentKey && currentBuffer) { + // Continue accumulating the value if the same key is detected + currentBuffer += `\n${value}`; + } else { + // If a new key is detected, update section and headers + const { updatedSection, updatedHeaders, updatedCookies } = + updateVulnerableApiFinding( + finding, + key, + value, + currentSection, + currentHeaders, + currentCookies + ); + + // Update current section and headers + if (updatedSection !== currentSection) { + currentSection = updatedSection; + } + + currentHeaders = updatedHeaders; + currentCookies = updatedCookies; + currentKey = key; // Track the current key + currentBuffer = value; // Start accumulating value + } + } + } else if (currentBuffer) { + // Continue accumulating the value if no new key is detected + currentBuffer += `\n${line}`; } }); + // Finalize any remaining buffer + if (currentBuffer && currentKey) { + updateFindingField(finding, currentKey, currentBuffer, currentSection); + } + return finding; } @@ -182,6 +244,14 @@ function parseLine(line: string): [string, string] | null { return null; } + // Split the line into key and value parts based on the first colon + const colonIndex = line.indexOf(':'); + + // If there's no colon, return null as it's not a valid key-value pair + if (colonIndex === -1) { + return null; + } + const value = valueParts.join(':').trim(); return [key.trim().toLowerCase(), value]; @@ -220,62 +290,6 @@ function processFirstLine( } } -/** - * Updates the severity and confidence fields of the finding based on the key-value pair. - * @param finding - The `VulnerableApiFinding` object to update. - * @param key - The key indicating the type of information (`severity` or `confidence`). - * @param value - The value to set. - */ -function updateFindingSeverityAndConfidence( - finding: VulnerableApiFinding, - key: string, - value: string -): void { - if (key === 'severity') { - finding.severity = value; - } else if (key === 'confidence') { - finding.confidence = value; - } -} - -/** - * Updates the current section of the finding based on the key. - * @param key - The key indicating the section to update. - * @param currentSection - The current section of the finding. - * @returns The updated section of the finding. - */ -function updateSection( - key: string, - currentSection: VulnerableApiFindingSection -): VulnerableApiFindingSection { - switch (key) { - case 'request': - case 'method': - return 'request'; - - case 'response': - case 'reason': - case 'text': - case 'status_code': - return 'response'; - - case 'headers': - return currentSection === 'response' - ? 'response-headers' - : 'request-headers'; - - case 'params': - return 'params'; - - case 'severity': - case 'confidence': - return 'other'; - - default: - return currentSection; - } -} - /** * Updates a specific field in the `VulnerableApiFinding` based on the current section. * @param finding - The `VulnerableApiFinding` object to update. @@ -287,18 +301,14 @@ function updateFindingField( finding: VulnerableApiFinding, key: string, value: string, - currentSection: VulnerableApiFindingSection + currentSection: NestedKeyOf ): void { - const isRequestSection = currentSection === 'request'; - const isResponseSection = currentSection === 'response'; - const isParamsSection = currentSection === 'params'; + const isRequestSection = currentSection.startsWith('request'); + const isResponseSection = currentSection.startsWith('response'); + const isParamsSection = currentSection.startsWith('request.params'); - if (key === 'body') { - if (isRequestSection) { - finding.request.body = value; - } else if (isResponseSection) { - finding.response.text = value; - } + if (key === 'body' && isRequestSection) { + finding.request.body = value; } else if (key === 'url') { if (isRequestSection || isParamsSection) { finding.request.url = value; @@ -311,15 +321,19 @@ function updateFindingField( finding.response.status_code = Number(value); } else if (key === 'reason' && isResponseSection) { finding.response.reason = value; + } else if (key === 'text' && isResponseSection) { + finding.response.text = value; + } else if (key === 'severity') { + finding.severity = value; + } else if (key === 'confidence') { + finding.confidence = value; + } else if (key === 'key' && isParamsSection) { + finding.request.params.key = value; + } else if (key === 'token' && isParamsSection) { + finding.request.params.token = value; } } -/** - * Updates the headers of the finding based on the current section. - * @param currentHeaders - The current headers to update. - * @param key - The key of the header. - * @param value - The value of the header. - */ function updateFindingHeaders( currentHeaders: Record | null, key: string, @@ -330,61 +344,66 @@ function updateFindingHeaders( } } -/** - * Updates the parameters of the finding. - * @param paramKey - The key of the parameter. - * @param paramValue - The value of the parameter. - * @param finding - The `VulnerableApiFinding` object to update. - */ -function updateFindingParams( - paramKey: string, - paramValue: string | undefined, - finding: VulnerableApiFinding +function updateFindingCookies( + currentCookies: Record | null, + key: string, + value: string ): void { - if (paramKey === 'key' || paramKey === 'token') { - finding.request.params[paramKey] = paramValue || ''; + if (currentCookies) { + currentCookies[key] = value; } } -/** - * Updates a `VulnerableApiFinding` based on the key-value pair and current section. - * @param finding - The `VulnerableApiFinding` object to update. - * @param key - The key indicating what to update. - * @param value - The value to set. - * @param currentSection - The current section of the finding. - * @param currentHeaders - The current headers being processed. - * @returns The updated section and headers. - */ function updateVulnerableApiFinding( finding: VulnerableApiFinding, key: string, value: string, - currentSection: VulnerableApiFindingSection, - currentHeaders: Record | null + currentSection: NestedKeyOf, + currentHeaders: Record | null, + currentCookies: Record | null ): { - updatedSection: VulnerableApiFindingSection; + updatedSection: NestedKeyOf; updatedHeaders: Record | null; + updatedCookies: Record | null; } { - updateFindingSeverityAndConfidence(finding, key, value); - currentSection = updateSection(key, currentSection); updateFindingField(finding, key, value, currentSection); - if (key === 'headers' && currentSection === 'request-headers') { - currentHeaders = finding.request.headers; - } else if (key === 'headers' && currentSection === 'response-headers') { - currentHeaders = finding.response.headers; - } else if (key === 'params') { - currentSection = 'params'; - } else if (currentSection === 'params') { - updateFindingParams(key, value, finding); - } else if ( - currentSection === 'request-headers' || - currentSection === 'response-headers' + if ( + (key === 'headers' && value === '') || + (key === 'cookies' && (value === '' || value === '{}')) ) { + return { + updatedSection: currentSection, + updatedHeaders: currentHeaders, + updatedCookies: currentCookies, + }; + } + + // Handle headers separately based on the current section + if (currentSection.endsWith('headers')) { + if (currentSection === 'request.headers') { + currentHeaders = finding.request.headers; + } else if (currentSection === 'response.headers') { + currentHeaders = finding.response.headers; + } updateFindingHeaders(currentHeaders, key, value); } - return { updatedSection: currentSection, updatedHeaders: currentHeaders }; + // Handle cookies separately based on the current section + if (currentSection.endsWith('cookies')) { + if (currentSection === 'request.cookies') { + currentCookies = finding.request.cookies; + } else if (currentSection === 'response.cookies') { + currentCookies = finding.response.cookies; + } + updateFindingCookies(currentCookies, key, value); + } + + return { + updatedSection: currentSection, + updatedHeaders: currentHeaders, + updatedCookies: currentCookies, + }; } diff --git a/app/utils/types.ts b/app/utils/types.ts index c12cfcf287..24c32019de 100644 --- a/app/utils/types.ts +++ b/app/utils/types.ts @@ -9,3 +9,9 @@ export type Resolved

= P extends Promise ? T : P; /** Get the resolved model value from a route. */ export type ModelFrom = Resolved>; + +export type NestedKeyOf = { + [Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends object + ? `${Key}` | `${Key}.${NestedKeyOf}` + : Key; +}[keyof ObjectType & (string | number)]; diff --git a/tests/unit/utils/parse-vulnerable-api-finding-test.js b/tests/unit/utils/parse-vulnerable-api-finding-test.js index ec85ac29df..d47f5272fd 100644 --- a/tests/unit/utils/parse-vulnerable-api-finding-test.js +++ b/tests/unit/utils/parse-vulnerable-api-finding-test.js @@ -9,12 +9,13 @@ module('Unit | Utility | parse-vulnerable-api-finding', function (hooks) { setupTest(hooks); const content1 = - "p157-contacts.icloud.com:443/mm/sub: A response to one of our payload requests has taken too long compared to the baseline request. This could indicate a vulnerability to time-based Regex DoS attacks\nconfidence: LOW\nparam:\n location: headers\n method: POST\n variables:\n - X-Apple-I-Md-M\n - Content-Length\n - X-Apple-I-Locale\n - Accept\n - Accept-Language\n - Connection\n - X-Apple-I-Md\n - Accept-Encoding\n - User-Agent\n - X-Apple-I-Timezone\n - X-Apple-I-Md-Rinfo\n - X-Apple-I-Client-Time\nrequest:\n body: ''\n headers:\n Accept: '*/*'\n Accept-Encoding: gzip, deflate, br\n Accept-Language: en-US,en;q=0.9\n Connection: keep-alive\n Content-Length: '0'\n Host: p157-caldav.icloud.com:443\n User-Agent: iOS/16.7.5 (20H307) dataaccessd/1.0\n X-Apple-I-Client-Time: '1111111111111111111111111111111112'\n X-Apple-I-Locale: en_US\n X-Apple-I-Md: AAAABQAAABD+t/oZrRyr0dQagkbgUyI3AAAAAw==\n X-Apple-I-Md-M: qKirfmb8fGttUzAtNOscrjefNSH3JW09VgFOjsxKbHYZeoFsqnHcTScIa6zrbXzkCyinChfXXcQZaME0\n X-Apple-I-Md-Rinfo: '50660608'\n X-Apple-I-Timezone: GMT+5:30\n method: POST\n params:\n key: '16304401481'\n token: b37163f4e3f63e20192b40e3bfe0ce293ba129f9706437f0dc0dce3e2bea9268\n url: https://p157-contacts.icloud.com:443/mm/sub\nresponse:\n cookies: {}\n headers:\n Connection: keep-alive\n Content-Length: '0'\n Date: Mon, 15 Jul 2024 12:49:15 GMT\n Server: AppleHttpServer/b866cf47a603\n X-Apple-Edge-Response-Time: '0'\n X-Apple-Filtered-At-Edge: 'true'\n X-Apple-Request-UUID: f3dcbfe2-9417-43ff-9e2d-d09071707eb6\n access-control-expose-headers: X-Apple-Request-UUID,Via\n via: 631194250daa17e24277dea86cf30319:18042a2d519f8fe036a8b503c12ad658:usmes1\n www-authenticate: X-MobileMe-AuthToken realm=\"MMCalDav\", Basic realm=\"MMCalDav\"\n x-apple-user-partition: '157'\n reason: Unauthorized\n status_code: 401\n text: ''\n url: https://p157-contacts.icloud.com:443/mm/sub?token=b37163f4e3f63e20192b40e3bfe0ce293ba129f9706437f0dc0dce3e2bea9268&key=16304401481\n version: 11\nseverity: MEDIUM\n\n"; + "p157-contacts.icloud.com:443/mm/sub: A response to one of our payload requests has taken too long compared to the baseline request. This could indicate a vulnerability to time-based Regex DoS attacks\nconfidence: LOW\nparam:\n location: headers\n method: POST\n variables:\n - X-Apple-I-Md-M\n - Content-Length\n - X-Apple-I-Locale\n - Accept\n - Accept-Language\n - Connection\n - X-Apple-I-Md\n - Accept-Encoding\n - User-Agent\n - X-Apple-I-Timezone\n - X-Apple-I-Md-Rinfo\n - X-Apple-I-Client-Time\nrequest:\n body: ''\n headers:\n Accept: '*/*'\n Accept-Encoding: gzip, deflate, br\n Accept-Language: en-US,en;q=0.9\n Connection: keep-alive\n Content-Length: '0'\n Host: p157-caldav.icloud.com:443\n User-Agent: iOS/16.7.5 (20H307) dataaccessd/1.0\n X-Apple-I-Client-Time: '1111111111111111111111111111111112'\n X-Apple-I-Locale: en_US\n X-Apple-I-Md: AAAABQAAABD+t/oZrRyr0dQagkbgUyI3AAAAAw==\n X-Apple-I-Md-M: qKirfmb8fGttUzAtNOscrjefNSH3JW09VgFOjsxKbHYZeoFsqnHcTScIa6zrbXzkCyinChfXXcQZaME0\n X-Apple-I-Md-Rinfo: '50660608'\n X-Apple-I-Timezone: GMT+5:30\n method: POST\n params:\n key: '16304401481'\n token: b37163f4e3f63e20192b40e3bfe0ce293ba129f9706437f0dc0dce3e2bea9268\n url: https://p157-contacts.icloud.com:443/mm/sub\nresponse:\n cookies:\n JSESSIONID: 0000gfnsEirGQB2UzBDCcDys4Un:1cca51vsg\n VSLEGFIA: 022f6c2a0b-ee5b-4b5HFOjCLRz0fkRYfGDWsskj3PxhW1FT4PNCd2AqIl_uBPL0m1psk_DSBX0qcKCSGO7bY\n WC_PERSISTENT: 6KqdTAXHThll4Ll8fMLSnpkpDZGTH2stmRKqWcNQfMk%3D%3B2024-07-31+16%3A19%3A53.785_1722457193785-8500_0\n __cf_bm: irVbX8KLSRbQwNnUZzx8.wKUryCpolObw3OtCxlBWRA-1722457193-1.0.1.1-2fvHPIjkGdPENjQnGpZO4HVGW2RCipjQ5ogdRhtyTnw.JF8skFeoJhkWAa53BWdd.U850VGe.MACd6K9tTWf9A\n src: app\n \n headers:\n Connection: keep-alive\n Content-Length: '0'\n Date: Mon, 15 Jul 2024 12:49:15 GMT\n Server: AppleHttpServer/b866cf47a603\n X-Apple-Edge-Response-Time: '0'\n X-Apple-Filtered-At-Edge: 'true'\n X-Apple-Request-UUID: f3dcbfe2-9417-43ff-9e2d-d09071707eb6\n access-control-expose-headers: X-Apple-Request-UUID,Via\n via: 631194250daa17e24277dea86cf30319:18042a2d519f8fe036a8b503c12ad658:usmes1\n www-authenticate: X-MobileMe-AuthToken realm=\"MMCalDav\", Basic realm=\"MMCalDav\"\n x-apple-user-partition: '157'\n reason: Unauthorized\n status_code: 401\n text: '{\"storeConf\":[{\"assortment_enable\":\"true\"}]}'\n url: https://p157-contacts.icloud.com:443/mm/sub?token=b37163f4e3f63e20192b40e3bfe0ce293ba129f9706437f0dc0dce3e2bea9268&key=16304401481\n version: 11\nseverity: MEDIUM\n\n"; const expectedObject1 = [ { request: { body: "''", + cookies: {}, headers: { accept: "'*/*'", 'accept-encoding': 'gzip, deflate, br', @@ -40,6 +41,16 @@ module('Unit | Utility | parse-vulnerable-api-finding', function (hooks) { url: 'https://p157-contacts.icloud.com:443/mm/sub', }, response: { + cookies: { + __cf_bm: + 'irVbX8KLSRbQwNnUZzx8.wKUryCpolObw3OtCxlBWRA-1722457193-1.0.1.1-2fvHPIjkGdPENjQnGpZO4HVGW2RCipjQ5ogdRhtyTnw.JF8skFeoJhkWAa53BWdd.U850VGe.MACd6K9tTWf9A', + jsessionid: '0000gfnsEirGQB2UzBDCcDys4Un:1cca51vsg', + src: 'app', + vslegfia: + '022f6c2a0b-ee5b-4b5HFOjCLRz0fkRYfGDWsskj3PxhW1FT4PNCd2AqIl_uBPL0m1psk_DSBX0qcKCSGO7bY', + wc_persistent: + '6KqdTAXHThll4Ll8fMLSnpkpDZGTH2stmRKqWcNQfMk%3D%3B2024-07-31+16%3A19%3A53.785_1722457193785-8500_0', + }, headers: { connection: 'keep-alive', 'content-length': "'0'", @@ -56,7 +67,7 @@ module('Unit | Utility | parse-vulnerable-api-finding', function (hooks) { }, reason: 'Unauthorized', status_code: 401, - text: '', + text: '\'{"storeConf":[{"assortment_enable":"true"}]}\'', url: 'https://p157-contacts.icloud.com:443/mm/sub?token=b37163f4e3f63e20192b40e3bfe0ce293ba129f9706437f0dc0dce3e2bea9268&key=16304401481', }, severity: 'MEDIUM', @@ -73,6 +84,7 @@ module('Unit | Utility | parse-vulnerable-api-finding', function (hooks) { { request: { body: '', + cookies: {}, headers: {}, method: '', params: { @@ -83,9 +95,10 @@ module('Unit | Utility | parse-vulnerable-api-finding', function (hooks) { }, response: { headers: {}, + cookies: {}, reason: '', status_code: 0, - text: '', + text: "''", url: '', }, severity: 'LOW', @@ -95,12 +108,13 @@ module('Unit | Utility | parse-vulnerable-api-finding', function (hooks) { ]; const content3 = - "p157-contacts.icloud.com:443/mm/sub: A response to one of our payload requests has taken too long compared to the baseline request. This could indicate a vulnerability to time-based SQL injection attacks\nconfidence: LOW\nparam:\n location: headers\n method: POST\n variables:\n - X-Apple-I-Md-M\n - Content-Length\n - X-Apple-I-Locale\n - Accept\n - Accept-Language\n - Connection\n - X-Apple-I-Md\n - Accept-Encoding\n - User-Agent\n - X-Apple-I-Timezone\n - X-Apple-I-Md-Rinfo\n - Host\n - X-Apple-I-Client-Time\nrequest:\n body: ''\n headers:\n Accept: '*/*'\n Accept-Encoding: ; OR '1'='1'\n Accept-Language: en-US,en;q=0.9\n Connection: keep-alive\n Content-Length: '0'\n Host: p157-caldav.icloud.com:443\n User-Agent: iOS/16.7.5 (20H307) dataaccessd/1.0\n X-Apple-I-Client-Time: '2024-07-15T09:07:13Z'\n X-Apple-I-Locale: en_US\n X-Apple-I-Md: AAAABQAAABD+t/oZrRyr0dQagkbgUyI3AAAAAw==\n X-Apple-I-Md-M: qKirfmb8fGttUzAtNOscrjefNSH3JW09VgFOjsxKbHYZeoFsqnHcTScIa6zrbXzkCyinChfXXcQZaME0\n X-Apple-I-Md-Rinfo: '50660608'\n X-Apple-I-Timezone: GMT+5:30\n method: POST\n params:\n key: '16304401481'\n token: b37163f4e3f63e20192b40e3bfe0ce293ba129f9706437f0dc0dce3e2bea9268\n url: https://p157-contacts.icloud.com:443/mm/sub\nresponse:\n cookies: {}\n headers:\n Connection: keep-alive\n Content-Length: '0'\n Date: Mon, 15 Jul 2024 12:50:17 GMT\n Server: AppleHttpServer/b866cf47a603\n X-Apple-Edge-Response-Time: '0'\n X-Apple-Filtered-At-Edge: 'true'\n X-Apple-Request-UUID: c411e3b6-c70a-4b50-acd5-b98c31521249\n access-control-expose-headers: X-Apple-Request-UUID,Via\n via: 631194250daa17e24277dea86cf30319:02caeb0e04ee373e250b945a1f576f08:usdal2\n www-authenticate: X-MobileMe-AuthToken realm=\"MMCalDav\", Basic realm=\"MMCalDav\"\n x-apple-user-partition: '157'\n reason: Unauthorized\n status_code: 401\n text: ''\n url: https://p157-contacts.icloud.com:443/mm/sub?token=b37163f4e3f63e20192b40e3bfe0ce293ba129f9706437f0dc0dce3e2bea9268&key=16304401481\n version: 11\nseverity: MEDIUM\n\nconfidence: LOW\nparam:\n location: params\n method: POST\n variables:\n - token\n - key\nrequest:\n body: ''\n headers:\n Accept: '*/*'\n Accept-Encoding: gzip, deflate, br\n Accept-Language: en-US,en;q=0.9\n Connection: keep-alive\n Content-Length: '0'\n Host: p157-caldav.icloud.com:443\n User-Agent: iOS/16.7.5 (20H307) dataaccessd/1.0\n X-Apple-I-Client-Time: '2024-07-15T09:07:13Z'\n X-Apple-I-Locale: en_US\n X-Apple-I-Md: AAAABQAAABD+t/oZrRyr0dQagkbgUyI3AAAAAw==\n X-Apple-I-Md-M: qKirfmb8fGttUzAtNOscrjefNSH3JW09VgFOjsxKbHYZeoFsqnHcTScIa6zrbXzkCyinChfXXcQZaME0\n X-Apple-I-Md-Rinfo: '50660608'\n X-Apple-I-Timezone: GMT+5:30\n method: POST\n params:\n key: '16304401481'\n token: ; OR '1'='1'\n url: https://p157-contacts.icloud.com:443/mm/sub\nresponse:\n cookies: {}\n headers:\n Connection: keep-alive\n Content-Length: '0'\n Date: Mon, 15 Jul 2024 12:50:18 GMT\n Server: AppleHttpServer/b866cf47a603\n X-Apple-Edge-Response-Time: '0'\n X-Apple-Filtered-At-Edge: 'true'\n X-Apple-Request-UUID: 05b1ac99-ee33-44ba-aa1d-f52499fdcd88\n access-control-expose-headers: X-Apple-Request-UUID,Via\n via: 631194250daa17e24277dea86cf30319:4253a6fbce6fc9cade45c5ab633577a5:usmes1\n www-authenticate: X-MobileMe-AuthToken realm=\"MMCalDav\", Basic realm=\"MMCalDav\"\n x-apple-user-partition: '157'\n reason: Unauthorized\n status_code: 401\n text: ''\n url: https://p157-contacts.icloud.com:443/mm/sub?token=%3B+OR+%271%27%3D%271%27&key=16304401481\n version: 11\nseverity: MEDIUM\n\n\n"; + "p157-contacts.icloud.com:443/mm/sub: A response to one of our payload requests has taken too long compared to the baseline request. This could indicate a vulnerability to time-based SQL injection attacks\nconfidence: LOW\nparam:\n location: headers\n method: POST\n variables:\n - X-Apple-I-Md-M\n - Content-Length\n - X-Apple-I-Locale\n - Accept\n - Accept-Language\n - Connection\n - X-Apple-I-Md\n - Accept-Encoding\n - User-Agent\n - X-Apple-I-Timezone\n - X-Apple-I-Md-Rinfo\n - Host\n - X-Apple-I-Client-Time\nrequest:\n body: '{\"operationName\": \"GetAdhocTasks\", \"variables\": {\"driverId\": 3, \"startTime\": \"2024-09-02 14:00:00\", \"endTime\": \"2024-09-03 00:00:00\"}, \"query\": \"query GetAdhocTasks($driverId: Int, $endTime: String, $startTime: String) {\\n adhocTasks(driverId: $driverId, endTime: $endTime, startTime: $startTime) {\\n adhoctaskId\\n driverId\\n note\\n startTime\\n endDeadline\\n issueType\\n delayedTask\\n __typename\\n }\\n}\"}'\n headers:\n Accept: '*/*'\n Accept-Encoding: ; OR '1'='1'\n Accept-Language: en-US,en;q=0.9\n Connection: keep-alive\n Content-Length: '0'\n Host: p157-caldav.icloud.com:443\n User-Agent: iOS/16.7.5 (20H307) dataaccessd/1.0\n X-Apple-I-Client-Time: '2024-07-15T09:07:13Z'\n X-Apple-I-Locale: en_US\n X-Apple-I-Md: AAAABQAAABD+t/oZrRyr0dQagkbgUyI3AAAAAw==\n X-Apple-I-Md-M: qKirfmb8fGttUzAtNOscrjefNSH3JW09VgFOjsxKbHYZeoFsqnHcTScIa6zrbXzkCyinChfXXcQZaME0\n X-Apple-I-Md-Rinfo: '50660608'\n X-Apple-I-Timezone: GMT+5:30\n method: POST\n params:\n key: '16304401481'\n token: b37163f4e3f63e20192b40e3bfe0ce293ba129f9706437f0dc0dce3e2bea9268\n url: https://p157-contacts.icloud.com:443/mm/sub\nresponse:\n cookies: {}\n headers:\n Connection: keep-alive\n Content-Length: '0'\n Date: Mon, 15 Jul 2024 12:50:17 GMT\n Server: AppleHttpServer/b866cf47a603\n X-Apple-Edge-Response-Time: '0'\n X-Apple-Filtered-At-Edge: 'true'\n X-Apple-Request-UUID: c411e3b6-c70a-4b50-acd5-b98c31521249\n access-control-expose-headers: X-Apple-Request-UUID,Via\n via: 631194250daa17e24277dea86cf30319:02caeb0e04ee373e250b945a1f576f08:usdal2\n www-authenticate: X-MobileMe-AuthToken realm=\"MMCalDav\", Basic realm=\"MMCalDav\"\n x-apple-user-partition: '157'\n reason: Unauthorized\n status_code: 401\n text: ''\n url: https://p157-contacts.icloud.com:443/mm/sub?token=b37163f4e3f63e20192b40e3bfe0ce293ba129f9706437f0dc0dce3e2bea9268&key=16304401481\n version: 11\nseverity: MEDIUM\n\nconfidence: LOW\nparam:\n location: params\n method: POST\n variables:\n - token\n - key\nrequest:\n body: ''\n headers:\n Accept: '*/*'\n Accept-Encoding: gzip, deflate, br\n Accept-Language: en-US,en;q=0.9\n Connection: keep-alive\n Content-Length: '0'\n Host: p157-caldav.icloud.com:443\n User-Agent: iOS/16.7.5 (20H307) dataaccessd/1.0\n X-Apple-I-Client-Time: '2024-07-15T09:07:13Z'\n X-Apple-I-Locale: en_US\n X-Apple-I-Md: AAAABQAAABD+t/oZrRyr0dQagkbgUyI3AAAAAw==\n X-Apple-I-Md-M: qKirfmb8fGttUzAtNOscrjefNSH3JW09VgFOjsxKbHYZeoFsqnHcTScIa6zrbXzkCyinChfXXcQZaME0\n X-Apple-I-Md-Rinfo: '50660608'\n X-Apple-I-Timezone: GMT+5:30\n method: POST\n params:\n key: '16304401481'\n token: ; OR '1'='1'\n url: https://p157-contacts.icloud.com:443/mm/sub\nresponse:\n cookies: {}\n headers:\n Connection: keep-alive\n Content-Length: '0'\n Date: Mon, 15 Jul 2024 12:50:18 GMT\n Server: AppleHttpServer/b866cf47a603\n X-Apple-Edge-Response-Time: '0'\n X-Apple-Filtered-At-Edge: 'true'\n X-Apple-Request-UUID: 05b1ac99-ee33-44ba-aa1d-f52499fdcd88\n access-control-expose-headers: X-Apple-Request-UUID,Via\n via: 631194250daa17e24277dea86cf30319:4253a6fbce6fc9cade45c5ab633577a5:usmes1\n www-authenticate: X-MobileMe-AuthToken realm=\"MMCalDav\", Basic realm=\"MMCalDav\"\n x-apple-user-partition: '157'\n reason: Unauthorized\n status_code: 401\n text: ''\n url: https://p157-contacts.icloud.com:443/mm/sub?token=%3B+OR+%271%27%3D%271%27&key=16304401481\n version: 11\nseverity: MEDIUM\n\n\n"; const expectedObject3 = [ { request: { - body: "''", + body: '\'{"operationName": "GetAdhocTasks", "variables": {"driverId": 3, "startTime": "2024-09-02 14:00:00", "endTime": "2024-09-03 00:00:00"}, "query": "query GetAdhocTasks($driverId: Int, $endTime: String, $startTime: String) {\\n adhocTasks(driverId: $driverId, endTime: $endTime, startTime: $startTime) {\\n adhoctaskId\\n driverId\\n note\\n startTime\\n endDeadline\\n issueType\\n delayedTask\\n __typename\\n }\\n}"}\'', + cookies: {}, headers: { accept: "'*/*'", 'accept-encoding': "; OR '1'='1'", @@ -140,9 +154,10 @@ module('Unit | Utility | parse-vulnerable-api-finding', function (hooks) { 'X-MobileMe-AuthToken realm="MMCalDav", Basic realm="MMCalDav"', 'x-apple-user-partition': "'157'", }, + cookies: {}, reason: 'Unauthorized', status_code: 401, - text: '', + text: "''", url: 'https://p157-contacts.icloud.com:443/mm/sub?token=b37163f4e3f63e20192b40e3bfe0ce293ba129f9706437f0dc0dce3e2bea9268&key=16304401481', }, severity: 'MEDIUM', @@ -169,6 +184,7 @@ module('Unit | Utility | parse-vulnerable-api-finding', function (hooks) { 'x-apple-i-md-rinfo': "'50660608'", 'x-apple-i-timezone': 'GMT+5:30', }, + cookies: {}, method: 'POST', params: { key: "'16304401481'", @@ -191,9 +207,10 @@ module('Unit | Utility | parse-vulnerable-api-finding', function (hooks) { 'X-MobileMe-AuthToken realm="MMCalDav", Basic realm="MMCalDav"', 'x-apple-user-partition': "'157'", }, + cookies: {}, reason: 'Unauthorized', status_code: 401, - text: '', + text: "''", url: 'https://p157-contacts.icloud.com:443/mm/sub?token=%3B+OR+%271%27%3D%271%27&key=16304401481', }, severity: 'MEDIUM', diff --git a/translations/en.json b/translations/en.json index efdc79e5b3..d0bae457f6 100644 --- a/translations/en.json +++ b/translations/en.json @@ -253,6 +253,7 @@ "contactUs": "Contact Us", "container": "Container", "continue": "Continue", + "cookies": "Cookies", "copiedToClipboard": "Copied to clipboard!", "copy": "Copy", "country": "Country", diff --git a/translations/ja.json b/translations/ja.json index 68d459eed7..014190efd9 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -253,6 +253,7 @@ "contactUs": "Contact Us", "container": "Container", "continue": "続ける", + "cookies": "Cookies", "copiedToClipboard": "Copied to clipboard!", "copy": "コピー", "country": "Country",